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 ca8619bb9a1031301245e00d780e13d093618627 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 26 Feb 2023 12:23:13 -0700 Subject: Update test framework tutorial [skip appveyor] A few minor edits, then a section added at the end mith more hints on things that are useful when writing both kinds of tests. Added an initial .editorconfig - this was useful to keep a formatting style for the test-framework.rst while tweaking it. Signed-off-by: Mats Wichmann --- .editorconfig | 26 ++++++ testing/framework/test-framework.rst | 153 ++++++++++++++++++++++++++--------- 2 files changed, 140 insertions(+), 39 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3d2b699 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,26 @@ +# EditorConfig file for SCons project + +root = true + +[*] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true +end_of_line = lf +charset = utf-8 + +[*.py] +max_line_length = 88 +ensure_newline_before_comments = true +include_trailing_comma = true +use_parentheses = true + +[*.xml] +indent_size = 2 + +[*.rst] +indent_size = 3 + +[*.bat] +end_of_line = crlf diff --git a/testing/framework/test-framework.rst b/testing/framework/test-framework.rst index 265b82e..01893ee 100644 --- a/testing/framework/test-framework.rst +++ b/testing/framework/test-framework.rst @@ -61,7 +61,7 @@ scripts as we find them.) End-to-end tests are by their nature harder to debug. You can drop straight into the Python debugger on the unit test scripts by using the ``runtest.py --pdb`` option, but the end-to-end -tests treat an SCons invocation as a "black box" and just look for +tests treat an SCons invocation as a *black box* and just look for external effects; simple methods like inserting ``print`` statements in the SCons code itself can disrupt those external effects. See `Debugging end-to-end tests`_ for some more thoughts. @@ -72,7 +72,7 @@ Naming conventions The end-to-end tests, more or less, stick to the following naming conventions: -#. All tests end with a .py suffix. +#. All tests end with a ``.py`` suffix. #. In the *General* form we use ``Feature.py`` @@ -161,7 +161,7 @@ a function which takes a path-component argument and returns the path to that path-component in the testing directory. The use of an ephemeral test directory means that you can't simply change -into a directory to "debug things" after a test has gone wrong. +into a directory to debug after a test has gone wrong. For a way around this, check out the ``PRESERVE`` environment variable. It can be seen in action in `How to convert old tests to use fixures`_ below. @@ -170,7 +170,7 @@ Not running tests If you simply want to check which tests would get executed, you can call the ``runtest.py`` script with the ``-l`` option combined with whichever -test finding options (see below) you intend to use. Example:: +test selection options (see below) you intend to use. Example:: $ python runtest.py -l test/scons-time @@ -179,8 +179,8 @@ each test which would have been run, but doesn't actually run them:: $ python runtest.py -n -a -Finding Tests -============= +Selecting tests +=============== When started in *standard* mode:: @@ -209,11 +209,11 @@ The same rules apply when testing external Tools when using the ``-e`` option. -Example End-to-End Test Script +Example End-to-End test script ============================== To illustrate how the end-to-end test scripts work, let's walk through -a simple "Hello, world!" example:: +a simple *Hello, world!* example:: #!python import TestSCons @@ -241,6 +241,8 @@ a simple "Hello, world!" example:: test.pass_test() +Explanation +----------- ``import TestSCons`` Imports the main infrastructure for writing SCons tests. This is @@ -249,7 +251,7 @@ a simple "Hello, world!" example:: imported before this line. ``test = TestSCons.TestSCons()`` - This initializes an object for testing. A fair amount happens under + Initializes an object for testing. A fair amount happens under the covers when the object is created, including: * A temporary directory is created for all the in-line files that will @@ -302,8 +304,8 @@ Working with fixtures In the simple example above, the files to set up the test are created on the fly by the test program. We give a filename to the ``TestSCons.write()`` -method, and a string holding its contents, and it gets written to the test -directory right before starting.. +method, plus a string holding its contents, and it gets written to the test +directory right before starting. This simple technique can be seen throughout most of the end-to-end tests as it was the original technique provided to test developers, @@ -321,12 +323,12 @@ for code, so the effect is lost on them. In testing parlance, a fixture is a repeatable test setup. The SCons test harness allows the use of saved files or directories to be used -in that sense: "the fixture for this test is foo", instead of writing +in that sense: *the fixture for this test is foo*, instead of writing a whole bunch of strings to create files. Since these setups can be reusable across multiple tests, the *fixture* terminology applies well. Note: fixtures must not be treated by SCons as runnable tests. To exclude -them, see instructions in the above section named "Finding Tests". +them, see instructions in the above section named `Selecting tests`_. Directory fixtures ------------------ @@ -390,9 +392,11 @@ would have been placed in the top level of the test directory. Again, a reference example can be found in the current revision of SCons, see ``test/packaging/sandbox-test/sandbox-test.py``. -For even more examples you should check out -one of the external Tools, e.g. the *Qt4* Tool at -https://bitbucket.org/dirkbaechle/scons_qt4. Also visit the SCons Tools +For even more examples you should check out one of the external Tools, +e.g. the *Qt5* Tool at +https://github.com/SCons/scons-contrib/tree/master/sconscontrib/SCons/Tool/qt5. +There are many other tools in the contrib repository, +and you can also visit the SCons Tools Index at https://github.com/SCons/scons/wiki/ToolsIndex for a complete list of available Tools, though not all may have tests yet. @@ -453,23 +457,24 @@ kind of usage that does not lend itself to a fixture:: import TestSCons _python_ = TestSCons._python_ - test.write('SConstruct', """ + test.write('SConstruct', f""" cc = Environment().Dictionary('CC') env = Environment( - LINK=r'%(_python_)s mylink.py', + LINK=r'{_python_} mylink.py', LINKFLAGS=[], - CC=r'%(_python_)s mycc.py', + CC=r'{_python_} mycc.py', CXX=cc, CXXFLAGS=[], ) env.Program(target='test1', source='test1.c') - """ % locals()) + """ -Here the value of ``_python_`` is picked out of the script's -``locals`` dictionary - which works because we've set it above - -and interpolated using a mapping key into the string that will -be written to ``SConstruct``. A fixture would be hard to use -here because we don't know the value of ``_python_`` until runtime. +Here the value of ``_python_`` from the test program is +pasted in via f-string formatting. A fixture would be hard to use +here because we don't know the value of ``_python_`` until runtime +(also note that as it will be a full pathname, it's entered as a +Python rawstring to avoid interpretation problems on Windows, +where the path separator is a backslash). The other files created in this test may still be candidates for use as fixture files, however. @@ -518,7 +523,7 @@ for debugging purposes. If you have a failing test, try:: You can now go to the save directory reported from this run and invoke the test manually to see what it is doing, without the presence of the test infrastructure which would otherwise -"swallow" output you may be interested in. In this case, +consume output you may be interested in. In this case, adding debug prints may be more useful. @@ -528,17 +533,17 @@ Test infrastructure The main test API is defined in the ``TestSCons`` class. ``TestSCons`` is a subclass of ``TestCommon``, which is a subclass of ``TestCmd``. All those classes are defined in Python files of the same name -in ``testing/framework``. +in ``testing/framework``. Start in ``testing/framework/TestCmd.py`` for the base API definitions, like how to create files (``test.write()``) and run commands (``test.run()``). Use ``TestSCons`` for the end-to-end tests in ``test``, but use -``TestCmd`` for the unit tests in the ``src`` directory. +``TestCmd`` for the unit tests in the ``SCons`` directory. The match functions work like this: ``TestSCons.match_re`` - match each line with a RE + match each line with an RE * Splits the lines into a list (unless they already are) * splits the REs at newlines (unless already a list) @@ -614,14 +619,84 @@ plumbed into the environment. These things can be tested by mocking the behavior of the executable. Many examples of this can be found in the ``test`` directory. See for example ``test/subdivide.py``. -This leads to a suggestion for E2E test organization because the framework -doesn't have a way to indicate a partial skip - if you executed -200 lines of test, then found a condition which caused you to skip the -last 20 lines, the whole test is marked as a skip; -it also doesn't have a way to indicate a partial pass. -To improve on this, keep tool tests which don't need the -underlying program in separate files from ones which do - -that way one can see in the test results that the "plumbing" -tests worked even if the the ones using the underlying program -maybe were skipped. +Testing DOs and DONTs +===================== + +There's no question that having to write tests in order to get a change +approved - even an apparently trivial change - does make it a little harder +to contribute to the SCons code base - but the requirement to have features +and bugfixes testable is a necessary part of ensuring SCons quality. +Thinking of SCons development in terms of the red/green model from +Test Driven Development should make things a little easier. + +If you are working on an SCons bug, try to come up with a simple +reproducer first. Bug reports (even your own!) are often like *I tried +to do this but it surprisingly failed*, and a reproducer is normally an +``SConstruct`` along with, probably, some supporting files such as source +files, data files, subsidiary SConscripts, etc. Try to make this example +as simple and clean as possible. No, this isn't necessarily easy to do, +but winnowing down what triggers a problem and removing the stuff that +doesn't actually contribute to triggering the problem it is a step that +lets you (and later readers) more clearly understand what is going on. +You don't have to turn this into a formal testcase yet, but keep this +reproducer around, and document with it what you expect to happen, +and what actually happens. This material will help produce an E2E +test later, and this is something you *may* be able to get help with, +if the way the tests are usually written and the test harness proves +too confusing. With a clean test in hand (make sure it's failing!) +you can go ahead an code up a fix and make sure it passes with the fix +in place. Jumping straight to a fix without working on a testcase like +this will often lead to a disappointing *how do I come up with a test +so the maintainer will be willing to merge* phase. Asking questions on +a public forum can be productive here. + +E2E-specific Suggestions: + +* Do not require the use of an external tool unless necessary. + Usually the SCons behavior is the thing we want to test, + not the behavior of the external tool. *Necessary* is not a precise term - + sometimes it would be too time-consuming to write a script to mock + a compiler with an extensive set of options, and sometimes it's + not a good idea to assume you know what all those will do vs what + the real tool does; there may be other good reasons for just going + ahead and calling the external tool. +* If using an external tool, be prepared to skip the test if it is unavailable. +* Do not combine tests that need an external tool with ones that + do not - divide these into separate test files. There is no concept + of partial skip for e2e tests, so if you successfully complete seven + of eight tests, and then come to a conditional "skip if tool missing" + or "skip if on Windows", and that branch is taken, then the + whole test file ends up skipped, and the seven that ran will + never be recorded. Some tests follow the convention of creating a + second test file with the ending ``-live`` for the part that requires + actually running the external tool. +* In testing, *fail fast* is not always the best policy - if you can think + of many scenarios that could go wrong and they are all run linearly in + a single test file, then you only hear about the first one that fails. + In some cases it may make sense to split them out a bit more, so you + can see several fails at once, which may show a helpful failure pattern + you wouldn't spot from a single fail. +* Use test fixtures where it makes sense, and in particular, try to + make use of shareable mocked tools, which, by getting lots of use, + will be better debugged (that is, don't have each test produce its + own ``myfortan.py`` or ``mylex.py`` etc. unless they need drastically + different behaviors). + +Unittest-specific hints: + +- Let the ``unittest`` module help! Lots of the existing tests just + use a bare ``assert`` call for checks, which works fine, but then + you are responsible for preparing the message if it fails. The base + ``TestCase`` class has methods which know how to display many things, + for example ``self.assertEqual()`` displays in what way the two arguments + differ if they are *not* equal. Checking for am expected exception can + be done with ``self.assertRaises()`` rather than crafting a stub of + code using a try block for this situation. +- The *fail fast* consideration applies here, too: try not to fail a whole + testcase on the first problem, if there are more checks to go. + Again, existing tests may use elaborate tricks for this, but modern + ``unittest`` has a ``subTest`` context manager that can be used to wrap + each distinct piece and not abort the testcase for a failing subtest + (to be fair, this functionality is a recent addition, after most SCons + unit tests were written - but it should be used going forward). -- 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 661f4cc3be460a985b784e66bdf0216974fe9615 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:05:22 -0400 Subject: Regenerated docs for 4.5.2 release. --- doc/generated/examples/caching_ex-random_1.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/generated/examples/caching_ex-random_1.xml b/doc/generated/examples/caching_ex-random_1.xml index 266eaa0..4773380 100644 --- a/doc/generated/examples/caching_ex-random_1.xml +++ b/doc/generated/examples/caching_ex-random_1.xml @@ -1,8 +1,8 @@ % scons -Q -cc -o f2.o -c f2.c -cc -o f3.o -c f3.c cc -o f1.o -c f1.c -cc -o f5.o -c f5.c cc -o f4.o -c f4.c +cc -o f2.o -c f2.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 -- cgit v0.12 From 120fd4f633e9ef3cafbc0fec35306d7555ffd1db Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:08:25 -0400 Subject: Updates to CHANGES.txt and RELEASE.txt for 4.5.2 Release --- CHANGES.txt | 2 +- RELEASE.txt | 48 +++++++++++------------------------------------- 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8bb3c21..2c11cb4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,7 +7,7 @@ NOTE: The 4.0.0 Release of SCons dropped Python 2.7 Support NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer supported -RELEASE VERSION/DATE TO BE FILLED IN LATER +RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 From Michał Górny: - Remove the redundant `wheel` dependency from `pyproject.toml`, diff --git a/RELEASE.txt b/RELEASE.txt index 4e25b95..959c566 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -10,36 +10,18 @@ A new SCons release, 4.5.2, is now available on the SCons download page: https://scons.org/pages/download.html - Here is a summary of the changes since 4.5.1: -NEW FUNCTIONALITY ------------------ - -- List new features (presumably why a checkpoint is being released) - -DEPRECATED FUNCTIONALITY ------------------------- - -- List anything that's been deprecated since the last release - -CHANGED/ENHANCED EXISTING FUNCTIONALITY ---------------------------------------- - -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug - FIXES ----- -- List fixes of outright bugs - -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 +- Fix a problem (#4321) in 4.5.0/4.5.1 where ParseConfig could cause an + exception in MergeFlags when the result would be to add preprocessor + defines to existing CPPDEFINES. The following code illustrates the + circumstances that could trigger this: + env=Environment(CPPDEFINES=['a']) + env.Append(CPPDEFINES=['b']) + env.MergeFlags({'CPPDEFINES': 'c'}) PACKAGING --------- @@ -47,20 +29,12 @@ PACKAGING - Remove the redundant `wheel` dependency from `pyproject.toml`, as it is added automatically by the setuptools PEP517 backend. -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) - -DEVELOPMENT ------------ - -- List visible changes in the way SCons is developed 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.1..HEAD + 3 Mats Wichmann + 2 William Deegan + 1 Michał Górny -- cgit v0.12 From 7dfbbcf697f47680a101d846f836e85bc14eef13 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:14:48 -0400 Subject: Updates for 4.5.2. Added zipapp package to scons-locals --- SCons/__init__.py | 8 ++++---- bin/upload-release-files.sh | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/SCons/__init__.py b/SCons/__init__.py index f53583b..12be8e6 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" +__date__="Tue, 21 Mar 2023 12:11:27 -0400" __buildsys__="M1DOG2021" -__revision__="49578b34582d9e92dac7d713a8e58599ae35aa63" -__build__="49578b34582d9e92dac7d713a8e58599ae35aa63" +__revision__="120fd4f633e9ef3cafbc0fec35306d7555ffd1db" +__build__="120fd4f633e9ef3cafbc0fec35306d7555ffd1db" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file diff --git a/bin/upload-release-files.sh b/bin/upload-release-files.sh index 607512e..65e9206 100755 --- a/bin/upload-release-files.sh +++ b/bin/upload-release-files.sh @@ -27,7 +27,7 @@ $RSYNC $RSYNCOPTS\ README.rst \ $SF_USER@$SF_MACHINE:$SF_TOPDIR/scons/ - + # Upload main scons release files: $RSYNC $RSYNCOPTS \ SCons-$VERSION.tar.gz \ @@ -39,6 +39,7 @@ $RSYNC $RSYNCOPTS \ $RSYNC $RSYNCOPTS \ scons-local-$VERSION.tar.gz \ scons-local-$VERSION.zip \ + scons-local-$VERSION.pyz \ CHANGES.txt RELEASE.txt \ $SF_USER@$SF_MACHINE:$SF_TOPDIR/scons-local/$VERSION/ -- cgit v0.12 From 3602c3c992d44129af19128b6203d10440a5a5fa Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:17:04 -0400 Subject: Updates for 4.5.2. Added zipapp package to scons-locals --- RELEASE.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/RELEASE.txt b/RELEASE.txt index 959c566..12a275e 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -1,11 +1,3 @@ -If you are reading this in the git repository, the contents -refer to *unreleased* changes since the last SCons release. -Past official release announcements appear at: - - https://scons.org/tag/releases.html - -================================================================== - A new SCons release, 4.5.2, is now available on the SCons download page: https://scons.org/pages/download.html -- cgit v0.12 From 5eab3a7caea508b69501d3b577a706910e980840 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:26:32 -0400 Subject: Updates post 4.5.2 release --- CHANGES.txt | 7 +++++ RELEASE.txt | 63 ++++++++++++++++++++++++++++++++---------- ReleaseConfig | 2 +- SConstruct | 2 +- doc/user/main.xml | 2 +- testing/framework/TestSCons.py | 2 +- 6 files changed, 59 insertions(+), 19 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 2c11cb4..c6f35fa 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,13 @@ NOTE: The 4.0.0 Release of SCons dropped Python 2.7 Support NOTE: 4.3.0 now requires Python 3.6.0 and above. Python 3.5.x is no longer supported +RELEASE VERSION/DATE TO BE FILLED IN LATER + + From John Doe: + + - Whatever John Doe did. + + RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 From Michał Górny: diff --git a/RELEASE.txt b/RELEASE.txt index 12a275e..769a12d 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -1,32 +1,65 @@ -A new SCons release, 4.5.2, is now available on the SCons download page: +If you are reading this in the git repository, the contents +refer to *unreleased* changes since the last SCons release. +Past official release announcements appear at: + + https://scons.org/tag/releases.html + +================================================================== + +A new SCons release, 4.5.3, is now available on the SCons download page: https://scons.org/pages/download.html -Here is a summary of the changes since 4.5.1: + +Here is a summary of the changes since 4.5.2: + +NEW FUNCTIONALITY +----------------- + +- List new features (presumably why a checkpoint is being released) + +DEPRECATED FUNCTIONALITY +------------------------ + +- List anything that's been deprecated since the last release + +CHANGED/ENHANCED EXISTING FUNCTIONALITY +--------------------------------------- + +- List modifications to existing features, where the previous behavior + wouldn't actually be considered a bug FIXES ----- -- Fix a problem (#4321) in 4.5.0/4.5.1 where ParseConfig could cause an - exception in MergeFlags when the result would be to add preprocessor - defines to existing CPPDEFINES. The following code illustrates the - circumstances that could trigger this: - env=Environment(CPPDEFINES=['a']) - env.Append(CPPDEFINES=['b']) - env.MergeFlags({'CPPDEFINES': 'c'}) +- List fixes of outright bugs + +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 PACKAGING --------- -- Remove the redundant `wheel` dependency from `pyproject.toml`, - as it is added automatically by the setuptools PEP517 backend. +- List changes in the way SCons is packaged and/or released + +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) + +DEVELOPMENT +----------- +- List visible changes in the way SCons is developed Thanks to the following contributors listed below for their contributions to this release. ========================================================================================== .. code-block:: text - git shortlog --no-merges -ns 4.5.1..HEAD - 3 Mats Wichmann - 2 William Deegan - 1 Michał Górny + git shortlog --no-merges -ns 4.0.1..HEAD diff --git a/ReleaseConfig b/ReleaseConfig index 2b80306..19ddee2 100755 --- a/ReleaseConfig +++ b/ReleaseConfig @@ -31,7 +31,7 @@ # 'final', the patchlevel is set to the release date. This value is # mandatory and must be present in this file. #version_tuple = (2, 2, 0, 'final', 0) -version_tuple = (4, 5, 2, 'a', 0) +version_tuple = (4, 5, 3, 'a', 0) # Python versions prior to unsupported_python_version cause a fatal error # when that version is used. Python versions prior to deprecate_python_version diff --git a/SConstruct b/SConstruct index 1f44ea4..4b42471 100644 --- a/SConstruct +++ b/SConstruct @@ -38,7 +38,7 @@ month_year = strftime('%B %Y') project = 'scons' -default_version = '4.5.2' +default_version = '4.5.3' copyright = "Copyright (c) %s The SCons Foundation" % copyright_years # diff --git a/doc/user/main.xml b/doc/user/main.xml index 7fcd922..de549a8 100644 --- a/doc/user/main.xml +++ b/doc/user/main.xml @@ -54,7 +54,7 @@ The SCons Development Team - Released: Mon, 06 Mar 2023 23:58:40 -0400 + Released: Mon, 21 Mar 2023 12:25:39 -0400 2004 - 2023 diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py index 2c96995..b65d807 100644 --- a/testing/framework/TestSCons.py +++ b/testing/framework/TestSCons.py @@ -55,7 +55,7 @@ from TestCmd import PIPE # here provides some independent verification that what we packaged # conforms to what we expect. -default_version = '4.5.2ayyyymmdd' +default_version = '4.5.3ayyyymmdd' # TODO: these need to be hand-edited when there are changes python_version_unsupported = (3, 6, 0) -- cgit v0.12 From fd166f513214e81d3622485128739354dfa11a24 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 21 Mar 2023 13:30:36 -0600 Subject: Fix dictifyCPPDEFINES handlong of macro strings CPPDEFINES can contain name=value strings, either a single one, or one or more in a sequence type. After conversion (subsequent Append/Prepend to CPPDEFINES), these will be stored as tuples, but it is possible to hit cases where the type conversion has never been triggered. The C Scanner has its own routine to process CPPDEFINES, and missed these cases, which are now handled. The testcases in issue 4193 which showed this problem are now included in the C scanner unit tests, and the test for dictifyCPPDEFINES is expanded to check these two forms. Fixes #4193 Signed-off-by: Mats Wichmann --- CHANGES.txt | 9 +++-- SCons/Scanner/C.py | 21 +++++++++-- SCons/Scanner/CTests.py | 98 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 91 insertions(+), 37 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c6f35fa..c594979 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -9,9 +9,12 @@ 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 John Doe: - - - Whatever John Doe did. + From Mats Wichmann + - C scanner's dictifyCPPDEFINES routine did not understand the possible + combinations of CPPDEFINES - not aware of a "name=value" string either + embedded in a sequence, or by itself. The conditional C scanner thus + did not always properly apply the defines. The regular C scanner does + not use these, so was not affected. [fixes #4193] RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index a066104..418454f 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -64,22 +64,35 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): def dictify_CPPDEFINES(env) -> dict: """Returns CPPDEFINES converted to a dict.""" cppdefines = env.get('CPPDEFINES', {}) + result = {} if cppdefines is None: - return {} + return result if SCons.Util.is_Sequence(cppdefines): - result = {} for c in cppdefines: if SCons.Util.is_Sequence(c): try: result[c[0]] = c[1] except IndexError: - # it could be a one-item sequence + # could be a one-item sequence result[c[0]] = None + elif SCons.Util.is_String(c): + try: + name, value = c.split('=') + result[name] = value + except ValueError: + result[c] = None else: + # don't really know what to do here result[c] = None return result + if SCons.Util.is_String(cppdefines): + try: + name, value = cppdefines.split('=') + return {name: value} + except ValueError: + return {cppdefines: None} if not SCons.Util.is_Dict(cppdefines): - return {cppdefines : None} + return {cppdefines: None} return cppdefines class SConsCPPScannerWrapper: diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index 14e156e..e9780d0 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -91,6 +91,27 @@ int main(void) } """) +# include using a macro, defined in source file +test.write('f9a.c', """\ +#define HEADER "f9.h" +#include HEADER + +int main(void) +{ + return 0; +} +""") + +# include using a macro, not defined in source file +test.write('f9b.c', """\ +#include HEADER + +int main(void) +{ + return 0; +} +""") + # for Emacs -> " @@ -99,7 +120,7 @@ test.subdir('d1', ['d1', 'd2']) headers = ['f1.h','f2.h', 'f3-test.h', 'fi.h', 'fj.h', 'never.h', 'd1/f1.h', 'd1/f2.h', 'd1/f3-test.h', 'd1/fi.h', 'd1/fj.h', 'd1/d2/f1.h', 'd1/d2/f2.h', 'd1/d2/f3-test.h', - 'd1/d2/f4.h', 'd1/d2/fi.h', 'd1/d2/fj.h'] + 'd1/d2/f4.h', 'd1/d2/fi.h', 'd1/d2/fj.h', 'f9.h'] for h in headers: test.write(h, " ") @@ -224,7 +245,7 @@ def deps_match(self, deps, headers): global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) - self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) + self.assertTrue(scanned == expect, f"expect {expect} != scanned {scanned}") # define some tests: @@ -443,7 +464,7 @@ class CScannerTestCase15(unittest.TestCase): env = DummyEnvironment(CPPSUFFIXES = suffixes) s = SCons.Scanner.C.CScanner() for suffix in suffixes: - assert suffix in s.get_skeys(env), "%s not in skeys" % suffix + assert suffix in s.get_skeys(env), f"{suffix} not in skeys" class CConditionalScannerTestCase1(unittest.TestCase): @@ -490,6 +511,29 @@ class CConditionalScannerTestCase3(unittest.TestCase): headers = ['d1/f1.h'] deps_match(self, deps, headers) + +class CConditionalScannerTestCase4(unittest.TestCase): + def runTest(self): + """Test that dependency is detected if #include uses a macro.""" + + # first try the macro defined in the source file + with self.subTest(): + env = DummyEnvironment() + s = SCons.Scanner.C.CConditionalScanner() + deps = s(env.File('f9a.c'), env, s.path(env)) + headers = ['f9.h'] + deps_match(self, deps, headers) + + # then try the macro defined on the command line + with self.subTest(): + env = DummyEnvironment(CPPDEFINES='HEADER=\\"f9.h\\"') + #env = DummyEnvironment(CPPDEFINES=['HEADER=\\"f9.h\\"']) + s = SCons.Scanner.C.CConditionalScanner() + deps = s(env.File('f9b.c'), env, s.path(env)) + headers = ['f9.h'] + deps_match(self, deps, headers) + + class dictify_CPPDEFINESTestCase(unittest.TestCase): def runTest(self): """Make sure single-item tuples convert correctly. @@ -497,35 +541,29 @@ class dictify_CPPDEFINESTestCase(unittest.TestCase): This is a regression test: AppendUnique turns sequences into lists of tuples, and dictify could gack on these. """ - env = DummyEnvironment(CPPDEFINES=(("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", ))) - d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} - assert d == expect - -def suite(): - suite = unittest.TestSuite() - suite.addTest(CScannerTestCase1()) - suite.addTest(CScannerTestCase2()) - suite.addTest(CScannerTestCase3()) - suite.addTest(CScannerTestCase4()) - suite.addTest(CScannerTestCase5()) - suite.addTest(CScannerTestCase6()) - suite.addTest(CScannerTestCase8()) - suite.addTest(CScannerTestCase9()) - suite.addTest(CScannerTestCase10()) - suite.addTest(CScannerTestCase11()) - suite.addTest(CScannerTestCase12()) - suite.addTest(CScannerTestCase13()) - suite.addTest(CScannerTestCase14()) - suite.addTest(CScannerTestCase15()) - suite.addTest(CConditionalScannerTestCase1()) - suite.addTest(CConditionalScannerTestCase2()) - suite.addTest(CConditionalScannerTestCase3()) - suite.addTest(dictify_CPPDEFINESTestCase()) - return suite + with self.subTest(): + env = DummyEnvironment(CPPDEFINES=[("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", )]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} + self.assertEqual(d, expect) + + # string-valued define in a sequence + with self.subTest(): + env = DummyEnvironment(CPPDEFINES=["STRING=VALUE"]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'STRING': 'VALUE'} + self.assertEqual(d, expect) + + # string-valued define by itself + with self.subTest(): + env = DummyEnvironment(CPPDEFINES="STRING=VALUE") + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'STRING': 'VALUE'} + self.assertEqual(d, expect) + if __name__ == "__main__": - TestUnit.run(suite()) + unittest.main() # Local Variables: # tab-width:4 -- cgit v0.12 From 0d7dbd4b904dc6392851060d070244219cdd567d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 22 Mar 2023 07:45:42 -0600 Subject: dictify_CPPDEFINES: also handle single tuple * Single-tuple CPPDEFINES was not handled. * Add some more unit tests. * Add some comments - that we need to keep in sync with processDefines, but don't actually call it (the routine *could* be rewritten to process the result of processDefines instead of the bare CPPDEFINES, but currently doesn't do that). Signed-off-by: Mats Wichmann --- SCons/Scanner/C.py | 37 ++++++++++++++++++++++++++++++++----- SCons/Scanner/CTests.py | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 22 deletions(-) diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index 418454f..31ab7e6 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -21,7 +21,12 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"""Dependency scanner for C/C++ code.""" +"""Dependency scanner for C/C++ code. + +Two scanners are defined here: the default CScanner, and the optional +CConditionalScanner, which must be explicitly selected by calling +add_scanner() for each affected suffix. +""" import SCons.Node.FS import SCons.cpp @@ -62,11 +67,30 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): return '' def dictify_CPPDEFINES(env) -> dict: - """Returns CPPDEFINES converted to a dict.""" + """Returns CPPDEFINES converted to a dict. + + This should be similar to :func:`~SCons.Defaults.processDefines`. + Unfortunately, we can't do the simple thing of calling that routine and + passing the result to the dict() constructor, because it turns the defines + into a list of "name=value" pairs, which the dict constructor won't + consume correctly. Also cannot just call dict on CPPDEFINES itself - it's + fine if it's stored in the converted form (currently deque of tuples), but + CPPDEFINES could be in other formats too. + + So we have to do all the work here - keep concepts in sync with + ``processDefines``. + """ cppdefines = env.get('CPPDEFINES', {}) result = {} if cppdefines is None: return result + + if SCons.Util.is_Tuple(cppdefines): + try: + return {cppdefines[0]: cppdefines[1]} + except IndexError: + return {cppdefines[0]: None} + if SCons.Util.is_Sequence(cppdefines): for c in cppdefines: if SCons.Util.is_Sequence(c): @@ -85,15 +109,18 @@ def dictify_CPPDEFINES(env) -> dict: # don't really know what to do here result[c] = None return result + if SCons.Util.is_String(cppdefines): try: name, value = cppdefines.split('=') return {name: value} except ValueError: return {cppdefines: None} - if not SCons.Util.is_Dict(cppdefines): - return {cppdefines: None} - return cppdefines + + if SCons.Util.is_Dict(cppdefines): + return cppdefines + + return {cppdefines: None} class SConsCPPScannerWrapper: """The SCons wrapper around a cpp.py scanner. diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index e9780d0..0f62198 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -516,16 +516,14 @@ class CConditionalScannerTestCase4(unittest.TestCase): def runTest(self): """Test that dependency is detected if #include uses a macro.""" - # first try the macro defined in the source file - with self.subTest(): + with self.subTest("macro defined in the source file"): env = DummyEnvironment() s = SCons.Scanner.C.CConditionalScanner() deps = s(env.File('f9a.c'), env, s.path(env)) headers = ['f9.h'] deps_match(self, deps, headers) - # then try the macro defined on the command line - with self.subTest(): + with self.subTest("macro defined on the command line"): env = DummyEnvironment(CPPDEFINES='HEADER=\\"f9.h\\"') #env = DummyEnvironment(CPPDEFINES=['HEADER=\\"f9.h\\"']) s = SCons.Scanner.C.CConditionalScanner() @@ -536,29 +534,42 @@ class CConditionalScannerTestCase4(unittest.TestCase): class dictify_CPPDEFINESTestCase(unittest.TestCase): def runTest(self): - """Make sure single-item tuples convert correctly. + """Make sure CPPDEFINES converts correctly. - This is a regression test: AppendUnique turns sequences into - lists of tuples, and dictify could gack on these. + Various types and combinations of types could fail if not handled + specifically by dictify_CPPDEFINES - this is a regression test. """ - with self.subTest(): - env = DummyEnvironment(CPPDEFINES=[("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", )]) + with self.subTest("tuples in a sequence, including one without value"): + env = DummyEnvironment(CPPDEFINES=[("VALUED", 1), ("UNVALUED",)]) d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} + expect = {"VALUED": 1, "UNVALUED": None} self.assertEqual(d, expect) - # string-valued define in a sequence - with self.subTest(): - env = DummyEnvironment(CPPDEFINES=["STRING=VALUE"]) + with self.subTest("tuple-valued define by itself"): + env = DummyEnvironment(CPPDEFINES=("STRING", "VALUE")) d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'STRING': 'VALUE'} + expect = {"STRING": "VALUE"} self.assertEqual(d, expect) - # string-valued define by itself - with self.subTest(): + with self.subTest("string-valued define in a sequence"): + env = DummyEnvironment(CPPDEFINES=[("STRING=VALUE")]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {"STRING": "VALUE"} + self.assertEqual(d, expect) + + with self.subTest("string-valued define by itself"): env = DummyEnvironment(CPPDEFINES="STRING=VALUE") d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'STRING': 'VALUE'} + expect = {"STRING": "VALUE"} + self.assertEqual(d, expect) + + from collections import deque + with self.subTest("compound CPPDEFINES in internal format"): + env = DummyEnvironment( + CPPDEFINES=deque([("STRING", "VALUE"), ("UNVALUED",)]) + ) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {"STRING": "VALUE", "UNVALUED": None} self.assertEqual(d, expect) -- cgit v0.12 From dd38d6ecf206aabb4d4c4ee048f4706e26763b29 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 26 Mar 2023 22:43:01 -0400 Subject: Added blurb to RELEASE.txt --- RELEASE.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASE.txt b/RELEASE.txt index 769a12d..4f6f0a8 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -32,7 +32,11 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY FIXES ----- -- List fixes of outright bugs +- C scanner's dictifyCPPDEFINES routine did not understand the possible + combinations of CPPDEFINES - not aware of a "name=value" string either + embedded in a sequence, or by itself. The conditional C scanner thus + did not always properly apply the defines. The regular C scanner does + not use these, so was not affected. [fixes #4193] IMPROVEMENTS ------------ -- cgit v0.12 From 6ce33bdadec1cf558a6d0df27a6a083516d6cf23 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 20 Feb 2023 13:26:05 -0700 Subject: Minor cleanup ValidateOptions doc/code/test Some nearby things in Main.py as well: - docstrings polished a bit, minor linting - move the list of predefined SConstruct file names into a constant defined at the top of the file, so it's a little less hidden, in the unlikely case of future changes. Manpage text and example revised a bit. Signed-off-by: Mats Wichmann --- CHANGES.txt | 2 + SCons/Script/Main.py | 96 +++++++++++++-------- SCons/Script/Main.xml | 127 ++++++++++++++++------------ test/ValidateOptions.py | 64 +++++++++----- test/fixture/SConstruct-check-valid-options | 10 ++- 5 files changed, 186 insertions(+), 113 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c594979..6b3d888 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER embedded in a sequence, or by itself. The conditional C scanner thus did not always properly apply the defines. The regular C scanner does not use these, so was not affected. [fixes #4193] + - Minor cleanup for ValidateOptions - docs and docstring tweaked, + add missed versionadded indicator. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4228fa..e34301e 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -31,13 +31,8 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ -# these define the range of versions SCons supports -minimum_python_version = (3, 6, 0) -deprecated_python_version = (3, 6, 0) - import SCons.compat -import atexit import importlib.util import os import re @@ -46,6 +41,7 @@ import time import traceback import platform import threading +from typing import Optional, List import SCons.CacheDir import SCons.Debug @@ -66,6 +62,20 @@ import SCons.Script.Interactive from SCons import __version__ as SConsVersion +# these define the range of versions SCons supports +minimum_python_version = (3, 6, 0) +deprecated_python_version = (3, 6, 0) + +# ordered list of SConsctruct names to look for if there is no -f flag +KNOWN_SCONSTRUCT_NAMES = [ + 'SConstruct', + 'Sconstruct', + 'sconstruct', + 'SConstruct.py', + 'Sconstruct.py', + 'sconstruct.py', +] + # Global variables first_command_start = None last_command_end = None @@ -284,7 +294,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): node = buildError.node if not SCons.Util.is_List(node): - node = [ node ] + node = [node] nodename = ', '.join(map(str, node)) errfmt = "scons: *** [%s] %s\n" @@ -460,24 +470,29 @@ def python_version_deprecated(version=sys.version_info): class FakeOptionParser: - """ - A do-nothing option parser, used for the initial OptionsParser variable. + """A do-nothing option parser, used for the initial OptionsParser value. During normal SCons operation, the OptionsParser is created right - away by the main() function. Certain tests scripts however, can + away by the main() function. Certain test scripts however, can introspect on different Tool modules, the initialization of which can try to add a new, local option to an otherwise uninitialized OptionsParser object. This allows that introspection to happen without blowing up. - """ + class FakeOptionValues: def __getattr__(self, attr): return None + values = FakeOptionValues() + + # TODO: to quiet checkers, FakeOptionParser should also define + # raise_exception_on_error, preserve_unknown_options, largs and parse_args + def add_local_option(self, *args, **kw): pass + OptionsParser = FakeOptionParser() def AddOption(*args, **kw): @@ -492,22 +507,26 @@ def GetOption(name): def SetOption(name, value): return OptionsParser.values.set_option(name, value) - -def ValidateOptions(throw_exception=False) -> None: +def ValidateOptions(throw_exception: bool = False) -> None: """Validate options passed to SCons on the command line. - If you call this after you set all your command line options with AddOption(), - it will verify that all command line options are valid. - So if you added an option --xyz and you call SCons with --xyy you can cause + Checks that all options given on the command line are known to this + instance of SCons. Call after all of the cli options have been set + up through :func:`AddOption` calls. For example, if you added an + option ``--xyz`` and you call SCons with ``--xyy`` you can cause SCons to issue an error message and exit by calling this function. - :param bool throw_exception: (Optional) Should this function raise an error if there's an invalid option on the command line, or issue a message and exit with error status. + Arguments: + throw_exception: if an invalid option is present on the command line, + raises an exception if this optional parameter evaluates true; + if false (the default), issue a message and exit with error status. - :raises SConsBadOptionError: If throw_exception is True and there are invalid options on command line. + Raises: + SConsBadOptionError: If *throw_exception* is true and there are invalid + options on the command line. .. versionadded:: 4.5.0 """ - OptionsParser.raise_exception_on_error = throw_exception OptionsParser.preserve_unknown_options = False OptionsParser.parse_args(OptionsParser.largs, OptionsParser.values) @@ -641,13 +660,23 @@ def _scons_internal_error(): traceback.print_exc() sys.exit(2) -def _SConstruct_exists(dirname='', repositories=[], filelist=None): - """This function checks that an SConstruct file exists in a directory. - If so, it returns the path of the file. By default, it checks the - current directory. +def _SConstruct_exists( + dirname: str, repositories: List[str], filelist: List[str] +) -> Optional[str]: + """Check that an SConstruct file exists in a directory. + + Arguments: + dirname: the directory to search. If empty, look in cwd. + repositories: a list of repositories to search in addition to the + project directory tree. + filelist: names of SConstruct file(s) to search for. + If empty list, use the built-in list of names. + + Returns: + The path to the located SConstruct file, or ``None``. """ if not filelist: - filelist = ['SConstruct', 'Sconstruct', 'sconstruct', 'SConstruct.py', 'Sconstruct.py', 'sconstruct.py'] + filelist = KNOWN_SCONSTRUCT_NAMES for file in filelist: sfile = os.path.join(dirname, file) if os.path.isfile(sfile): @@ -679,14 +708,14 @@ def _set_debug_values(options): SCons.Warnings.warn(SCons.Warnings.NoObjectCountWarning, msg) if "dtree" in debug_values: options.tree_printers.append(TreePrinter(derived=True)) - options.debug_explain = ("explain" in debug_values) + options.debug_explain = "explain" in debug_values if "findlibs" in debug_values: SCons.Scanner.Prog.print_find_libs = "findlibs" - options.debug_includes = ("includes" in debug_values) - print_memoizer = ("memoizer" in debug_values) + options.debug_includes = "includes" in debug_values + print_memoizer = "memoizer" in debug_values if "memory" in debug_values: memory_stats.enable(sys.stdout) - print_objects = ("objects" in debug_values) + print_objects = "objects" in debug_values if print_objects: SCons.Debug.track_instances = True if "presub" in debug_values: @@ -919,9 +948,9 @@ def _main(parser): target_top = None if options.climb_up: target_top = '.' # directory to prepend to targets - while script_dir and not _SConstruct_exists(script_dir, - options.repository, - options.file): + while script_dir and not _SConstruct_exists( + script_dir, options.repository, options.file + ): script_dir, last_part = os.path.split(script_dir) if last_part: target_top = os.path.join(last_part, target_top) @@ -951,8 +980,7 @@ def _main(parser): if options.file: scripts.extend(options.file) if not scripts: - sfile = _SConstruct_exists(repositories=options.repository, - filelist=options.file) + sfile = _SConstruct_exists("", options.repository, options.file) if sfile: scripts.append(sfile) @@ -1011,8 +1039,8 @@ def _main(parser): # Next, set up the variables that hold command-line arguments, # so the SConscript files that we read and execute have access to them. # TODO: for options defined via AddOption which take space-separated - # option-args, the option-args will collect into targets here, - # because we don't yet know to do any different. + # option-args, the option-args will collect into targets here, + # because we don't yet know to do any different. targets = [] xmit_args = [] for a in parser.largs: diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 2070c36..379d534 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -749,7 +749,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 @@ -946,64 +946,79 @@ SetOption('max_drift', 0) - - - ([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: - - - + + ([throw_exception=False]) + + + + 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 + + + diff --git a/test/ValidateOptions.py b/test/ValidateOptions.py index 9b53c09..5dff386 100644 --- a/test/ValidateOptions.py +++ b/test/ValidateOptions.py @@ -28,38 +28,60 @@ Test ValidateOptions(). import TestSCons test = TestSCons.TestSCons() +# ref: test/fixture/SConstruct-check-valid-options test.file_fixture('fixture/SConstruct-check-valid-options', 'SConstruct') -# Should see "This is in SConstruct" because all options specified (none) are valid and -# so ValidatedOptions() won't exit before it's printed. +# Should see "This is in SConstruct" because all options specified (none) +# are valid and so ValidatedOptions() won't exit before it's printed. test.run() test.must_contain_single_instance_of(test.stdout(), ["This is in SConstruct"]) -# Should see "This is in SConstruct" because all options specified (--testing=abc) are valid and -# so ValidatedOptions() won't exit before it's printed. +# Should see "This is in SConstruct" because all options specified +# (--testing=abc) are valid and so ValidatedOptions() won't exit before +# it's printed. test.run(arguments="--testing=abc") test.must_contain_single_instance_of(test.stdout(), ["This is in SConstruct"]) -# Should not see "This is in SConstruct" because the option specified (--garbage=xyz) is invalid and -# so ValidatedOptions() will exit before it's printed. -test.run(arguments="--garbage=xyz", status=2, stderr=".*SCons Error: no such option: --garbage.*", - match=TestSCons.match_re_dotall) -test.fail_test(("This is in SConstruct" in test.stdout()), - message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') +# Should not see "This is in SConstruct" because the option specified +# (--garbage=xyz) is invalid and so ValidatedOptions() will exit +# before it's printed. +test.run( + arguments="--garbage=xyz", + status=2, + stderr=".*SCons Error: no such option: --garbage.*", + match=TestSCons.match_re_dotall, +) +test.fail_test( + ("This is in SConstruct" in test.stdout()), + message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed', +) # Now we'll test having ValidateOptions raise a SConsBadOptionError exception -test.run(arguments="--garbage=xyz raise=1", status=2, - stderr=".*SConsBadOptionError: no such option: no such option: --garbage.*", - match=TestSCons.match_re_dotall) -test.fail_test(("This is in SConstruct" in test.stdout()), - message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') +test.run( + arguments="--garbage=xyz raise=1", + status=2, + stderr=".*SConsBadOptionError: no such option: no such option: --garbage.*", + match=TestSCons.match_re_dotall, +) +test.fail_test( + ("This is in SConstruct" in test.stdout()), + message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed', +) -# Now we'll test having ValidateOptions raise a SConsBadOptionError exception and catching that exception -test.run(arguments="--garbage=xyz raise=2", status=3, - stdout=".*Parser is SConsOptionParser:True.*Message is .no such option. --garbage.*", - match=TestSCons.match_re_dotall) -test.fail_test(("This is in SConstruct" in test.stdout()), - message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed') +# Now we'll test having ValidateOptions raise a SConsBadOptionError +# exception and catching that exception +test.run( + arguments="--garbage=xyz raise=2", + status=3, + stdout=".*Parser is SConsOptionParser: True.*Message is. no such option. --garbage.*", + match=TestSCons.match_re_dotall, +) +test.fail_test( + ("This is in SConstruct" in test.stdout()), + message='"This is in SConstruct" should not be output. This means ValidateOptions() did not error out before this was printed', +) + +test.pass_test() # Local Variables: # tab-width:4 diff --git a/test/fixture/SConstruct-check-valid-options b/test/fixture/SConstruct-check-valid-options index 2c935a2..53bdf89 100644 --- a/test/fixture/SConstruct-check-valid-options +++ b/test/fixture/SConstruct-check-valid-options @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: MIT +# +# Copyright The SCons Foundation + import sys from SCons.Script.SConsOptions import SConsOptionParser, SConsBadOptionError @@ -12,8 +16,10 @@ elif ARGUMENTS.get('raise', 0) == '2': 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"Parser is SConsOptionParser: {isinstance(e.parser, SConsOptionParser)}" + ) + print(f"Message is: {e.opt_str}") Exit(3) else: ValidateOptions() -- cgit v0.12 From 9594422c63ea550ea941b88ec43e856de764ce7b Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:30:27 -0400 Subject: MSCommon: minor updates to README.rst [skip ci] Changes: * Fix typographical error (missing word). * Add lines between literal block markers and indented text. * Expand build tools lists in Visual Studio table. --- SCons/Tool/MSCommon/README.rst | 44 +++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/SCons/Tool/MSCommon/README.rst b/SCons/Tool/MSCommon/README.rst index 36e58aa..5ab07ad 100644 --- a/SCons/Tool/MSCommon/README.rst +++ b/SCons/Tool/MSCommon/README.rst @@ -40,7 +40,7 @@ The following issues are known to exist: * The code to suppress the "No versions of the MSVC compiler were found" warning for the default environment was moved from ``MSCommon/vc.py`` to ``MSCommon/MSVC/SetupEnvDefault.py``. - There very few, if any, existing unit tests. Now that the code is isolated in its own + There are very few, if any, existing unit tests. Now that the code is isolated in its own module with a limited API, unit tests may be easier to implement. @@ -59,6 +59,7 @@ This is a proxy for using the toolset version for selection until that functiona Example usage: :: + for version in [ '14.3', '14.2', @@ -90,6 +91,7 @@ Example usage: Example output fragment :: + Build: _build003 {'MSVC_VERSION': '14.3', 'MSVC_TOOLSET_VERSION': '14.29.30133'} Where: C:\Software\MSVS-2022-143-Com\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe Where: C:\Software\MSVS-2022-143-Com\Common7\Tools\guidgen.exe @@ -138,6 +140,7 @@ for build failures. Refer to the documentation for details. Change the default policy: :: + from SCons.Tool.MSCommon import msvc_set_scripterror_policy msvc_set_scripterror_policy('Warning') @@ -169,6 +172,7 @@ detection of installed msvc instances. Windows command-line sample invocations: :: + @rem 64-Bit Windows "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -all -sort -prerelease -products * -legacy -format json >MYVSWHEREOUTPUT.json @@ -241,6 +245,7 @@ toolset specification should be omitted entirely. Local installation and summary test results: :: + VS2022\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt 14.31.31103 @@ -249,6 +254,7 @@ Local installation and summary test results: Toolset version summary: :: + 14.31.31103 Environment() 14.31.31103 Environment(MSVC_TOOLSET_VERSION=None) @@ -263,6 +269,7 @@ Toolset version summary: VS2022\\Common7\\Tools\\vsdevcmd\\ext\\vcvars.bat usage fragment: :: + @echo -vcvars_ver=version : Version of VC++ Toolset to select @echo ** [Default] : If -vcvars_ver=version is NOT specified, the toolset specified by @echo [VSInstallDir]\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt will be used. @@ -283,6 +290,7 @@ VS2022\\Common7\\Tools\\vsdevcmd\\ext\\vcvars.bat usage fragment: VS2022 batch file fragment to determine the default toolset version: :: + @REM Add MSVC set "__VCVARS_DEFAULT_CONFIG_FILE=%VCINSTALLDIR%Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" @@ -349,33 +357,33 @@ v60 6.0 12.0 60 Product Versions ---------------- -======== ===== ========= ============ +======== ===== ========= ====================== Product VSVER SDK BuildTools -======== ===== ========= ============ -2022 17.0 10.0, 8.1 v143 .. v140 --------- ----- --------- ------------ -2019 16.0 10.0, 8.1 v142 .. v140 --------- ----- --------- ------------ -2017 15.0 10.0, 8.1 v141 .. v140 --------- ----- --------- ------------ +======== ===== ========= ====================== +2022 17.0 10.0, 8.1 v143, v142, v141, v140 +-------- ----- --------- ---------------------- +2019 16.0 10.0, 8.1 v142, v141, v140 +-------- ----- --------- ---------------------- +2017 15.0 10.0, 8.1 v141, v140 +-------- ----- --------- ---------------------- 2015 14.0 10.0, 8.1 v140 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2013 12.0 v120 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2012 11.0 v110 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2010 10.0 v100 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2008 9.0 v90 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2005 8.0 v80 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2003.NET 7.1 v71 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2002.NET 7.0 v70 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 6.0 6.0 v60 -======== ===== ========= ============ +======== ===== ========= ====================== SCons Implementation Notes -- cgit v0.12 From 05864ca5926e54446753788be5cf7e77f6db08c0 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 14 Apr 2023 14:49:48 -0600 Subject: Drop coverage from CI, don't add mingw Experiment: coverage build broke because "codecov" package removed from PyPI on 12 Apr 2023. We'll need to re-craft a coverage build, for now just don't set COVERAGE true for any appveyor build (leaving the framework in place to copy to the new setup). Experiment: the setup of mingw for the github action for experimental features on Windows is failing for unknown reason ("error code 1"), possibly sourceforge failure, possibly something else. But - we shouldn't need to install mingw into an environment that is already provisioned with mingw. Try that. Apparently it's technically a syntax error for setup.cfg lines (that are not continuation lines) to be indented - had one tool gripe about this, which was made happy by dedenting one line. Including that in this PR, just because... Signed-off-by: Mats Wichmann --- .appveyor.yml | 2 +- .github/workflows/experimental_tests.yml | 14 ++++++++------ setup.cfg | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index a8db5e9..f7e23f6 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -30,6 +30,7 @@ install: # Leaving the Coverage build on VS2017 for build-time reasons (1hr time limit). # maybe move coverage to github in future to restore some flexibility? environment: + # set COVERAGE to 1 for any builder that should run it COVERAGE: 0 SCONS_CACHE_MSVC_CONFIG: "true" matrix: @@ -42,7 +43,6 @@ environment: - WINPYTHON: "Python38" - WINPYTHON: "Python36" - COVERAGE: 1 # remove sets of build jobs based on criteria below # to fine tune the number and platforms tested diff --git a/.github/workflows/experimental_tests.yml b/.github/workflows/experimental_tests.yml index 8717b14..0ff03a3 100644 --- a/.github/workflows/experimental_tests.yml +++ b/.github/workflows/experimental_tests.yml @@ -23,7 +23,8 @@ jobs: matrix: # note: in the 2nd half of 2022 the setup-mingw was often failing on # windows-latest. revisit someday (perhaps when there's an @v3) - os: ['ubuntu-latest', 'windows-2019', 'macos-latest'] + #os: ['ubuntu-latest', 'windows-2019', 'macos-latest'] + os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] # The type of runner that the job will run on runs-on: ${{ matrix.os }} @@ -33,11 +34,12 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - - name: Set up MinGW - uses: egor-tensin/setup-mingw@v2 - if: matrix.os == 'windows-2019' - with: - platform: x64 + # experiment: looks like we don't need this if we use windows-latest + #- name: Set up MinGW + # uses: egor-tensin/setup-mingw@v2 + # if: matrix.os == 'windows-2019' + # with: + # platform: x64 - name: Set up Python 3.11 ${{ matrix.os }} uses: actions/setup-python@v2 diff --git a/setup.cfg b/setup.cfg index f177d6f..67a0385 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,7 +75,7 @@ SCons.Tool.docbook = *.* sconsign.1 [sdist] - dist_dir=build/dist +dist_dir=build/dist [bdist_wheel] ; We're now py3 only -- cgit v0.12 From 991bf6744dbe73ce49e8d3ce3c2a6400517b89df Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 15 Apr 2023 09:08:55 -0600 Subject: Put back the setup-mingw [skip appveyor] The test ran through the two mingw tests in the experimental ninja tests, but hung up later - apparently on test/ninja\ninja_command_line.py. Try putting the install step back in. Signed-off-by: Mats Wichmann --- .github/workflows/experimental_tests.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/experimental_tests.yml b/.github/workflows/experimental_tests.yml index 0ff03a3..c272d51 100644 --- a/.github/workflows/experimental_tests.yml +++ b/.github/workflows/experimental_tests.yml @@ -23,8 +23,8 @@ jobs: matrix: # note: in the 2nd half of 2022 the setup-mingw was often failing on # windows-latest. revisit someday (perhaps when there's an @v3) - #os: ['ubuntu-latest', 'windows-2019', 'macos-latest'] - os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] + #os: ['ubuntu-latest', 'windows-latest', 'macos-latest'] + os: ['ubuntu-latest', 'windows-2019', 'macos-latest'] # The type of runner that the job will run on runs-on: ${{ matrix.os }} @@ -34,12 +34,13 @@ jobs: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v2 - # experiment: looks like we don't need this if we use windows-latest - #- name: Set up MinGW - # uses: egor-tensin/setup-mingw@v2 - # if: matrix.os == 'windows-2019' - # with: - # platform: x64 + # experiment: maybe don't need this? + # update: looks like we do: with this commented out, the build hung + - name: Set up MinGW + uses: egor-tensin/setup-mingw@v2 + if: matrix.os == 'windows-2019' + with: + platform: x64 - name: Set up Python 3.11 ${{ matrix.os }} uses: actions/setup-python@v2 -- cgit v0.12 From 1a103470a13a83590b3fc06e8779494e2b99751d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 1 May 2023 11:54:48 -0600 Subject: Add some cheap return and parameter annotations Use: https://github.com/JelleZijlstra/autotyping to add "safe" return annotations. Where a parameter has a default value that is an obvious scalar type (bool, int, str, etc.) add those annotations as well. Also fixed two small bugs that popped up when sanity-checking with mypy. One in FortranCommon, where a return had been previously annotated to be a tuple of Action, which should be ActionBase - Action is the factory function, not the base class. The other was a typo in the error raised in _add_cppdefines - the message was formatted with the value of "define" which should have been "defines". Signed-off-by: Mats Wichmann --- .editorconfig | 2 +- CHANGES.txt | 2 + SCons/Action.py | 44 +-- SCons/ActionTests.py | 316 +++++++++--------- SCons/Builder.py | 42 +-- SCons/BuilderTests.py | 144 ++++----- SCons/CacheDir.py | 10 +- SCons/CacheDirTests.py | 44 +-- SCons/Conftest.py | 12 +- SCons/Debug.py | 24 +- SCons/Defaults.py | 16 +- SCons/DefaultsTests.py | 12 +- SCons/Environment.py | 122 +++---- SCons/EnvironmentTests.py | 388 +++++++++++------------ SCons/EnvironmentValues.py | 8 +- SCons/EnvironmentValuesTest.py | 2 +- SCons/Errors.py | 8 +- SCons/ErrorsTests.py | 4 +- SCons/Executor.py | 64 ++-- SCons/ExecutorTests.py | 68 ++-- SCons/Memoize.py | 14 +- SCons/MemoizeTests.py | 8 +- SCons/Node/Alias.py | 16 +- SCons/Node/AliasTests.py | 16 +- SCons/Node/FS.py | 166 +++++----- SCons/Node/FSTests.py | 240 +++++++------- SCons/Node/NodeTests.py | 190 +++++------ SCons/Node/Python.py | 14 +- SCons/Node/PythonTests.py | 26 +- SCons/Node/__init__.py | 122 +++---- SCons/PathList.py | 6 +- SCons/PathListTests.py | 28 +- SCons/Platform/PlatformTests.py | 18 +- SCons/Platform/__init__.py | 8 +- SCons/Platform/aix.py | 2 +- SCons/Platform/cygwin.py | 2 +- SCons/Platform/darwin.py | 2 +- SCons/Platform/hpux.py | 2 +- SCons/Platform/irix.py | 2 +- SCons/Platform/os2.py | 2 +- SCons/Platform/posix.py | 2 +- SCons/Platform/sunos.py | 2 +- SCons/Platform/virtualenv.py | 8 +- SCons/Platform/virtualenvTests.py | 36 +-- SCons/Platform/win32.py | 4 +- SCons/SConf.py | 116 +++---- SCons/SConfTests.py | 82 ++--- SCons/SConsign.py | 38 +-- SCons/SConsignTests.py | 34 +- SCons/Scanner/C.py | 12 +- SCons/Scanner/CTests.py | 44 +-- SCons/Scanner/D.py | 2 +- SCons/Scanner/DTests.py | 28 +- SCons/Scanner/DirTests.py | 8 +- SCons/Scanner/Fortran.py | 4 +- SCons/Scanner/FortranTests.py | 44 +-- SCons/Scanner/IDLTests.py | 36 +-- SCons/Scanner/Java.py | 2 +- SCons/Scanner/JavaTests.py | 36 +-- SCons/Scanner/LaTeX.py | 10 +- SCons/Scanner/LaTeXTests.py | 12 +- SCons/Scanner/ProgTests.py | 32 +- SCons/Scanner/PythonTests.py | 38 +-- SCons/Scanner/RCTests.py | 12 +- SCons/Scanner/ScannerTests.py | 92 +++--- SCons/Scanner/__init__.py | 20 +- SCons/Script/Interactive.py | 24 +- SCons/Script/Main.py | 98 +++--- SCons/Script/SConsOptions.py | 22 +- SCons/Script/SConscript.py | 22 +- SCons/Script/__init__.py | 16 +- SCons/Subst.py | 62 ++-- SCons/SubstTests.py | 110 +++---- SCons/Taskmaster/Job.py | 42 +-- SCons/Taskmaster/JobTests.py | 76 ++--- SCons/Taskmaster/TaskmasterTests.py | 90 +++--- SCons/Taskmaster/__init__.py | 46 +-- SCons/Tool/386asm.py | 2 +- SCons/Tool/DCommon.py | 4 +- SCons/Tool/FortranCommon.py | 8 +- SCons/Tool/FortranCommonTests.py | 10 +- SCons/Tool/GettextCommon.py | 14 +- SCons/Tool/JavaCommon.py | 28 +- SCons/Tool/JavaCommonTests.py | 40 +-- SCons/Tool/MSCommon/MSVC/ConfigTests.py | 10 +- SCons/Tool/MSCommon/MSVC/Dispatcher.py | 8 +- SCons/Tool/MSCommon/MSVC/DispatcherTests.py | 24 +- SCons/Tool/MSCommon/MSVC/PolicyTests.py | 30 +- SCons/Tool/MSCommon/MSVC/Registry.py | 8 +- SCons/Tool/MSCommon/MSVC/RegistryTests.py | 14 +- SCons/Tool/MSCommon/MSVC/ScriptArguments.py | 22 +- SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py | 26 +- SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py | 10 +- SCons/Tool/MSCommon/MSVC/UtilTests.py | 20 +- SCons/Tool/MSCommon/MSVC/WinSDK.py | 10 +- SCons/Tool/MSCommon/MSVC/WinSDKTests.py | 24 +- SCons/Tool/MSCommon/MSVC/__init__.py | 4 +- SCons/Tool/MSCommon/arch.py | 2 +- SCons/Tool/MSCommon/common.py | 8 +- SCons/Tool/MSCommon/sdk.py | 8 +- SCons/Tool/MSCommon/vc.py | 14 +- SCons/Tool/MSCommon/vcTests.py | 52 +-- SCons/Tool/MSCommon/vs.py | 10 +- SCons/Tool/PharLapCommon.py | 2 +- SCons/Tool/ToolTests.py | 14 +- SCons/Tool/__init__.py | 22 +- SCons/Tool/aixcc.py | 2 +- SCons/Tool/aixcxx.py | 2 +- SCons/Tool/aixf77.py | 2 +- SCons/Tool/aixlink.py | 2 +- SCons/Tool/applelink.py | 8 +- SCons/Tool/ar.py | 2 +- SCons/Tool/asm.py | 2 +- SCons/Tool/bcc32.py | 2 +- SCons/Tool/cc.py | 4 +- SCons/Tool/clang.py | 2 +- SCons/Tool/clangxx.py | 2 +- SCons/Tool/compilation_db.py | 12 +- SCons/Tool/cvf.py | 2 +- SCons/Tool/cxx.py | 4 +- SCons/Tool/cyglink.py | 6 +- SCons/Tool/default.py | 4 +- SCons/Tool/dmd.py | 2 +- SCons/Tool/docbook/__init__.py | 18 +- SCons/Tool/dvi.py | 4 +- SCons/Tool/dvipdf.py | 4 +- SCons/Tool/dvips.py | 2 +- SCons/Tool/f03.py | 2 +- SCons/Tool/f08.py | 2 +- SCons/Tool/f77.py | 2 +- SCons/Tool/f90.py | 2 +- SCons/Tool/f95.py | 2 +- SCons/Tool/filesystem.py | 6 +- SCons/Tool/fortran.py | 2 +- SCons/Tool/g77.py | 2 +- SCons/Tool/gas.py | 2 +- SCons/Tool/gcc.py | 2 +- SCons/Tool/gdc.py | 2 +- SCons/Tool/gettext_tool.py | 2 +- SCons/Tool/gfortran.py | 2 +- SCons/Tool/gnulink.py | 2 +- SCons/Tool/gs.py | 2 +- SCons/Tool/gxx.py | 2 +- SCons/Tool/hpcc.py | 2 +- SCons/Tool/hpcxx.py | 2 +- SCons/Tool/hplink.py | 2 +- SCons/Tool/icc.py | 2 +- SCons/Tool/ifl.py | 2 +- SCons/Tool/ifort.py | 2 +- SCons/Tool/ilink.py | 2 +- SCons/Tool/ilink32.py | 2 +- SCons/Tool/install.py | 12 +- SCons/Tool/intelc.py | 2 +- SCons/Tool/ipkg.py | 2 +- SCons/Tool/jar.py | 2 +- SCons/Tool/javac.py | 8 +- SCons/Tool/javacTests.py | 28 +- SCons/Tool/javah.py | 4 +- SCons/Tool/latex.py | 2 +- SCons/Tool/ldc.py | 2 +- SCons/Tool/lex.py | 2 +- SCons/Tool/link.py | 2 +- SCons/Tool/linkCommon/LoadableModule.py | 4 +- SCons/Tool/linkCommon/SharedLibrary.py | 4 +- SCons/Tool/linkCommon/__init__.py | 8 +- SCons/Tool/linkCommon/linkCommmonTests.py | 4 +- SCons/Tool/linkloc.py | 4 +- SCons/Tool/m4.py | 2 +- SCons/Tool/masm.py | 2 +- SCons/Tool/midl.py | 2 +- SCons/Tool/mingw.py | 2 +- SCons/Tool/msgfmt.py | 2 +- SCons/Tool/msginit.py | 2 +- SCons/Tool/msgmerge.py | 2 +- SCons/Tool/mslib.py | 2 +- SCons/Tool/mslink.py | 2 +- SCons/Tool/mssdk.py | 2 +- SCons/Tool/msvc.py | 4 +- SCons/Tool/msvs.py | 70 ++-- SCons/Tool/msvsTests.py | 36 +-- SCons/Tool/mwcc.py | 8 +- SCons/Tool/mwld.py | 2 +- SCons/Tool/nasm.py | 2 +- SCons/Tool/ninja/Methods.py | 12 +- SCons/Tool/ninja/NinjaState.py | 10 +- SCons/Tool/ninja/Overrides.py | 8 +- SCons/Tool/ninja/Utils.py | 12 +- SCons/Tool/ninja/__init__.py | 8 +- SCons/Tool/ninja/ninja_daemon_build.py | 2 +- SCons/Tool/ninja/ninja_run_daemon.py | 2 +- SCons/Tool/ninja/ninja_scons_daemon.py | 18 +- SCons/Tool/packaging/__init__.py | 12 +- SCons/Tool/packaging/ipk.py | 2 +- SCons/Tool/packaging/msi.py | 16 +- SCons/Tool/packaging/rpm.py | 2 +- SCons/Tool/pdf.py | 6 +- SCons/Tool/pdflatex.py | 2 +- SCons/Tool/pdftex.py | 2 +- SCons/Tool/python.py | 4 +- SCons/Tool/qt.py | 2 +- SCons/Tool/qt3.py | 4 +- SCons/Tool/rmic.py | 4 +- SCons/Tool/rpcgen.py | 2 +- SCons/Tool/rpm.py | 4 +- SCons/Tool/rpmutils.py | 8 +- SCons/Tool/sgiar.py | 2 +- SCons/Tool/sgicc.py | 2 +- SCons/Tool/sgicxx.py | 2 +- SCons/Tool/sgilink.py | 2 +- SCons/Tool/sunar.py | 2 +- SCons/Tool/suncc.py | 2 +- SCons/Tool/suncxx.py | 2 +- SCons/Tool/sunf77.py | 2 +- SCons/Tool/sunf90.py | 2 +- SCons/Tool/sunf95.py | 2 +- SCons/Tool/sunlink.py | 2 +- SCons/Tool/swig.py | 6 +- SCons/Tool/tar.py | 2 +- SCons/Tool/tex.py | 12 +- SCons/Tool/textfile.py | 8 +- SCons/Tool/tlib.py | 2 +- SCons/Tool/wix.py | 2 +- SCons/Tool/wixTests.py | 2 +- SCons/Tool/xgettext.py | 6 +- SCons/Tool/yacc.py | 2 +- SCons/Tool/zip.py | 6 +- SCons/Util/__init__.py | 56 ++-- SCons/Util/envs.py | 10 +- SCons/Util/hashes.py | 6 +- SCons/Util/types.py | 12 +- SCons/UtilTests.py | 154 ++++----- SCons/Utilities/ConfigureCache.py | 2 +- SCons/Utilities/sconsign.py | 16 +- SCons/Variables/BoolVariableTests.py | 6 +- SCons/Variables/EnumVariable.py | 2 +- SCons/Variables/EnumVariableTests.py | 10 +- SCons/Variables/ListVariable.py | 4 +- SCons/Variables/ListVariableTests.py | 6 +- SCons/Variables/PackageVariableTests.py | 6 +- SCons/Variables/PathVariableTests.py | 4 +- SCons/Variables/VariablesTests.py | 44 +-- SCons/Variables/__init__.py | 4 +- SCons/Warnings.py | 8 +- SCons/WarningsTests.py | 8 +- SCons/compat/__init__.py | 2 +- SCons/cpp.py | 44 +-- SCons/cppTests.py | 46 +-- SCons/dblite.py | 16 +- SCons/exitfuncs.py | 4 +- testing/framework/TestCmd.py | 108 +++---- testing/framework/TestCmdTests.py | 222 ++++++------- testing/framework/TestCommon.py | 52 +-- testing/framework/TestCommonTests.py | 190 +++++------ testing/framework/TestRuntest.py | 10 +- testing/framework/TestSCons.py | 74 ++--- testing/framework/TestSConsMSVS.py | 12 +- testing/framework/TestSCons_time.py | 8 +- testing/framework/TestSConsign.py | 4 +- testing/framework/TestUnit/cli.py | 2 +- testing/framework/TestUnit/taprunner.py | 28 +- 260 files changed, 2897 insertions(+), 2893 deletions(-) diff --git a/.editorconfig b/.editorconfig index 3d2b699..1889885 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ end_of_line = lf charset = utf-8 [*.py] -max_line_length = 88 +max_line_length = 78 ensure_newline_before_comments = true include_trailing_comma = true use_parentheses = true diff --git a/CHANGES.txt b/CHANGES.txt index c594979..e6f4967 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER embedded in a sequence, or by itself. The conditional C scanner thus did not always properly apply the defines. The regular C scanner does not use these, so was not affected. [fixes #4193] + - Added some typing annotations generated by a tool, to eliminate manual + work in future on things which are safe for the tool to produce. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Action.py b/SCons/Action.py index 1f5e548..3f1a24e 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -597,8 +597,8 @@ class _ActionAction(ActionBase): """Base class for actions that create output objects.""" def __init__(self, cmdstr=_null, strfunction=_null, varlist=(), presub=_null, chdir=None, exitstatfunc=None, - batch_key=None, targets='$TARGETS', - **kw): + batch_key=None, targets: str='$TARGETS', + **kw) -> None: self.cmdstr = cmdstr if strfunction is not _null: if strfunction is None: @@ -625,7 +625,7 @@ class _ActionAction(ActionBase): batch_key = default_batch_key SCons.Util.AddMethod(self, batch_key, 'batch_key') - def print_cmd_line(self, s, target, source, env): + def print_cmd_line(self, s, target, source, env) -> None: """ In python 3, and in some of our tests, sys.stdout is a String io object, and it takes unicode strings only @@ -787,7 +787,7 @@ def _resolve_shell_env(env, target, source): return ENV -def _subproc(scons_env, cmd, error='ignore', **kw): +def _subproc(scons_env, cmd, error: str='ignore', **kw): """Wrapper for subprocess which pulls from construction env. Use for calls to subprocess which need to interpolate values from @@ -814,7 +814,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): if error == 'raise': raise # return a dummy Popen instance that only returns error class dummyPopen: - def __init__(self, e): + def __init__(self, e) -> None: self.exception = e # Add the following two to enable using the return value as a context manager # for example @@ -824,7 +824,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): def __enter__(self): return self - def __exit__(self, *args): + def __exit__(self, *args) -> None: pass def communicate(self, input=None): @@ -835,8 +835,8 @@ def _subproc(scons_env, cmd, error='ignore', **kw): stdin = None class f: - def read(self): return '' - def readline(self): return '' + def read(self) -> str: return '' + def readline(self) -> str: return '' def __iter__(self): return iter(()) stdout = stderr = f() pobj = dummyPopen(e) @@ -851,7 +851,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): class CommandAction(_ActionAction): """Class for command-execution actions.""" - def __init__(self, cmd, **kw): + def __init__(self, cmd, **kw) -> None: # Cmd can actually be a list or a single item; if it's a # single item it should be the command string to execute; if a # list then it should be the words of the command string to @@ -870,12 +870,12 @@ class CommandAction(_ActionAction): "a single command") self.cmd_list = cmd - def __str__(self): + def __str__(self) -> str: if is_List(self.cmd_list): return ' '.join(map(str, self.cmd_list)) return str(self.cmd_list) - def process(self, target, source, env, executor=None, overrides=False): + def process(self, target, source, env, executor=None, overrides: bool=False): if executor: result = env.subst_list(self.cmd_list, 0, executor=executor, overrides=overrides) else: @@ -896,7 +896,7 @@ class CommandAction(_ActionAction): pass return result, ignore, silent - def strfunction(self, target, source, env, executor=None, overrides=False): + def strfunction(self, target, source, env, executor=None, overrides: bool=False): if self.cmdstr is None: return None if self.cmdstr is not _null: @@ -1099,7 +1099,7 @@ class CommandAction(_ActionAction): class CommandGeneratorAction(ActionBase): """Class for command-generator actions.""" - def __init__(self, generator, kw): + def __init__(self, generator, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.CommandGeneratorAction') self.generator = generator self.gen_kw = kw @@ -1124,7 +1124,7 @@ class CommandGeneratorAction(ActionBase): raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret)) return gen_cmd - def __str__(self): + def __str__(self) -> str: try: env = self.presub_env except AttributeError: @@ -1191,7 +1191,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): an action based on what's in the construction variable. """ - def __init__(self, var, kw): + def __init__(self, var, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction') CommandAction.__init__(self, '${'+var+'}', **kw) self.var = SCons.Util.to_String(var) @@ -1232,7 +1232,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): class FunctionAction(_ActionAction): """Class for Python function actions.""" - def __init__(self, execfunction, kw): + def __init__(self, execfunction, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.FunctionAction') self.execfunction = execfunction @@ -1293,7 +1293,7 @@ class FunctionAction(_ActionAction): sstr = array(source) return "%s(%s, %s)" % (name, tstr, sstr) - def __str__(self): + def __str__(self) -> str: name = self.function_name() if name == 'ActionCaller': return str(self.execfunction) @@ -1354,7 +1354,7 @@ class FunctionAction(_ActionAction): class ListAction(ActionBase): """Class for lists of other actions.""" - def __init__(self, actionlist): + def __init__(self, actionlist) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.ListAction') def list_of_actions(x): if isinstance(x, ActionBase): @@ -1369,7 +1369,7 @@ class ListAction(ActionBase): def genstring(self, target, source, env): return '\n'.join([a.genstring(target, source, env) for a in self.list]) - def __str__(self): + def __str__(self) -> str: return '\n'.join(map(str, self.list)) def presub_lines(self, env): @@ -1418,7 +1418,7 @@ class ActionCaller: but what it's really doing is hanging on to the arguments until we have a target, source and env to use for the expansion. """ - def __init__(self, parent, args, kw): + def __init__(self, parent, args, kw) -> None: self.parent = parent self.args = args self.kw = kw @@ -1476,7 +1476,7 @@ class ActionCaller: kw = self.subst_kw(target, source, env) return self.parent.strfunc(*args, **kw) - def __str__(self): + def __str__(self) -> str: return self.parent.strfunc(*self.args, **self.kw) @@ -1489,7 +1489,7 @@ class ActionFactory: called with and give them to the ActionCaller object we create, so it can hang onto them until it needs them. """ - def __init__(self, actfunc, strfunc, convert=lambda x: x): + def __init__(self, actfunc, strfunc, convert=lambda x: x) -> None: self.actfunc = actfunc self.strfunc = strfunc self.convert = convert diff --git a/SCons/ActionTests.py b/SCons/ActionTests.py index 88bb36f..2e6204e 100644 --- a/SCons/ActionTests.py +++ b/SCons/ActionTests.py @@ -27,12 +27,12 @@ # contents, so try to minimize changes by defining them here, before we # even import anything. -def GlobalFunc(): +def GlobalFunc() -> None: pass class GlobalActFunc: - def __call__(self): + def __call__(self) -> None: pass @@ -105,7 +105,7 @@ sys.stdout = io.StringIO() class CmdStringHolder: - def __init__(self, cmd, literal=None): + def __init__(self, cmd, literal=None) -> None: self.data = str(cmd) self.literal = literal @@ -132,7 +132,7 @@ class CmdStringHolder: class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.d = {} self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] @@ -142,23 +142,23 @@ class Environment: self.d[k] = v # Just use the underlying scons_subst*() utility methods. - def subst(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False): + def subst(self, strSubst, raw: int=0, target=[], source=[], conv=None, overrides: bool=False): return SCons.Subst.scons_subst(strSubst, self, raw, target, source, self.d, conv=conv, overrides=overrides) subst_target_source = subst - def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False): + def subst_list(self, strSubst, raw: int=0, target=[], source=[], conv=None, overrides: bool=False): return SCons.Subst.scons_subst_list(strSubst, self, raw, target, source, self.d, conv=conv, overrides=overrides) def __getitem__(self, item): return self.d[item] - def __setitem__(self, item, value): + def __setitem__(self, item, value) -> None: self.d[item] = value - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.d def get(self, key, value=None): @@ -188,13 +188,13 @@ class Environment: class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name def str_for_display(self): return '"' + self.name + '"' - def __str__(self): + def __str__(self) -> str: return self.name def rfile(self): @@ -213,7 +213,7 @@ _python_ = test.escape(python) _null = SCons.Action._null -def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw): +def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw) -> None: def call_action(a, pos_call=pos_call, str_call=str_call, kw=kw): a = SCons.Action.Action(*a, **kw) # returned object must provide these entry points @@ -260,7 +260,7 @@ def test_positional_args(pos_callback, cmd, **kw): if not isinstance(act, SCons.Action._ActionAction): # only valid cmdstrfunc is None - def none(a): + def none(a) -> None: pass test_varlist(pos_callback, none, cmd, None, **kw) @@ -273,22 +273,22 @@ def test_positional_args(pos_callback, cmd, **kw): assert act.exitstatfunc is SCons.Action.default_exitstatfunc, \ act.exitstatfunc - def cmdstr(a): + def cmdstr(a) -> None: assert hasattr(a, 'strfunction') assert a.cmdstr == 'cmdstr', a.cmdstr test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw) - def fun(): + def fun() -> None: pass - def strfun(a, fun=fun): + def strfun(a, fun=fun) -> None: assert a.strfunction is fun, a.strfunction assert a.cmdstr == _null, a.cmdstr test_varlist(pos_callback, strfun, cmd, fun, **kw) - def none(a): + def none(a) -> None: assert hasattr(a, 'strfunction') assert a.cmdstr is None, a.cmdstr @@ -310,13 +310,13 @@ def test_positional_args(pos_callback, cmd, **kw): class ActionTestCase(unittest.TestCase): """Test the Action() factory function""" - def test_FunctionAction(self): + def test_FunctionAction(self) -> None: """Test the Action() factory's creation of FunctionAction objects.""" - def foo(): + def foo() -> None: pass - def func_action(a, foo=foo): + def func_action(a, foo=foo) -> None: assert isinstance(a, SCons.Action.FunctionAction), a assert a.execfunction == foo, a.execfunction @@ -324,10 +324,10 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(func_action, [foo]) - def test_CommandAction(self): + def test_CommandAction(self) -> None: """Test the Action() factory's creation of CommandAction objects.""" - def cmd_action(a): + def cmd_action(a) -> None: assert isinstance(a, SCons.Action.CommandAction), a assert a.cmd_list == "string", a.cmd_list @@ -335,13 +335,13 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(cmd_action, ["string"]) - def line_action(a): + def line_action(a) -> None: assert isinstance(a, SCons.Action.CommandAction), a assert a.cmd_list == ["explicit", "command", "line"], a.cmd_list test_positional_args(line_action, [["explicit", "command", "line"]]) - def test_ListAction(self): + def test_ListAction(self) -> None: """Test the Action() factory's creation of ListAction objects.""" a1 = SCons.Action.Action(["x", "y", "z", ["a", "b", "c"]]) @@ -366,7 +366,7 @@ class ActionTestCase(unittest.TestCase): assert isinstance(a2.list[2], SCons.Action.CommandAction), a2.list[2] assert a2.list[2].cmd_list == "z", a2.list[2].cmd_list - def foo(): + def foo() -> None: pass a3 = SCons.Action.Action(["x", foo, "z"]) @@ -399,21 +399,21 @@ class ActionTestCase(unittest.TestCase): assert a5.list[1].cmd_list == "y", a5.list[1].cmd_list assert a5.list[1].strfunction == foo, a5.list[1].strfunction - def test_CommandGeneratorAction(self): + def test_CommandGeneratorAction(self) -> None: """Test the Action factory's creation of CommandGeneratorAction objects.""" - def foo(): pass + def foo() -> None: pass - def gen_action(a, foo=foo): + def gen_action(a, foo=foo) -> None: assert isinstance(a, SCons.Action.CommandGeneratorAction), a assert a.generator is foo, a.generator test_positional_args(gen_action, foo, generator=1) - def test_LazyCmdGeneratorAction(self): + def test_LazyCmdGeneratorAction(self) -> None: """Test the Action factory's creation of lazy CommandGeneratorAction objects.""" - def lazy_action(a): + def lazy_action(a) -> None: assert isinstance(a, SCons.Action.LazyAction), a assert a.var == "FOO", a.var assert a.cmd_list == "${FOO}", a.cmd_list @@ -421,7 +421,7 @@ class ActionTestCase(unittest.TestCase): test_positional_args(lazy_action, "$FOO") test_positional_args(lazy_action, "${FOO}") - def test_no_action(self): + def test_no_action(self) -> None: """Test when the Action() factory can't create an action object.""" try: @@ -431,7 +431,7 @@ class ActionTestCase(unittest.TestCase): else: assert 0, "Should have thrown a TypeError creating Action from an int." - def test_reentrance(self): + def test_reentrance(self) -> None: """Test the Action factory when the action is already an Action object.""" a1 = SCons.Action.Action("foo") @@ -441,16 +441,16 @@ class ActionTestCase(unittest.TestCase): class _ActionActionTestCase(unittest.TestCase): - def test__init__(self): + def test__init__(self) -> None: """Test creation of _ActionAction objects.""" - def func1(): + def func1() -> None: pass - def func2(): + def func2() -> None: pass - def func3(): + def func3() -> None: pass a = SCons.Action._ActionAction() @@ -517,7 +517,7 @@ class _ActionActionTestCase(unittest.TestCase): def test_dup_keywords(self): """Test handling of both cmdstr and strfunction arguments.""" - def func(): + def func() -> None: pass try: @@ -529,7 +529,7 @@ class _ActionActionTestCase(unittest.TestCase): else: raise Exception("did not catch expected UserError") - def test___cmp__(self): + def test___cmp__(self) -> None: """Test Action comparison.""" a1 = SCons.Action.Action("x") @@ -539,13 +539,13 @@ class _ActionActionTestCase(unittest.TestCase): assert a1 != a3 assert a2 != a3 - def test_print_cmd_lines(self): + def test_print_cmd_lines(self) -> None: """Test the print_cmd_lines() method.""" save_stdout = sys.stdout try: - def execfunc(target, source, env): + def execfunc(target, source, env) -> None: pass a = SCons.Action.Action(execfunc) @@ -559,7 +559,7 @@ class _ActionActionTestCase(unittest.TestCase): finally: sys.stdout = save_stdout - def test___call__(self): + def test___call__(self) -> None: """Test calling an Action.""" save_stdout = sys.stdout @@ -576,19 +576,19 @@ class _ActionActionTestCase(unittest.TestCase): try: env = Environment() - def execfunc(target, source, env): + def execfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 7 a = SCons.Action.Action(execfunc) - def firstfunc(target, source, env): + def firstfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 0 - def lastfunc(target, source, env): + def lastfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 9 @@ -733,7 +733,7 @@ class _ActionActionTestCase(unittest.TestCase): result = [] - def my_print_cmd_line(s, target, source, env, result=result): + def my_print_cmd_line(s, target, source, env, result=result) -> None: result.append(s) env['PRINT_CMD_LINE_FUNC'] = my_print_cmd_line @@ -747,7 +747,7 @@ class _ActionActionTestCase(unittest.TestCase): SCons.Action.print_actions_presub = save_print_actions_presub SCons.Action.execute_actions = save_execute_actions - def test_presub_lines(self): + def test_presub_lines(self) -> None: """Test the presub_lines() method.""" env = Environment() @@ -759,7 +759,7 @@ class _ActionActionTestCase(unittest.TestCase): s = a.presub_lines(env) assert s == ['y', 'z'], s - def func(): + def func() -> None: pass a = SCons.Action.Action(func) @@ -781,7 +781,7 @@ class _ActionActionTestCase(unittest.TestCase): s = a.presub_lines(Environment(ACT='expanded action')) assert s == ['expanded action'], s - def test_add(self): + def test_add(self) -> None: """Test adding Actions to stuff.""" # Adding actions to other Actions or to stuff that can @@ -869,7 +869,7 @@ class _ActionActionTestCase(unittest.TestCase): class CommandActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a command Action.""" a = SCons.Action.CommandAction(["xyzzy"]) @@ -880,7 +880,7 @@ class CommandActionTestCase(unittest.TestCase): assert a.cmd_list == ["abra"], a.cmd_list assert a.cmdstr == "cadabra", a.cmdstr - def test___str__(self): + def test___str__(self) -> None: """Test fetching the pre-substitution string for command Actions.""" env = Environment() @@ -894,7 +894,7 @@ class CommandActionTestCase(unittest.TestCase): s = str(act) assert s == "xyzzy $TARGET $SOURCE $TARGETS $SOURCES", s - def test_genstring(self): + def test_genstring(self) -> None: """Test the genstring() method for command Actions.""" env = Environment() @@ -931,7 +931,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.genstring([t1, t2], [s1, s2], env) assert s == expect, s - def test_strfunction(self): + def test_strfunction(self) -> None: """Test fetching the string representation of command Actions.""" env = Environment() @@ -993,7 +993,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.strfunction([t1, t2], [s1, s2], env) assert s == 'cmdstr\tt1 t2\ns1 s2 ', s - def sf(target, source, env): + def sf(target, source, env) -> str: return "sf was called" act = SCons.Action.CommandAction('foo', strfunction=sf) @@ -1001,35 +1001,35 @@ class CommandActionTestCase(unittest.TestCase): assert s == "sf was called", s class actclass1: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 1 class actclass2: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: self.strfunction = 5 - def __call__(self): + def __call__(self) -> int: return 2 class actclass3: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 3 - def strfunction(self, targets, sources, env): + def strfunction(self, targets, sources, env) -> str: return 'actclass3 on %s to get %s' % (str(sources[0]), str(targets[0])) class actclass4: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 4 strfunction = None @@ -1082,7 +1082,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.strfunction([], [], env) assert s == "foo bar", s - def test_execute(self): + def test_execute(self) -> None: """Test execution of command Actions.""" try: @@ -1156,10 +1156,10 @@ class CommandActionTestCase(unittest.TestCase): assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy5'\n", c class Obj: - def __init__(self, str): + def __init__(self, str) -> None: self._str = str - def __str__(self): + def __str__(self) -> str: return self._str def rfile(self): @@ -1238,16 +1238,16 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env) assert r == 0, r - def test_set_handler(self): + def test_set_handler(self) -> None: """Test setting the command handler...""" class Test: - def __init__(self): + def __init__(self) -> None: self.executed = 0 t = Test() - def func(sh, escape, cmd, args, env, test=t): + def func(sh, escape, cmd, args, env, test=t) -> int: test.executed = args test.shell = sh return 0 @@ -1256,16 +1256,16 @@ class CommandActionTestCase(unittest.TestCase): return '**' + cmd + '**' class LiteralStr: - def __init__(self, x): + def __init__(self, x) -> None: self.data = x - def __str__(self): + def __str__(self) -> str: return self.data def escape(self, escape_func): return escape_func(self.data) - def is_literal(self): + def is_literal(self) -> int: return 1 a = SCons.Action.CommandAction(["xyzzy"]) @@ -1289,10 +1289,10 @@ class CommandActionTestCase(unittest.TestCase): a([], [], e) assert t.executed == ['**xyzzy**'], t.executed - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a command Action.""" - def CmdGen(target, source, env, for_signature): + def CmdGen(target, source, env, for_signature) -> str: assert for_signature return "%s %s" % \ (env["foo"], env["bar"]) @@ -1308,7 +1308,7 @@ class CommandActionTestCase(unittest.TestCase): # Make sure that CommandActions use an Environment's # subst_target_source() method for substitution. class SpecialEnvironment(Environment): - def subst_target_source(self, strSubst, raw=0, target=[], source=[]): + def subst_target_source(self, strSubst, raw: int=0, target=[], source=[]): return 'subst_target_source: ' + strSubst c = a.get_contents(target=DummyNode('ttt'), source=DummyNode('sss'), @@ -1361,7 +1361,7 @@ class CommandActionTestCase(unittest.TestCase): c = a.get_contents(target=t, source=s, env=env) assert c == b"s4 s5", c - def test_get_implicit_deps(self): + def test_get_implicit_deps(self) -> None: """Test getting the implicit dependencies of a command Action.""" class SpecialEnvironment(Environment): @@ -1407,19 +1407,19 @@ class CommandGeneratorActionTestCase(unittest.TestCase): return SCons.Action.CommandGeneratorAction(act, kw) - def test___init__(self): + def test___init__(self) -> None: """Test creation of a command generator Action.""" - def f(target, source, env): + def f(target, source, env) -> None: pass a = self.factory(f) assert a.generator == f - def test___str__(self): + def test___str__(self) -> None: """Test the pre-substitution strings for command generator Actions.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: # See if "env" is really a construction environment (or # looks like one) by accessing the FindIxes attribute. # (The Tool/mingw.py module has a generator that uses this, @@ -1433,10 +1433,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase): s = str(a) assert s == 'FOO', s - def test_genstring(self): + def test_genstring(self) -> None: """Test the command generator Action genstring() method.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: dummy = env['dummy'] self.dummy = dummy return "$FOO $TARGET $SOURCE $TARGETS $SOURCES" @@ -1447,17 +1447,17 @@ class CommandGeneratorActionTestCase(unittest.TestCase): assert self.dummy == 1, self.dummy assert s == "$FOO $TARGET $SOURCE $TARGETS $SOURCES", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a command generator Action.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: dummy = env['dummy'] self.dummy = dummy s = env.subst("$FOO") assert s == 'foo baz\nbar ack', s return "$FOO" - def func_action(target, source, env, self=self): + def func_action(target, source, env, self=self) -> None: dummy = env['dummy'] s = env.subst('$foo') assert s == 'bar', s @@ -1466,7 +1466,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def f2(target, source, env, for_signature, f=func_action): return f - def ch(sh, escape, cmd, args, env, self=self): + def ch(sh, escape, cmd, args, env, self=self) -> None: self.cmd.append(cmd) self.args.append(args) @@ -1489,7 +1489,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): del self.dummy class DummyFile: - def __init__(self, t): + def __init__(self, t) -> None: self.t = t def rfile(self): @@ -1499,14 +1499,14 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def get_subst_proxy(self): return self - def f3(target, source, env, for_signature): + def f3(target, source, env, for_signature) -> str: return '' c = self.factory(f3) c(target=[], source=DummyFile(self), env=Environment()) assert self.rfile_called - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a command generator Action.""" def f(target, source, env, for_signature): @@ -1516,7 +1516,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): return [["guux", foo, "$(", "$ignore", "$)", bar, '${test("$( foo $bar $)")}']] - def test(mystr): + def test(mystr) -> str: assert mystr == "$( foo $bar $)", mystr return "test" @@ -1526,10 +1526,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == b"guux FFF BBB test", c - def test_get_contents_of_function_action(self): + def test_get_contents_of_function_action(self) -> None: """Test contents of a CommandGeneratorAction-generated FunctionAction.""" - def LocalFunc(): + def LocalFunc() -> None: pass # Since the python bytecode has per version differences, we need different expected results per version @@ -1586,19 +1586,19 @@ class CommandGeneratorActionTestCase(unittest.TestCase): class FunctionActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a function Action.""" - def func1(): + def func1() -> None: pass - def func2(): + def func2() -> None: pass - def func3(): + def func3() -> None: pass - def func4(): + def func4() -> None: pass a = SCons.Action.FunctionAction(func1, {}) @@ -1609,10 +1609,10 @@ class FunctionActionTestCase(unittest.TestCase): assert a.execfunction == func2, a.execfunction assert a.strfunction == func3, a.strfunction - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method for function Actions.""" - def func1(): + def func1() -> None: pass a = SCons.Action.FunctionAction(func1, {}) @@ -1620,19 +1620,19 @@ class FunctionActionTestCase(unittest.TestCase): assert s == "func1(target, source, env)", s class class1: - def __call__(self): + def __call__(self) -> None: pass a = SCons.Action.FunctionAction(class1(), {}) s = str(a) assert s == "class1(target, source, env)", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a function Action.""" self.inc = 0 - def f(target, source, env): + def f(target, source, env) -> int: s = env['s'] s.inc = s.inc + 1 s.target = target @@ -1650,7 +1650,7 @@ class FunctionActionTestCase(unittest.TestCase): global count count = 0 - def function1(target, source, env): + def function1(target, source, env) -> int: global count count = count + 1 for t in target: @@ -1669,7 +1669,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == "function1\n", c class class1a: - def __init__(self, target, source, env): + def __init__(self, target, source, env) -> None: with open(env['out'], 'w') as f: f.write("class1a\n") @@ -1680,7 +1680,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == "class1a\n", c class class1b: - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> int: with open(env['out'], 'w') as f: f.write("class1b\n") return 2 @@ -1691,7 +1691,7 @@ class FunctionActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "class1b\n", c - def build_it(target, source, env, executor=None, self=self): + def build_it(target, source, env, executor=None, self=self) -> int: self.build_it = 1 return 0 @@ -1706,10 +1706,10 @@ class FunctionActionTestCase(unittest.TestCase): assert self.build_it assert self.string_it - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a function Action.""" - def LocalFunc(): + def LocalFunc() -> None: pass func_matches = { @@ -1775,7 +1775,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c in matches_foo, repr(c) class Foo: - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> bytes: return b'xyzzy' a = factory(Foo()) @@ -1783,7 +1783,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == b'xyzzy', repr(c) class LocalClass: - def LocalMethod(self): + def LocalMethod(self) -> None: pass lc = LocalClass() @@ -1793,10 +1793,10 @@ class FunctionActionTestCase(unittest.TestCase): c == meth_matches[sys.version_info[:2]] ), f"Got\n{c!r}\nExpected one of \n" + repr(meth_matches[sys.version_info[:2]]) - def test_strfunction(self): + def test_strfunction(self) -> None: """Test the FunctionAction.strfunction() method.""" - def func(): + def func() -> None: pass def factory(act, **kw): @@ -1817,10 +1817,10 @@ class FunctionActionTestCase(unittest.TestCase): class ListActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a list of subsidiary Actions.""" - def func(): + def func() -> None: pass a = SCons.Action.ListAction(["x", func, ["y", "z"]]) @@ -1829,26 +1829,26 @@ class ListActionTestCase(unittest.TestCase): assert isinstance(a.list[2], SCons.Action.ListAction) assert a.list[2].list[0].cmd_list == 'y' - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method for a list of subsidiary Actions.""" - def f(target, source, env): + def f(target, source, env) -> None: pass - def g(target, source, env): + def g(target, source, env) -> None: pass a = SCons.Action.ListAction([f, g, "XXX", f]) s = str(a) assert s == "f(target, source, env)\ng(target, source, env)\nXXX\nf(target, source, env)", s - def test_genstring(self): + def test_genstring(self) -> None: """Test the genstring() method for a list of subsidiary Actions.""" - def f(target, source, env): + def f(target, source, env) -> None: pass - def g(target, source, env, for_signature): + def g(target, source, env, for_signature) -> str: return 'generated %s %s' % (target[0], source[0]) g = SCons.Action.Action(g, generator=1) @@ -1856,11 +1856,11 @@ class ListActionTestCase(unittest.TestCase): s = a.genstring(['foo.x'], ['bar.y'], Environment()) assert s == "f(target, source, env)\ngenerated foo.x bar.y\nXXX\nf(target, source, env)", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a list of subsidiary Actions.""" self.inc = 0 - def f(target, source, env): + def f(target, source, env) -> None: s = env['s'] s.inc = s.inc + 1 @@ -1870,19 +1870,19 @@ class ListActionTestCase(unittest.TestCase): cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile) - def function2(target, source, env): + def function2(target, source, env) -> int: with open(env['out'], 'a') as f: f.write("function2\n") return 0 class class2a: - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> int: with open(env['out'], 'a') as f: f.write("class2a\n") return 0 class class2b: - def __init__(self, target, source, env): + def __init__(self, target, source, env) -> None: with open(env['out'], 'a') as f: f.write("class2b\n") @@ -1892,12 +1892,12 @@ class ListActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a list of subsidiary Actions.""" self.foo = 0 - def gen(target, source, env, for_signature): + def gen(target, source, env, for_signature) -> str: s = env['s'] s.foo = 1 return "y" @@ -1911,7 +1911,7 @@ class ListActionTestCase(unittest.TestCase): class LazyActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a lazy-evaluation Action.""" # Environment variable references should create a special type @@ -1925,10 +1925,10 @@ class LazyActionTestCase(unittest.TestCase): assert isinstance(a10, SCons.Action.LazyAction), a10 assert a10.var == 'FOO', a10.var - def test_genstring(self): + def test_genstring(self) -> None: """Test the lazy-evaluation Action genstring() method.""" - def f(target, source, env): + def f(target, source, env) -> None: pass a = SCons.Action.Action('$BAR') @@ -1939,10 +1939,10 @@ class LazyActionTestCase(unittest.TestCase): s = a.genstring([], [], env=env2) assert s == 'xxx', s - def test_execute(self): + def test_execute(self) -> None: """Test executing a lazy-evaluation Action.""" - def f(target, source, env): + def f(target, source, env) -> int: s = env['s'] s.test = 1 return 0 @@ -1955,7 +1955,7 @@ class LazyActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'lazy'\n", c - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a lazy-evaluation Action.""" a = SCons.Action.Action("${FOO}") @@ -1963,10 +1963,10 @@ class LazyActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == b"This is a test", c - def test_get_contents_of_function_action(self): + def test_get_contents_of_function_action(self) -> None: """Test fetching the contents of a lazy-evaluation FunctionAction.""" - def LocalFunc(): + def LocalFunc() -> None: pass func_matches = { @@ -2018,7 +2018,7 @@ class LazyActionTestCase(unittest.TestCase): class ActionCallerTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of an ActionCaller""" ac = SCons.Action.ActionCaller(1, [2, 3], {'FOO': 4, 'BAR': 5}) @@ -2026,13 +2026,13 @@ class ActionCallerTestCase(unittest.TestCase): assert ac.args == [2, 3], ac.args assert ac.kw == {'FOO': 4, 'BAR': 5}, ac.kw - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of an ActionCaller""" - def strfunc(): + def strfunc() -> None: pass - def LocalFunc(): + def LocalFunc() -> None: pass matches = { @@ -2063,7 +2063,7 @@ class ActionCallerTestCase(unittest.TestCase): ) class LocalActFunc: - def __call__(self): + def __call__(self) -> None: pass af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc) @@ -2093,15 +2093,15 @@ class ActionCallerTestCase(unittest.TestCase): assert c in ("", "", ""), repr(c) # ^^ class str for python3 - def test___call__(self): + def test___call__(self) -> None: """Test calling an ActionCaller""" actfunc_args = [] - def actfunc(a1, a2, a3, args=actfunc_args): + def actfunc(a1, a2, a3, args=actfunc_args) -> None: args.extend([a1, a2, a3]) - def strfunc(a1, a2, a3): + def strfunc(a1, a2, a3) -> None: pass e = Environment(FOO=2, BAR=5) @@ -2121,15 +2121,15 @@ class ActionCallerTestCase(unittest.TestCase): assert actfunc_args[2] is e, actfunc_args del actfunc_args[:] - def test_strfunction(self): + def test_strfunction(self) -> None: """Test calling the ActionCaller strfunction() method""" strfunc_args = [] - def actfunc(a1, a2, a3, a4): + def actfunc(a1, a2, a3, a4) -> None: pass - def strfunc(a1, a2, a3, a4, args=strfunc_args): + def strfunc(a1, a2, a3, a4, args=strfunc_args) -> None: args.extend([a1, a2, a3, a4]) af = SCons.Action.ActionFactory(actfunc, strfunc) @@ -2145,29 +2145,29 @@ class ActionCallerTestCase(unittest.TestCase): class ActionFactoryTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of an ActionFactory""" - def actfunc(): + def actfunc() -> None: pass - def strfunc(): + def strfunc() -> None: pass ac = SCons.Action.ActionFactory(actfunc, strfunc) assert ac.actfunc is actfunc, ac.actfunc assert ac.strfunc is strfunc, ac.strfunc - def test___call__(self): + def test___call__(self) -> None: """Test calling whatever's returned from an ActionFactory""" actfunc_args = [] strfunc_args = [] - def actfunc(a1, a2, a3, args=actfunc_args): + def actfunc(a1, a2, a3, args=actfunc_args) -> None: args.extend([a1, a2, a3]) - def strfunc(a1, a2, a3, args=strfunc_args): + def strfunc(a1, a2, a3, args=strfunc_args) -> None: args.extend([a1, a2, a3]) af = SCons.Action.ActionFactory(actfunc, strfunc) @@ -2177,7 +2177,7 @@ class ActionFactoryTestCase(unittest.TestCase): class ActionCompareTestCase(unittest.TestCase): - def test_1_solo_name(self): + def test_1_solo_name(self) -> None: """Test Lazy Cmd Generator Action get_name alone. Basically ensures we can locate the builder, comparing it to @@ -2188,7 +2188,7 @@ class ActionCompareTestCase(unittest.TestCase): name = bar.get_name(env) assert name == 'BAR', name - def test_2_multi_name(self): + def test_2_multi_name(self) -> None: """Test LazyCmdGenerator Action get_name multi builders. Ensure that we can compare builders (and thereby actions) to @@ -2204,7 +2204,7 @@ class ActionCompareTestCase(unittest.TestCase): name = bar.get_name(env) assert name == 'BAR', name - def test_3_dict_names(self): + def test_3_dict_names(self) -> None: """Test Action/Suffix dicts with get_name. Verifies that Action/Suffix dictionaries work correctly, @@ -2226,16 +2226,16 @@ class ActionCompareTestCase(unittest.TestCase): class TestClass: """A test class used by ObjectContentsTestCase.test_object_contents""" - def __init__(self): + def __init__(self) -> None: self.a = "a" self.b = "b" - def method(self, arg): + def method(self, arg) -> None: pass class ObjectContentsTestCase(unittest.TestCase): - def test_function_contents(self): + def test_function_contents(self) -> None: """Test that Action._function_contents works""" def func1(a, b, c): @@ -2263,7 +2263,7 @@ class ObjectContentsTestCase(unittest.TestCase): expected[sys.version_info[:2]] ) - def test_object_contents(self): + def test_object_contents(self) -> None: """Test that Action._object_contents works""" # See definition above @@ -2305,7 +2305,7 @@ class ObjectContentsTestCase(unittest.TestCase): expected[sys.version_info[:2]] ) - def test_code_contents(self): + def test_code_contents(self) -> None: """Test that Action._code_contents works""" code = compile("print('Hello, World!')", '', 'exec') diff --git a/SCons/Builder.py b/SCons/Builder.py index ab51c32..bdedc3a 100644 --- a/SCons/Builder.py +++ b/SCons/Builder.py @@ -130,14 +130,14 @@ class DictCmdGenerator(SCons.Util.Selector): to return the proper action based on the file suffix of the source file.""" - def __init__(self, mapping=None, source_ext_match=True): + def __init__(self, mapping=None, source_ext_match: bool=True) -> None: super().__init__(mapping) self.source_ext_match = source_ext_match def src_suffixes(self): return list(self.keys()) - def add_action(self, suffix, action): + def add_action(self, suffix, action) -> None: """Add a suffix-action pair to the mapping. """ self[suffix] = action @@ -222,12 +222,12 @@ class OverrideWarner(UserDict): can actually invoke multiple builders. This class only emits the warnings once, no matter how many Builders are invoked. """ - def __init__(self, mapping): + def __init__(self, mapping) -> None: super().__init__(mapping) if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.OverrideWarner') self.already_warned = None - def warn(self): + def warn(self) -> None: if self.already_warned: return for k in self.keys(): @@ -335,7 +335,7 @@ class EmitterProxy: look there at actual build time to see if it holds a callable. If so, we will call that as the actual emitter.""" - def __init__(self, var): + def __init__(self, var) -> None: self.var = SCons.Util.to_String(var) def __call__(self, target, source, env): @@ -375,23 +375,23 @@ class BuilderBase: """ def __init__(self, action = None, - prefix = '', - suffix = '', - src_suffix = '', + prefix: str = '', + suffix: str = '', + src_suffix: str = '', target_factory = None, source_factory = None, target_scanner = None, source_scanner = None, emitter = None, - multi = 0, + multi: int = 0, env = None, - single_source = 0, + single_source: int = 0, name = None, chdir = _null, - is_explicit = 1, + is_explicit: int = 1, src_builder = None, - ensure_suffix = False, - **overrides): + ensure_suffix: bool = False, + **overrides) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.BuilderBase') self._memo = {} self.action = action @@ -439,7 +439,7 @@ class BuilderBase: src_builder = [ src_builder ] self.src_builder = src_builder - def __bool__(self): + def __bool__(self) -> bool: raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead") def get_name(self, env): @@ -471,7 +471,7 @@ class BuilderBase: suffixes = [] return match_splitext(path, suffixes) - def _adjustixes(self, files, pre, suf, ensure_suffix=False): + def _adjustixes(self, files, pre, suf, ensure_suffix: bool=False): if not files: return [] result = [] @@ -673,7 +673,7 @@ class BuilderBase: prefix = prefix(env, sources) return env.subst(prefix) - def set_suffix(self, suffix): + def set_suffix(self, suffix) -> None: if not callable(suffix): suffix = self.adjust_suffix(suffix) self.suffix = suffix @@ -684,7 +684,7 @@ class BuilderBase: suffix = suffix(env, sources) return env.subst(suffix) - def set_src_suffix(self, src_suffix): + def set_src_suffix(self, src_suffix) -> None: if not src_suffix: src_suffix = [] elif not SCons.Util.is_List(src_suffix): @@ -698,7 +698,7 @@ class BuilderBase: return '' return ret[0] - def add_emitter(self, suffix, emitter): + def add_emitter(self, suffix, emitter) -> None: """Add a suffix-emitter mapping to this Builder. This assumes that emitter has been initialized with an @@ -708,7 +708,7 @@ class BuilderBase: """ self.emitter[suffix] = emitter - def add_src_builder(self, builder): + def add_src_builder(self, builder) -> None: """ Add a new Builder to the list of src_builders. @@ -875,7 +875,7 @@ class CompositeBuilder(SCons.Util.Proxy): to the DictCmdGenerator's add_action() method. """ - def __init__(self, builder, cmdgen): + def __init__(self, builder, cmdgen) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.CompositeBuilder') super().__init__(builder) @@ -885,7 +885,7 @@ class CompositeBuilder(SCons.Util.Proxy): __call__ = SCons.Util.Delegate('__call__') - def add_action(self, suffix, action): + def add_action(self, suffix, action) -> None: self.cmdgen.add_action(suffix, action) self.set_src_suffix(self.cmdgen.src_suffixes()) diff --git a/SCons/BuilderTests.py b/SCons/BuilderTests.py index 636534f..3ba5285 100644 --- a/SCons/BuilderTests.py +++ b/SCons/BuilderTests.py @@ -27,7 +27,7 @@ import SCons.compat # Where this is defined in the file seems to affect its # byte-code contents, so try to minimize changes by # defining it here, before we even import anything. -def Func(): +def Func() -> None: pass from collections import UserList @@ -70,7 +70,7 @@ scons_env = SCons.Environment.Environment() env_arg2nodes_called = None class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.d = {} self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] @@ -87,11 +87,11 @@ class Environment: def substitute(m, d=self.d): return d.get(m.group(1), '') return re.sub(r'\$(\w+)', substitute, s) - def subst_target_source(self, string, raw=0, target=None, + def subst_target_source(self, string, raw: int=0, target=None, source=None, dict=None, conv=None): return SCons.Subst.scons_subst(string, self, raw, target, source, dict, conv) - def subst_list(self, string, raw=0, target=None, source=None, conv=None): + def subst_list(self, string, raw: int=0, target=None, source=None, conv=None): return SCons.Subst.scons_subst_list(string, self, raw, target, source, {}, {}, conv) def arg2nodes(self, args, factory, **kw): @@ -111,13 +111,13 @@ class Environment: return self.scanner def Dictionary(self): return {} - def autogenerate(self, dir=''): + def autogenerate(self, dir: str=''): return {} - def __setitem__(self, item, var): + def __setitem__(self, item, var) -> None: self.d[item] = var def __getitem__(self, item): return self.d[item] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.d def keys(self): return list(self.d.keys()) @@ -128,7 +128,7 @@ class Environment: env.d.update(overrides) env.scanner = self.scanner return env - def _update(self, dict): + def _update(self, dict) -> None: self.d.update(dict) def items(self): return list(self.d.items()) @@ -144,15 +144,15 @@ class Environment: return self.scanner == other.scanner or self.d == other.d class MyAction: - def __init__(self, action): + def __init__(self, action) -> None: self.action = action - def __call__(self, *args, **kw): + def __call__(self, *args, **kw) -> None: pass def get_executor(self, env, overrides, tlist, slist, executor_kw): return ['executor'] + [self.action] class MyNode_without_target_from_source: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.sources = [] self.builder = None @@ -162,19 +162,19 @@ class MyNode_without_target_from_source: return os.path.splitext(self.name)[1] def disambiguate(self): return self - def __str__(self): + def __str__(self) -> str: return self.name - def builder_set(self, builder): + def builder_set(self, builder) -> None: self.builder = builder - def has_builder(self): + def has_builder(self) -> bool: return self.builder is not None - def set_explicit(self, is_explicit): + def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit def has_explicit_builder(self): return self.is_explicit - def env_set(self, env, safe=0): + def env_set(self, env, safe: int=0) -> None: self.env = env - def add_source(self, source): + def add_source(self, source) -> None: self.sources.extend(source) def scanner_key(self): return self.name @@ -184,9 +184,9 @@ class MyNode_without_target_from_source: return env def get_build_env(self): return self.executor.get_build_env() - def set_executor(self, executor): + def set_executor(self, executor) -> None: self.executor = executor - def get_executor(self, create=1): + def get_executor(self, create: int=1): return self.executor class MyNode(MyNode_without_target_from_source): @@ -195,7 +195,7 @@ class MyNode(MyNode_without_target_from_source): class BuilderTestCase(unittest.TestCase): - def test__init__(self): + def test__init__(self) -> None: """Test simple Builder creation """ builder = SCons.Builder.Builder(action="foo") @@ -204,7 +204,7 @@ class BuilderTestCase(unittest.TestCase): x = builder.overrides['OVERRIDE'] assert x == 'x', x - def test__bool__(self): + def test__bool__(self) -> None: """Test a builder raising an exception when __bool__ is called. """ # basic test: explicitly call it @@ -339,7 +339,7 @@ class BuilderTestCase(unittest.TestCase): p = target.sources[0].get_internal_path() assert p == os.path.join('src_dir', 'n22'), p - def test_mistaken_variables(self): + def test_mistaken_variables(self) -> None: """Test keyword arguments that are often mistakes """ import SCons.Warnings @@ -348,7 +348,7 @@ class BuilderTestCase(unittest.TestCase): save_warn = SCons.Warnings.warn warned = [] - def my_warn(exception, warning, warned=warned): + def my_warn(exception, warning, warned=warned) -> None: warned.append(warning) SCons.Warnings.warn = my_warn @@ -368,7 +368,7 @@ class BuilderTestCase(unittest.TestCase): finally: SCons.Warnings.warn = save_warn - def test_action(self): + def test_action(self) -> None: """Test Builder creation Verify that we can retrieve the supplied action attribute. @@ -376,7 +376,7 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(action="foo") assert builder.action.cmd_list == "foo" - def func(): + def func() -> None: pass builder = SCons.Builder.Builder(action=func) assert isinstance(builder.action, SCons.Action.FunctionAction) @@ -385,16 +385,16 @@ class BuilderTestCase(unittest.TestCase): # point in the future. assert builder.action.execfunction == func - def test_generator(self): + def test_generator(self) -> None: """Test Builder creation given a generator function.""" - def generator(): + def generator() -> None: pass builder = SCons.Builder.Builder(generator=generator) assert builder.action.generator == generator - def test_cmp(self): + def test_cmp(self) -> None: """Test simple comparisons of Builder objects """ b1 = SCons.Builder.Builder(src_suffix = '.o') @@ -404,7 +404,7 @@ class BuilderTestCase(unittest.TestCase): assert b1 != b3 assert b2 != b3 - def test_target_factory(self): + def test_target_factory(self) -> None: """Test a Builder that creates target nodes of a specified class """ class Foo: @@ -416,7 +416,7 @@ class BuilderTestCase(unittest.TestCase): assert builder.target_factory is FooFactory assert builder.source_factory is not FooFactory - def test_source_factory(self): + def test_source_factory(self) -> None: """Test a Builder that creates source nodes of a specified class """ class Foo: @@ -428,7 +428,7 @@ class BuilderTestCase(unittest.TestCase): assert builder.target_factory is not FooFactory assert builder.source_factory is FooFactory - def test_splitext(self): + def test_splitext(self) -> None: """Test the splitext() method attached to a Builder.""" b = SCons.Builder.Builder() assert b.splitext('foo') == ('foo','') @@ -436,14 +436,14 @@ class BuilderTestCase(unittest.TestCase): assert b.splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'') class MyBuilder(SCons.Builder.BuilderBase): - def splitext(self, path): + def splitext(self, path) -> str: return "called splitext()" b = MyBuilder() ret = b.splitext('xyz.c') assert ret == "called splitext()", ret - def test_adjust_suffix(self): + def test_adjust_suffix(self) -> None: """Test how a Builder adjusts file suffixes """ b = SCons.Builder.Builder() @@ -452,14 +452,14 @@ class BuilderTestCase(unittest.TestCase): assert b.adjust_suffix('$foo') == '$foo' class MyBuilder(SCons.Builder.BuilderBase): - def adjust_suffix(self, suff): + def adjust_suffix(self, suff) -> str: return "called adjust_suffix()" b = MyBuilder() ret = b.adjust_suffix('.foo') assert ret == "called adjust_suffix()", ret - def test_prefix(self): + def test_prefix(self) -> None: """Test Builder creation with a specified target prefix Make sure that there is no '.' separator appended. @@ -515,7 +515,7 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.get_internal_path() == 'emit-f6', tgt.get_internal_path() - def test_set_suffix(self): + def test_set_suffix(self) -> None: """Test the set_suffix() method""" b = SCons.Builder.Builder(action='') env = Environment(XSUFFIX = '.x') @@ -531,7 +531,7 @@ class BuilderTestCase(unittest.TestCase): s = b.get_suffix(env) assert s == '.x', s - def test_src_suffix(self): + def test_src_suffix(self) -> None: """Test Builder creation with a specified source file suffix Make sure that the '.' separator is appended to the @@ -565,7 +565,7 @@ class BuilderTestCase(unittest.TestCase): b5 = SCons.Builder.Builder(action = { '.y' : ''}) assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env) - def test_srcsuffix_nonext(self): + def test_srcsuffix_nonext(self) -> None: """Test target generation from non-extension source suffixes""" env = Environment() b6 = SCons.Builder.Builder(action = '', @@ -592,7 +592,7 @@ class BuilderTestCase(unittest.TestCase): tgt = b9(env, target=None, source='foo_altsrc.b') assert str(tgt[0]) == 'foo.c', str(tgt[0]) - def test_src_suffix_expansion(self): + def test_src_suffix_expansion(self) -> None: """Test handling source suffixes when an expansion is involved""" env = Environment(OBJSUFFIX = '.obj') @@ -607,7 +607,7 @@ class BuilderTestCase(unittest.TestCase): s = list(map(str, tgt[0].sources)) assert s == ['foo.obj'], s - def test_suffix(self): + def test_suffix(self) -> None: """Test Builder creation with a specified target suffix Make sure that the '.' separator is appended to the @@ -658,9 +658,9 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.get_internal_path() == 'f6.emit', tgt.get_internal_path() - def test_single_source(self): + def test_single_source(self) -> None: """Test Builder with single_source flag set""" - def func(target, source, env): + def func(target, source, env) -> None: """create the file""" with open(str(target[0]), "w"): pass @@ -715,9 +715,9 @@ class BuilderTestCase(unittest.TestCase): assert 0 - def test_lists(self): + def test_lists(self) -> None: """Testing handling lists of targets and source""" - def function2(target, source, env, tlist = [outfile, outfile2], **kw): + def function2(target, source, env, tlist = [outfile, outfile2], **kw) -> int: for t in target: with open(str(t), 'w') as f: f.write("function2\n") @@ -748,7 +748,7 @@ class BuilderTestCase(unittest.TestCase): sub1_out = test.workpath('sub1', 'out') sub2_out = test.workpath('sub2', 'out') - def function3(target, source, env, tlist = [sub1_out, sub2_out]): + def function3(target, source, env, tlist = [sub1_out, sub2_out]) -> int: for t in target: with open(str(t), 'w') as f: f.write("function3\n") @@ -773,7 +773,7 @@ class BuilderTestCase(unittest.TestCase): assert os.path.exists(test.workpath('sub1')) assert os.path.exists(test.workpath('sub2')) - def test_src_builder(self): + def test_src_builder(self) -> None: """Testing Builders with src_builder""" # These used to be MultiStepBuilder objects until we # eliminated it as a separate class @@ -829,7 +829,7 @@ class BuilderTestCase(unittest.TestCase): s = list(map(str, tgt.sources[0].sources[0].sources)) assert s == ['test.i'], s - def test_target_scanner(self): + def test_target_scanner(self) -> None: """Testing ability to set target and source scanners through a builder.""" global instanced class TestScanner: @@ -855,12 +855,12 @@ class BuilderTestCase(unittest.TestCase): assert tgt.builder.target_scanner == tscan, tgt.builder.target_scanner assert tgt.builder.source_scanner == tscan, tgt.builder.source_scanner - def test_actual_scanner(self): + def test_actual_scanner(self) -> None: """Test usage of actual Scanner objects.""" import SCons.Scanner - def func(self): + def func(self) -> None: pass scanner = SCons.Scanner.ScannerBase(func, name='fooscan') @@ -872,17 +872,17 @@ class BuilderTestCase(unittest.TestCase): assert b1 == b2 assert b1 != b3 - def test_src_scanner(self): + def test_src_scanner(self) -> None: """Testing ability to set a source file scanner through a builder.""" class TestScanner: - def key(self, env): + def key(self, env) -> str: return 'TestScannerkey' def instance(self, env): return self def select(self, node): return self name = 'TestScanner' - def __str__(self): + def __str__(self) -> str: return self.name scanner = TestScanner() @@ -904,12 +904,12 @@ class BuilderTestCase(unittest.TestCase): # An Environment that has suffix-specified SCANNERS should # provide a source scanner to the target. class EnvTestScanner: - def key(self, env): + def key(self, env) -> str: return '.y' def instance(self, env): return self name = 'EnvTestScanner' - def __str__(self): + def __str__(self) -> str: return self.name def select(self, node): return self @@ -962,7 +962,7 @@ class BuilderTestCase(unittest.TestCase): - def test_Builder_API(self): + def test_Builder_API(self) -> None: """Test Builder interface. Some of this is tested elsewhere in this file, but this is a @@ -1135,9 +1135,9 @@ class BuilderTestCase(unittest.TestCase): assert r == ['.src_sfx1', '.src_sfx2'], r - def test_Builder_Args(self): + def test_Builder_Args(self) -> None: """Testing passing extra args to a builder.""" - def buildFunc(target, source, env, s=self): + def buildFunc(target, source, env, s=self) -> None: s.foo=env['foo'] s.bar=env['bar'] assert env['CC'] == 'mycc' @@ -1150,7 +1150,7 @@ class BuilderTestCase(unittest.TestCase): assert self.foo == 1, self.foo assert self.bar == 2, self.bar - def test_emitter(self): + def test_emitter(self) -> None: """Test emitter functions.""" def emit(target, source, env): foo = env.get('foo', 0) @@ -1214,7 +1214,7 @@ class BuilderTestCase(unittest.TestCase): assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources)) assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources)) - def test_emitter_preserve_builder(self): + def test_emitter_preserve_builder(self) -> None: """Test an emitter not overwriting a newly-set builder""" env = Environment() @@ -1236,7 +1236,7 @@ class BuilderTestCase(unittest.TestCase): assert tgt.builder is builder, tgt.builder assert node.builder is new_builder, node.builder - def test_emitter_suffix_map(self): + def test_emitter_suffix_map(self) -> None: """Test mapping file suffixes to emitter functions""" env = Environment() @@ -1270,7 +1270,7 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(env, None, source='ccc.4c')[0] assert str(tgt) == 'emit4c-ccc', str(tgt) - def test_emitter_function_list(self): + def test_emitter_function_list(self) -> None: """Test lists of emitter functions""" env = Environment() @@ -1309,7 +1309,7 @@ class BuilderTestCase(unittest.TestCase): tgts = list(map(str, tgts)) assert tgts == ['target-2', 'emit2a-aaa', 'emit2b-aaa'], tgts - def test_emitter_TARGET_SOURCE(self): + def test_emitter_TARGET_SOURCE(self) -> None: """Test use of $TARGET and $SOURCE in emitter results""" env = SCons.Environment.Environment() @@ -1329,7 +1329,7 @@ class BuilderTestCase(unittest.TestCase): assert targets == ['TTT', 'SSS.s1', 'TTT.t1'], targets assert sources == ['SSS', 'TTT.t2', 'SSS.s2'], targets - def test_no_target(self): + def test_no_target(self) -> None: """Test deducing the target from the source.""" env = Environment() @@ -1385,7 +1385,7 @@ class BuilderTestCase(unittest.TestCase): assert str(tgt.sources[0]) == 'i0.w', list(map(str, tgt.sources)) assert str(tgt.sources[1]) == 'i1.y', list(map(str, tgt.sources)) - def test_get_name(self): + def test_get_name(self) -> None: """Test getting name of builder. Each type of builder should return its environment-specific @@ -1445,8 +1445,8 @@ class BuilderTestCase(unittest.TestCase): class CompositeBuilderTestCase(unittest.TestCase): - def setUp(self): - def func_action(target, source, env): + def setUp(self) -> None: + def func_action(target, source, env) -> int: return 0 builder = SCons.Builder.Builder(action={ '.foo' : func_action, @@ -1455,7 +1455,7 @@ class CompositeBuilderTestCase(unittest.TestCase): self.func_action = func_action self.builder = builder - def test___init__(self): + def test___init__(self) -> None: """Test CompositeBuilder creation""" env = Environment() builder = SCons.Builder.Builder(action={}) @@ -1466,7 +1466,7 @@ class CompositeBuilderTestCase(unittest.TestCase): assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) - def test_target_action(self): + def test_target_action(self) -> None: """Test CompositeBuilder setting of target builder actions""" env = Environment() builder = self.builder @@ -1479,7 +1479,7 @@ class CompositeBuilderTestCase(unittest.TestCase): assert isinstance(tgt.builder, SCons.Builder.BuilderBase) assert tgt.builder.action is builder.action - def test_multiple_suffix_error(self): + def test_multiple_suffix_error(self) -> None: """Test the CompositeBuilder multiple-source-suffix error""" env = Environment() builder = self.builder @@ -1494,7 +1494,7 @@ class CompositeBuilderTestCase(unittest.TestCase): expect = "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo" assert str(err) == expect, err - def test_source_ext_match(self): + def test_source_ext_match(self) -> None: """Test the CompositeBuilder source_ext_match argument""" env = Environment() func_action = self.func_action @@ -1505,7 +1505,7 @@ class CompositeBuilderTestCase(unittest.TestCase): tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0] tgt.build() - def test_suffix_variable(self): + def test_suffix_variable(self) -> None: """Test CompositeBuilder defining action suffixes through a variable""" env = Environment(BAR_SUFFIX = '.BAR2', FOO_SUFFIX = '.FOO2') func_action = self.func_action @@ -1532,7 +1532,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 1 assert flag, "UserError should be thrown when we call a builder with ambigous suffixes." - def test_src_builder(self): + def test_src_builder(self) -> None: """Test CompositeBuilder's use of a src_builder""" env = Environment() diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 70c4f38..12f1d54 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -43,7 +43,7 @@ cache_show = False cache_readonly = False cache_tmp_uuid = uuid.uuid4().hex -def CacheRetrieveFunc(target, source, env): +def CacheRetrieveFunc(target, source, env) -> int: t = target[0] fs = t.fs cd = env.get_CacheDir() @@ -133,7 +133,7 @@ CachePush = SCons.Action.Action(CachePushFunc, None) class CacheDir: - def __init__(self, path): + def __init__(self, path) -> None: """ Initialize a CacheDir object. @@ -192,12 +192,12 @@ class CacheDir: msg = "Failed to read cache configuration for " + path raise SCons.Errors.SConsEnvironmentError(msg) - def CacheDebug(self, fmt, target, cachefile): + def CacheDebug(self, fmt, target, cachefile) -> None: if cache_debug != self.current_cache_debug: if cache_debug == '-': self.debugFP = sys.stdout elif cache_debug: - def debug_cleanup(debugFP): + def debug_cleanup(debugFP) -> None: debugFP.close() self.debugFP = open(cache_debug, 'w') @@ -270,7 +270,7 @@ class CacheDir: cachedir = os.path.join(self.path, subdir) return cachedir, os.path.join(cachedir, sig) - def retrieve(self, node): + def retrieve(self, node) -> bool: """ This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in diff --git a/SCons/CacheDirTests.py b/SCons/CacheDirTests.py index c4a0ed7..cc7563d 100644 --- a/SCons/CacheDirTests.py +++ b/SCons/CacheDirTests.py @@ -35,7 +35,7 @@ import SCons.CacheDir built_it = None class Action: - def __call__(self, targets, sources, env, **kw): + def __call__(self, targets, sources, env, **kw) -> int: global built_it if kw.get('execute', 1): built_it = 1 @@ -46,7 +46,7 @@ class Action: return bytearray('','utf-8') class Builder: - def __init__(self, environment, action): + def __init__(self, environment, action) -> None: self.env = environment self.action = action self.overrides = {} @@ -54,7 +54,7 @@ class Builder: self.target_scanner = None class Environment: - def __init__(self, cachedir): + def __init__(self, cachedir) -> None: self.cachedir = cachedir def Override(self, overrides): return self @@ -65,7 +65,7 @@ class BaseTestCase(unittest.TestCase): """ Base fixtures common to our other unittest classes. """ - def setUp(self): + def setUp(self) -> None: self.test = TestCmd(workdir='') import SCons.Node.FS @@ -82,7 +82,7 @@ class BaseTestCase(unittest.TestCase): #node.binfo.ninfo.bsig = bsig return node - def tearDown(self): + def tearDown(self) -> None: os.remove(os.path.join(self._CacheDir.path, 'config')) os.rmdir(self._CacheDir.path) # Should that be shutil.rmtree? @@ -91,7 +91,7 @@ class CacheDirTestCase(BaseTestCase): """ Test calling CacheDir code directly. """ - def test_cachepath(self): + def test_cachepath(self) -> None: """Test the cachepath() method""" # Verify how the cachepath() method determines the name @@ -117,15 +117,15 @@ class ExceptionTestCase(unittest.TestCase): # Don't inherit from BaseTestCase, we're by definition trying to # break things so we really want a clean slate for each test. - def setUp(self): + def setUp(self) -> None: self.tmpdir = tempfile.mkdtemp() self._CacheDir = SCons.CacheDir.CacheDir(self.tmpdir) - def tearDown(self): + def tearDown(self) -> None: shutil.rmtree(self.tmpdir) @unittest.skipIf(sys.platform.startswith("win"), "This fixture will not trigger an OSError on Windows") - def test_throws_correct_on_OSError(self): + def test_throws_correct_on_OSError(self) -> None: """Test that the correct error is thrown when cache directory cannot be created.""" privileged_dir = os.path.join(self.tmpdir, "privileged") try: @@ -140,11 +140,11 @@ class ExceptionTestCase(unittest.TestCase): shutil.rmtree(privileged_dir) - def test_throws_correct_when_failed_to_write_configfile(self): + def test_throws_correct_when_failed_to_write_configfile(self) -> None: class Unserializable: """A class which the JSON should not be able to serialize""" - def __init__(self, oldconfig): + def __init__(self, oldconfig) -> None: self.something = 1 # Make the object unserializable # Pretend to be the old config just enough self.__dict__["prefix_len"] = oldconfig["prefix_len"] @@ -155,7 +155,7 @@ class ExceptionTestCase(unittest.TestCase): else: return None - def __setitem__(self, name, value): + def __setitem__(self, name, value) -> None: self.__dict__[name] = value oldconfig = self._CacheDir.config @@ -171,7 +171,7 @@ class ExceptionTestCase(unittest.TestCase): except SCons.Errors.SConsEnvironmentError as e: assert str(e) == "Failed to write cache configuration for {}".format(self._CacheDir.path) - def test_raise_environment_error_on_invalid_json(self): + def test_raise_environment_error_on_invalid_json(self) -> None: config_file = os.path.join(self._CacheDir.path, "config") with open(config_file, "r") as cfg: content = cfg.read() @@ -195,19 +195,19 @@ class FileTestCase(BaseTestCase): # when the CacheDir support was refactored into its own module. # Look in the history for Node/FSTests.py if any of this needs # to be re-examined. - def retrieve_succeed(self, target, source, env, execute=1): + def retrieve_succeed(self, target, source, env, execute: int=1) -> int: self.retrieved.append(target) return 0 - def retrieve_fail(self, target, source, env, execute=1): + def retrieve_fail(self, target, source, env, execute: int=1) -> int: self.retrieved.append(target) return 1 - def push(self, target, source, env): + def push(self, target, source, env) -> int: self.pushed.append(target) return 0 - def test_CacheRetrieve(self): + def test_CacheRetrieve(self) -> None: """Test the CacheRetrieve() function""" save_CacheRetrieve = SCons.CacheDir.CacheRetrieve @@ -235,7 +235,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CacheRetrieve = save_CacheRetrieve - def test_CacheRetrieveSilent(self): + def test_CacheRetrieveSilent(self) -> None: """Test the CacheRetrieveSilent() function""" save_CacheRetrieveSilent = SCons.CacheDir.CacheRetrieveSilent @@ -264,7 +264,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CacheRetrieveSilent = save_CacheRetrieveSilent - def test_CachePush(self): + def test_CachePush(self) -> None: """Test the CachePush() function""" save_CachePush = SCons.CacheDir.CachePush @@ -299,7 +299,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CachePush = save_CachePush - def test_warning(self): + def test_warning(self) -> None: """Test raising a warning if we can't copy a file to cache.""" test = TestCmd(workdir='') @@ -309,7 +309,7 @@ class FileTestCase(BaseTestCase): raise OSError shutil.copy2 = copy2 save_mkdir = os.mkdir - def mkdir(dir, mode=0): + def mkdir(dir, mode: int=0) -> None: pass os.mkdir = mkdir old_warn_exceptions = SCons.Warnings.warningAsException(1) @@ -333,7 +333,7 @@ class FileTestCase(BaseTestCase): SCons.Warnings.warningAsException(old_warn_exceptions) SCons.Warnings.suppressWarningClass(SCons.Warnings.CacheWriteErrorWarning) - def test_no_strfunction(self): + def test_no_strfunction(self) -> None: """Test handling no strfunction() for an action.""" save_CacheRetrieveSilent = SCons.CacheDir.CacheRetrieveSilent diff --git a/SCons/Conftest.py b/SCons/Conftest.py index 3c52ef4..3541bce 100644 --- a/SCons/Conftest.py +++ b/SCons/Conftest.py @@ -215,7 +215,7 @@ int main(void) _YesNoResult(context, ret, None, text) return ret -def _check_empty_program(context, comp, text, language, use_shared = False): +def _check_empty_program(context, comp, text, language, use_shared: bool = False): """Return 0 on success, 1 otherwise.""" if comp not in context.env or not context.env[comp]: # The compiler construction variable is not set or empty @@ -626,8 +626,8 @@ int main(void) { return ret def CheckLib(context, libs, func_name = None, header = None, - extra_libs = None, call = None, language = None, autoadd = 1, - append=True, unique=False): + extra_libs = None, call = None, language = None, autoadd: int = 1, + append: bool=True, unique: bool=False): """ Configure check for a C or C++ libraries "libs". Searches through the list of libraries, until one is found where the test succeeds. @@ -753,7 +753,7 @@ def CheckProg(context, prog_name): # END OF PUBLIC FUNCTIONS # -def _YesNoResult(context, ret, key, text, comment = None): +def _YesNoResult(context, ret, key, text, comment = None) -> None: r""" Handle the result of a test with a "yes" or "no" result. @@ -772,7 +772,7 @@ def _YesNoResult(context, ret, key, text, comment = None): context.Display("yes\n") -def _Have(context, key, have, comment = None): +def _Have(context, key, have, comment = None) -> None: r""" Store result of a test in context.havedict and context.headerfilename. @@ -815,7 +815,7 @@ def _Have(context, key, have, comment = None): context.config_h = context.config_h + lines -def _LogFailed(context, text, msg): +def _LogFailed(context, text, msg) -> None: """ Write to the log about a failed program. Add line numbers, so that error messages can be understood. diff --git a/SCons/Debug.py b/SCons/Debug.py index fa07743..000ebd5 100644 --- a/SCons/Debug.py +++ b/SCons/Debug.py @@ -42,7 +42,7 @@ track_instances = False # List of currently tracked classes tracked_classes = {} -def logInstanceCreation(instance, name=None): +def logInstanceCreation(instance, name=None) -> None: if name is None: name = instance.__class__.__name__ if name not in tracked_classes: @@ -60,15 +60,15 @@ def string_to_classes(s): else: return s.split() -def fetchLoggedInstances(classes="*"): +def fetchLoggedInstances(classes: str="*"): classnames = string_to_classes(classes) return [(cn, len(tracked_classes[cn])) for cn in classnames] -def countLoggedInstances(classes, file=sys.stdout): +def countLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write("%s: %d\n" % (classname, len(tracked_classes[classname]))) -def listLoggedInstances(classes, file=sys.stdout): +def listLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write('\n%s:\n' % classname) for ref in tracked_classes[classname]: @@ -79,7 +79,7 @@ def listLoggedInstances(classes, file=sys.stdout): if obj is not None: file.write(' %s\n' % repr(obj)) -def dumpLoggedInstances(classes, file=sys.stdout): +def dumpLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write('\n%s:\n' % classname) for ref in tracked_classes[classname]: @@ -99,7 +99,7 @@ if sys.platform[:5] == "linux": return int(mstr) elif sys.platform[:6] == 'darwin': #TODO really get memory stats for OS X - def memory(): + def memory() -> int: return 0 elif sys.platform == 'win32': from SCons.compat.win32 import get_peak_memory_usage @@ -108,7 +108,7 @@ else: try: import resource except ImportError: - def memory(): + def memory() -> int: return 0 else: def memory(): @@ -132,7 +132,7 @@ def caller_stack(): caller_bases = {} caller_dicts = {} -def caller_trace(back=0): +def caller_trace(back: int=0) -> None: """ Trace caller stack and save info into global dicts, which are printed automatically at the end of SCons execution. @@ -153,7 +153,7 @@ def caller_trace(back=0): callee = caller # print a single caller and its callers, if any -def _dump_one_caller(key, file, level=0): +def _dump_one_caller(key, file, level: int=0) -> None: leader = ' '*level for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) @@ -161,7 +161,7 @@ def _dump_one_caller(key, file, level=0): _dump_one_caller(c, file, level+1) # print each call tree -def dump_caller_counts(file=sys.stdout): +def dump_caller_counts(file=sys.stdout) -> None: for k in sorted(caller_bases.keys()): file.write("Callers of %s:%d(%s), %d calls:\n" % (func_shorten(k) + (caller_bases[k],))) @@ -196,7 +196,7 @@ TimeStampDefault = False StartTime = time.perf_counter() PreviousTime = StartTime -def Trace(msg, tracefile=None, mode='w', tstamp=False): +def Trace(msg, tracefile=None, mode: str='w', tstamp: bool=False) -> None: """Write a trace message. Write messages when debugging which do not interfere with stdout. @@ -217,7 +217,7 @@ def Trace(msg, tracefile=None, mode='w', tstamp=False): global TimeStampDefault global PreviousTime - def trace_cleanup(traceFP): + def trace_cleanup(traceFP) -> None: traceFP.close() if tracefile is None: diff --git a/SCons/Defaults.py b/SCons/Defaults.py index b21ce4c..15041a5 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -164,7 +164,7 @@ def get_paths_str(dest) -> str: If *dest* is a list, manually converts each elem to a string. """ - def quote(arg): + def quote(arg) -> str: return f'"{arg}"' if is_List(dest): @@ -256,7 +256,7 @@ Chmod = ActionFactory(chmod_func, chmod_strfunc) -def copy_func(dest, src, symlinks=True) -> int: +def copy_func(dest, src, symlinks: bool=True) -> int: """Implementation of the Copy action function. Copies *src* to *dest*. If *src* is a list, *dest* must be @@ -308,7 +308,7 @@ def copy_func(dest, src, symlinks=True) -> int: return 0 -def copy_strfunc(dest, src, symlinks=True) -> str: +def copy_strfunc(dest, src, symlinks: bool=True) -> str: """strfunction for the Copy action function.""" return f'Copy({get_paths_str(dest)}, {get_paths_str(src)})' @@ -316,7 +316,7 @@ def copy_strfunc(dest, src, symlinks=True) -> str: Copy = ActionFactory(copy_func, copy_strfunc) -def delete_func(dest, must_exist=False) -> None: +def delete_func(dest, must_exist: bool=False) -> None: """Implementation of the Delete action function. Lets the Python :func:`os.unlink` raise an error if *dest* does not exist, @@ -338,7 +338,7 @@ def delete_func(dest, must_exist=False) -> None: os.unlink(entry) -def delete_strfunc(dest, must_exist=False) -> str: +def delete_strfunc(dest, must_exist: bool=False) -> str: """strfunction for the Delete action function.""" return f'Delete({get_paths_str(dest)})' @@ -392,7 +392,7 @@ Touch = ActionFactory(touch_func, lambda file: f'Touch({get_paths_str(file)})') # Internal utility functions # pylint: disable-msg=too-many-arguments -def _concat(prefix, items_iter, suffix, env, f=lambda x: x, target=None, source=None, affect_signature=True): +def _concat(prefix, items_iter, suffix, env, f=lambda x: x, target=None, source=None, affect_signature: bool=True): """ Creates a new list from 'items_iter' by first interpolating each element in the list using the 'env' dictionary and then calling f on the @@ -602,7 +602,7 @@ class NullCmdGenerator: env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}" """ - def __init__(self, cmd): + def __init__(self, cmd) -> None: self.cmd = cmd def __call__(self, target, source, env, for_signature=None): @@ -622,7 +622,7 @@ class Variable_Method_Caller: create new environment objects to hold the variables.) """ - def __init__(self, variable, method): + def __init__(self, variable, method) -> None: self.variable = variable self.method = method diff --git a/SCons/DefaultsTests.py b/SCons/DefaultsTests.py index b23f328..a59b8b0 100644 --- a/SCons/DefaultsTests.py +++ b/SCons/DefaultsTests.py @@ -32,7 +32,7 @@ from SCons.Errors import UserError class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) @@ -48,7 +48,7 @@ class DummyEnvironment(collections.UserDict): class DefaultsTestCase(unittest.TestCase): - def test_mkdir_func0(self): + def test_mkdir_func0(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir2 = test.workpath('sub', 'dir1', 'dir2') @@ -56,7 +56,7 @@ class DefaultsTestCase(unittest.TestCase): mkdir_func(subdir2) mkdir_func(subdir2) # 2nd time should be OK too - def test_mkdir_func1(self): + def test_mkdir_func1(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir1 = test.workpath('sub', 'dir1') @@ -66,7 +66,7 @@ class DefaultsTestCase(unittest.TestCase): mkdir_func(subdir2) mkdir_func(subdir1) - def test_mkdir_func2(self): + def test_mkdir_func2(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir1 = test.workpath('sub', 'dir1') @@ -84,7 +84,7 @@ class DefaultsTestCase(unittest.TestCase): else: self.fail("expected OSError") - def test__defines_no_target_or_source_arg(self): + def test__defines_no_target_or_source_arg(self) -> None: """ Verify that _defines() function can handle either or neither source or target being specified @@ -106,7 +106,7 @@ class DefaultsTestCase(unittest.TestCase): z = _defines('-D', ['AAB', 'BAB', 'CAB'], 'XYZAB', env, 'XYZ', 'abc') self.assertEqual(z, ['-DAABXYZAB', '-DBABXYZAB', '-DCABXYZAB']) - def test_processDefines(self): + def test_processDefines(self) -> None: """Verify correct handling in processDefines.""" env = DummyEnvironment() diff --git a/SCons/Environment.py b/SCons/Environment.py index bd94832..b074af7 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -87,7 +87,7 @@ _warn_target_signatures_deprecated = True CleanTargets = {} CalculatorArgs = {} -def alias_builder(env, target, source): +def alias_builder(env, target, source) -> None: pass AliasBuilder = SCons.Builder.Builder( @@ -99,7 +99,7 @@ AliasBuilder = SCons.Builder.Builder( name='AliasBuilder', ) -def apply_tools(env, tools, toolpath): +def apply_tools(env, tools, toolpath) -> None: # Store the toolpath in the Environment. # This is expected to work even if no tools are given, so do this first. if toolpath is not None: @@ -145,11 +145,11 @@ def copy_non_reserved_keywords(dict): del result[k] return result -def _set_reserved(env, key, value): +def _set_reserved(env, key, value) -> None: msg = "Ignoring attempt to set reserved variable `$%s'" SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % key) -def _set_future_reserved(env, key, value): +def _set_future_reserved(env, key, value) -> None: env._dict[key] = value msg = "`$%s' will be reserved in a future release and setting it will become ignored" SCons.Warnings.warn(SCons.Warnings.FutureReservedVariableWarning, msg % key) @@ -167,11 +167,11 @@ def _set_BUILDERS(env, key, value): raise UserError('%s is not a Builder.' % repr(v)) bd.update(value) -def _del_SCANNERS(env, key): +def _del_SCANNERS(env, key) -> None: del env._dict[key] env.scanner_map_delete() -def _set_SCANNERS(env, key, value): +def _set_SCANNERS(env, key, value) -> None: env._dict[key] = value env.scanner_map_delete() @@ -305,7 +305,7 @@ def _add_cppdefines( elif is_Tuple(defines): if len(defines) > 2: raise SCons.Errors.UserError( - f"Invalid tuple in CPPDEFINES: {define!r}, must be a two-tuple" + f"Invalid tuple in CPPDEFINES: {defines!r}, must be a two-tuple" ) env_dict[key] = deque([defines]) elif is_List(defines): @@ -438,10 +438,10 @@ class BuilderWrapper(MethodWrapper): source = [source] return super().__call__(target, source, *args, **kw) - def __repr__(self): + def __repr__(self) -> str: return '' % repr(self.name) - def __str__(self): + def __str__(self) -> str: return self.__repr__() def __getattr__(self, name): @@ -452,7 +452,7 @@ class BuilderWrapper(MethodWrapper): else: raise AttributeError(name) - def __setattr__(self, name, value): + def __setattr__(self, name, value) -> None: if name == 'env': self.object = value elif name == 'builder': @@ -476,7 +476,7 @@ class BuilderDict(UserDict): the Builders. We need to do this because every time someone changes the Builders in the Environment's BUILDERS dictionary, we must update the Environment's attributes.""" - def __init__(self, mapping, env): + def __init__(self, mapping, env) -> None: # Set self.env before calling the superclass initialization, # because it will end up calling our other methods, which will # need to point the values in this dictionary to self.env. @@ -488,7 +488,7 @@ class BuilderDict(UserDict): # just copying would modify the original builder raise TypeError( 'cannot semi_deepcopy a BuilderDict' ) - def __setitem__(self, item, val): + def __setitem__(self, item, val) -> None: try: method = getattr(self.env, item).method except AttributeError: @@ -498,11 +498,11 @@ class BuilderDict(UserDict): super().__setitem__(item, val) BuilderWrapper(self.env, val, item) - def __delitem__(self, item): + def __delitem__(self, item) -> None: super().__delitem__(item) delattr(self.env, item) - def update(self, mapping): + def update(self, mapping) -> None: for i, v in mapping.items(): self.__setitem__(i, v) @@ -544,7 +544,7 @@ class SubstitutionEnvironment: class actually becomes useful.) """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialization of an underlying SubstitutionEnvironment class. """ if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.SubstitutionEnvironment') @@ -556,7 +556,7 @@ class SubstitutionEnvironment: self.added_methods = [] #self._memo = {} - def _init_special(self): + def _init_special(self) -> None: """Initial the dispatch tables for special handling of special construction variables.""" self._special_del = {} @@ -577,7 +577,7 @@ class SubstitutionEnvironment: def __eq__(self, other): return self._dict == other._dict - def __delitem__(self, key): + def __delitem__(self, key) -> None: special = self._special_del.get(key) if special: special(self, key) @@ -614,7 +614,7 @@ class SubstitutionEnvironment: """Emulates the get() method of dictionaries.""" return self._dict.get(key, default) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self._dict def keys(self): @@ -682,7 +682,7 @@ class SubstitutionEnvironment: def lvars(self): return {} - def subst(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False): + def subst(self, string, raw: int=0, target=None, source=None, conv=None, executor=None, overrides: bool=False): """Recursively interpolates construction variables from the Environment into the specified string, returning the expanded result. Construction variables are specified by a $ prefix @@ -699,7 +699,7 @@ class SubstitutionEnvironment: lvars.update(executor.get_lvars()) return SCons.Subst.scons_subst(string, self, raw, target, source, gvars, lvars, conv, overrides=overrides) - def subst_kw(self, kw, raw=0, target=None, source=None): + def subst_kw(self, kw, raw: int=0, target=None, source=None): nkw = {} for k, v in kw.items(): k = self.subst(k, raw, target, source) @@ -708,7 +708,7 @@ class SubstitutionEnvironment: nkw[k] = v return nkw - def subst_list(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False): + def subst_list(self, string, raw: int=0, target=None, source=None, conv=None, executor=None, overrides: bool=False): """Calls through to SCons.Subst.scons_subst_list(). See the documentation for that function.""" gvars = self.gvars() @@ -799,7 +799,7 @@ class SubstitutionEnvironment: return out - def AddMethod(self, function, name=None): + def AddMethod(self, function, name=None) -> None: """ Adds the specified function as a method of this construction environment with the specified name. If the name is omitted, @@ -808,7 +808,7 @@ class SubstitutionEnvironment: method = MethodWrapper(self, function, name) self.added_methods.append(method) - def RemoveMethod(self, function): + def RemoveMethod(self, function) -> None: """ Removes the specified function's MethodWrapper from the added_methods list, so we don't re-bind it when making a clone. @@ -873,7 +873,7 @@ class SubstitutionEnvironment: 'RPATH' : [], } - def do_parse(arg): + def do_parse(arg) -> None: # if arg is a sequence, recurse with each element if not arg: return @@ -887,7 +887,7 @@ class SubstitutionEnvironment: arg = self.backtick(arg[1:]) # utility function to deal with -D option - def append_define(name, mapping=mapping): + def append_define(name, mapping=mapping) -> None: t = name.split('=') if len(t) == 1: mapping['CPPDEFINES'].append(name) @@ -1035,7 +1035,7 @@ class SubstitutionEnvironment: do_parse(arg) return mapping - def MergeFlags(self, args, unique=True) -> None: + def MergeFlags(self, args, unique: bool=True) -> None: """Merge flags into construction variables. Merges the flags from *args* into this construction environent. @@ -1166,7 +1166,7 @@ class Base(SubstitutionEnvironment): variables=None, parse_flags=None, **kw - ): + ) -> None: """Initialization of a basic SCons construction environment. Sets up special construction variables like BUILDER, @@ -1304,7 +1304,7 @@ class Base(SubstitutionEnvironment): self._last_CacheDir = cd return cd - def get_factory(self, factory, default='File'): + def get_factory(self, factory, default: str='File'): """Return a factory function for creating Nodes for this construction environment. """ @@ -1373,7 +1373,7 @@ class Base(SubstitutionEnvironment): skey = skey.lower() return self._gsm().get(skey) - def scanner_map_delete(self, kw=None): + def scanner_map_delete(self, kw=None) -> None: """Delete the cached scanner map (if we need to). """ try: @@ -1381,14 +1381,14 @@ class Base(SubstitutionEnvironment): except KeyError: pass - def _update(self, other): + def _update(self, other) -> None: """Private method to update an environment's consvar dict directly. Bypasses the normal checks that occur when users try to set items. """ self._dict.update(other) - def _update_onlynew(self, other): + def _update_onlynew(self, other) -> None: """Private method to add new items to an environment's consvar dict. Only adds items from `other` whose keys do not already appear in @@ -1425,7 +1425,7 @@ class Base(SubstitutionEnvironment): # an Environment's construction variables. ####################################################################### - def Append(self, **kw): + def Append(self, **kw) -> None: """Append values to construction variables in an Environment. The variable is created if it is not already present. @@ -1505,8 +1505,8 @@ class Base(SubstitutionEnvironment): path = str(self.fs.Dir(path)) return path - def AppendENVPath(self, name, newpath, envname='ENV', - sep=os.pathsep, delete_existing=False): + def AppendENVPath(self, name, newpath, envname: str='ENV', + sep=os.pathsep, delete_existing: bool=False) -> None: """Append path elements to the path *name* in the *envname* dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help @@ -1528,7 +1528,7 @@ class Base(SubstitutionEnvironment): self._dict[envname][name] = nv - def AppendUnique(self, delete_existing=False, **kw): + def AppendUnique(self, delete_existing: bool=False, **kw) -> None: """Append values to existing construction variables in an Environment, if they're not already there. If delete_existing is True, removes existing values first, so @@ -1704,7 +1704,7 @@ class Base(SubstitutionEnvironment): return dlist - def Dump(self, key=None, format='pretty'): + def Dump(self, key=None, format: str='pretty'): """ Return construction variables serialized to a string. Args: @@ -1764,7 +1764,7 @@ class Base(SubstitutionEnvironment): return path - def ParseConfig(self, command, function=None, unique=True): + def ParseConfig(self, command, function=None, unique: bool=True): """Parse the result of running a command to update construction vars. Use ``function`` to parse the output of running ``command`` @@ -1790,7 +1790,7 @@ class Base(SubstitutionEnvironment): return function(self, self.backtick(command), unique) - def ParseDepends(self, filename, must_exist=None, only_one=False): + def ParseDepends(self, filename, must_exist=None, only_one: bool=False): """ Parse a mkdep-style file for explicit dependencies. This is completely abusable, and should be unnecessary in the "normal" @@ -1834,7 +1834,7 @@ class Base(SubstitutionEnvironment): platform = self.subst(platform) return SCons.Platform.Platform(platform)(self) - def Prepend(self, **kw): + def Prepend(self, **kw) -> None: """Prepend values to construction variables in an Environment. The variable is created if it is not already present. @@ -1902,8 +1902,8 @@ class Base(SubstitutionEnvironment): self.scanner_map_delete(kw) - def PrependENVPath(self, name, newpath, envname='ENV', - sep=os.pathsep, delete_existing=True): + def PrependENVPath(self, name, newpath, envname: str='ENV', + sep=os.pathsep, delete_existing: bool=True) -> None: """Prepend path elements to the path *name* in the *envname* dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help @@ -1926,7 +1926,7 @@ class Base(SubstitutionEnvironment): self._dict[envname][name] = nv - def PrependUnique(self, delete_existing=False, **kw): + def PrependUnique(self, delete_existing: bool=False, **kw) -> None: """Prepend values to existing construction variables in an Environment, if they're not already there. If delete_existing is True, removes existing values first, so @@ -1969,7 +1969,7 @@ class Base(SubstitutionEnvironment): self._dict[key] = val + dk self.scanner_map_delete(kw) - def Replace(self, **kw): + def Replace(self, **kw) -> None: """Replace existing construction variables in an Environment with new construction variables and/or values. """ @@ -2009,7 +2009,7 @@ class Base(SubstitutionEnvironment): name = name[:-len(old_suffix)] return os.path.join(dir, new_prefix+name+new_suffix) - def SetDefault(self, **kw): + def SetDefault(self, **kw) -> None: for k in list(kw.keys()): if k in self._dict: del kw[k] @@ -2159,7 +2159,7 @@ class Base(SubstitutionEnvironment): nkw = self.subst_kw(kw) return SCons.Builder.Builder(**nkw) - def CacheDir(self, path, custom_class=None): + def CacheDir(self, path, custom_class=None) -> None: if path is not None: path = self.subst(path) self._CacheDir_path = path @@ -2174,7 +2174,7 @@ class Base(SubstitutionEnvironment): # multiple threads, but initializing it before the task walk starts self.get_CacheDir() - def Clean(self, targets, files): + def Clean(self, targets, files) -> None: global CleanTargets tlist = self.arg2nodes(targets, self.fs.Entry) flist = self.arg2nodes(files, self.fs.Entry) @@ -2341,7 +2341,7 @@ class Base(SubstitutionEnvironment): else: return result[0] - def Glob(self, pattern, ondisk=True, source=False, strings=False, exclude=None): + def Glob(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False, exclude=None): return self.fs.Glob(self.subst(pattern), ondisk, source, strings, exclude) def Ignore(self, target, dependency): @@ -2383,7 +2383,7 @@ class Base(SubstitutionEnvironment): t.set_pseudo() return tlist - def Repository(self, *dirs, **kw): + def Repository(self, *dirs, **kw) -> None: dirs = self.arg2nodes(list(dirs), self.fs.Dir) self.fs.Repository(*dirs, **kw) @@ -2406,7 +2406,7 @@ class Base(SubstitutionEnvironment): nkw = self.subst_kw(kw) return SCons.Scanner.ScannerBase(*nargs, **nkw) - def SConsignFile(self, name=SCons.SConsign.current_sconsign_filename(), dbm_module=None): + def SConsignFile(self, name=SCons.SConsign.current_sconsign_filename(), dbm_module=None) -> None: if name is not None: name = self.subst(name) if not os.path.isabs(name): @@ -2469,17 +2469,17 @@ class Base(SubstitutionEnvironment): """ return SCons.Node.Python.ValueWithMemo(value, built_value, name) - def VariantDir(self, variant_dir, src_dir, duplicate=1): + def VariantDir(self, variant_dir, src_dir, duplicate: int=1) -> None: variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0] self.fs.VariantDir(variant_dir, src_dir, duplicate) - def FindSourceFiles(self, node='.') -> list: + def FindSourceFiles(self, node: str='.') -> list: """Return a list of all source files.""" node = self.arg2nodes(node, self.fs.Entry)[0] sources = [] - def build_source(ss): + def build_source(ss) -> None: for s in ss: if isinstance(s, SCons.Node.FS.Dir): build_source(s.all_children()) @@ -2527,7 +2527,7 @@ class OverrideEnvironment(Base): values from the overrides dictionary. """ - def __init__(self, subject, overrides=None): + def __init__(self, subject, overrides=None) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.OverrideEnvironment') self.__dict__['__subject'] = subject if overrides is None: @@ -2551,7 +2551,7 @@ class OverrideEnvironment(Base): else: return attr - def __setattr__(self, name, value): + def __setattr__(self, name, value) -> None: setattr(self.__dict__['__subject'], name, value) # Methods that make this class act like a dictionary. @@ -2588,7 +2588,7 @@ class OverrideEnvironment(Base): except KeyError: return self.__dict__['__subject'].get(key, default) - def __contains__(self, key): + def __contains__(self, key) -> bool: if key in self.__dict__['overrides']: return True return key in self.__dict__['__subject'] @@ -2624,10 +2624,10 @@ class OverrideEnvironment(Base): return default # Overridden private construction environment methods. - def _update(self, other): + def _update(self, other) -> None: self.__dict__['overrides'].update(other) - def _update_onlynew(self, other): + def _update_onlynew(self, other) -> None: """Update a dict with new keys. Unlike the .update method, if the key is already present, @@ -2646,7 +2646,7 @@ class OverrideEnvironment(Base): return lvars # Overridden public construction environment methods. - def Replace(self, **kw): + def Replace(self, **kw) -> None: kw = copy_non_reserved_keywords(kw) self.__dict__['overrides'].update(semi_deepcopy(kw)) @@ -2675,7 +2675,7 @@ def NoSubstitutionProxy(subject): might have assigned to SCons.Environment.Environment. """ class _NoSubstitutionProxy(Environment): - def __init__(self, subject): + def __init__(self, subject) -> None: self.__dict__['__subject'] = subject def __getattr__(self, name): @@ -2684,14 +2684,14 @@ def NoSubstitutionProxy(subject): def __setattr__(self, name, value): return setattr(self.__dict__['__subject'], name, value) - def executor_to_lvars(self, kwdict): + def executor_to_lvars(self, kwdict) -> None: if 'executor' in kwdict: kwdict['lvars'] = kwdict['executor'].get_lvars() del kwdict['executor'] else: kwdict['lvars'] = {} - def raw_to_mode(self, mapping): + def raw_to_mode(self, mapping) -> None: try: raw = mapping['raw'] except KeyError: diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index 81143d5..e7cb99f 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -91,16 +91,16 @@ class Builder(SCons.Builder.BuilderBase): """A dummy Builder class for testing purposes. "Building" a target is simply setting a value in the dictionary. """ - def __init__(self, name = None): + def __init__(self, name = None) -> None: self.name = name - def __call__(self, env, target=None, source=None, **kw): + def __call__(self, env, target=None, source=None, **kw) -> None: global called_it called_it['target'] = target called_it['source'] = source called_it.update(kw) - def execute(self, target = None, **kw): + def execute(self, target = None, **kw) -> None: global built_it built_it[target] = 1 @@ -112,11 +112,11 @@ class Scanner: """A dummy Scanner class for testing purposes. "Scanning" a target is simply setting a value in the dictionary. """ - def __init__(self, name, skeys=[]): + def __init__(self, name, skeys=[]) -> None: self.name = name self.skeys = skeys - def __call__(self, filename): + def __call__(self, filename) -> None: global scanned_it scanned_it[filename] = 1 @@ -129,21 +129,21 @@ class Scanner: def get_skeys(self, env): return self.skeys - def __str__(self): + def __str__(self) -> str: return self.name class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def rfile(self): return self def get_subst_proxy(self): return self -def test_tool( env ): +def test_tool( env ) -> None: env['_F77INCFLAGS'] = '${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}' class TestEnvironmentFixture: @@ -169,12 +169,12 @@ class TestEnvironmentFixture: class SubstitutionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test initializing a SubstitutionEnvironment.""" env = SubstitutionEnvironment() assert '__env__' not in env - def test___cmp__(self): + def test___cmp__(self) -> None: """Test comparing SubstitutionEnvironments.""" env1 = SubstitutionEnvironment(XXX = 'x') env2 = SubstitutionEnvironment(XXX = 'x') @@ -185,38 +185,38 @@ class SubstitutionTestCase(unittest.TestCase): assert env1 != env3 assert env1 != env4 - def test___delitem__(self): + def test___delitem__(self) -> None: """Test deleting a variable from a SubstitutionEnvironment.""" env1 = SubstitutionEnvironment(XXX = 'x', YYY = 'y') env2 = SubstitutionEnvironment(XXX = 'x') del env1['YYY'] assert env1 == env2 - def test___getitem__(self): + def test___getitem__(self) -> None: """Test fetching a variable from a SubstitutionEnvironment.""" env = SubstitutionEnvironment(XXX = 'x') assert env['XXX'] == 'x', env['XXX'] - def test___setitem__(self): + def test___setitem__(self) -> None: """Test setting a variable in a SubstitutionEnvironment.""" env1 = SubstitutionEnvironment(XXX = 'x') env2 = SubstitutionEnvironment(XXX = 'x', YYY = 'y') env1['YYY'] = 'y' assert env1 == env2 - def test_get(self): + def test_get(self) -> None: """Test the SubstitutionEnvironment get() method.""" env = SubstitutionEnvironment(XXX = 'x') assert env.get('XXX') == 'x', env.get('XXX') assert env.get('YYY') is None, env.get('YYY') - def test_contains(self): + def test_contains(self) -> None: """Test the SubstitutionEnvironment __contains__() method.""" env = SubstitutionEnvironment(XXX = 'x') assert 'XXX' in env assert 'YYY' not in env - def test_keys(self): + def test_keys(self) -> None: """Test the SubstitutionEnvironment keys() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -225,7 +225,7 @@ class SubstitutionTestCase(unittest.TestCase): for k in testdata.keys(): assert k in keys, keys - def test_values(self): + def test_values(self) -> None: """Test the SubstitutionEnvironment values() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -234,7 +234,7 @@ class SubstitutionTestCase(unittest.TestCase): for v in testdata.values(): assert v in values, values - def test_items(self): + def test_items(self) -> None: """Test the SubstitutionEnvironment items() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -243,20 +243,20 @@ class SubstitutionTestCase(unittest.TestCase): for k, v in testdata.items(): assert (k, v) in items, items - def test_setdefault(self): + def test_setdefault(self) -> None: """Test the SubstitutionEnvironment setdefault() method.""" env = SubstitutionEnvironment(XXX = 'x') assert env.setdefault('XXX', 'z') == 'x', env['XXX'] assert env.setdefault('YYY', 'y') == 'y', env['YYY'] assert 'YYY' in env - def test_arg2nodes(self): + def test_arg2nodes(self) -> None: """Test the arg2nodes method.""" env = SubstitutionEnvironment() dict = {} class X(SCons.Node.Node): pass - def Factory(name, directory = None, create = 1, dict=dict, X=X): + def Factory(name, directory = None, create: int = 1, dict=dict, X=X): if name not in dict: dict[name] = X() dict[name].name = name @@ -360,7 +360,7 @@ class SubstitutionTestCase(unittest.TestCase): assert not hasattr(nodes[1], 'bbbb'), nodes[0] assert nodes[1].c == 1, nodes[1] - def test_arg2nodes_target_source(self): + def test_arg2nodes_target_source(self) -> None: """Test the arg2nodes method with target= and source= keywords """ targets = [DummyNode('t1'), DummyNode('t2')] @@ -376,19 +376,19 @@ class SubstitutionTestCase(unittest.TestCase): names = [n.name for n in nodes] assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names - def test_gvars(self): + def test_gvars(self) -> None: """Test the base class gvars() method""" env = SubstitutionEnvironment() gvars = env.gvars() assert gvars == {}, gvars - def test_lvars(self): + def test_lvars(self) -> None: """Test the base class lvars() method""" env = SubstitutionEnvironment() lvars = env.lvars() assert lvars == {}, lvars - def test_subst(self): + def test_subst(self) -> None: """Test substituting construction variables within strings Check various combinations, including recursive expansion @@ -447,7 +447,7 @@ class SubstitutionTestCase(unittest.TestCase): # This will take some serious surgery to subst() and # subst_list(), so just leave these tests out until we can # do that. - def bar(arg): + def bar(arg) -> None: pass env = SubstitutionEnvironment(BAR=bar, FOO='$BAR') @@ -458,7 +458,7 @@ class SubstitutionTestCase(unittest.TestCase): subst = env.subst('$FOO', call=None) assert subst is bar, subst - def test_subst_kw(self): + def test_subst_kw(self) -> None: """Test substituting construction variables within dictionaries""" env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'}) @@ -466,7 +466,7 @@ class SubstitutionTestCase(unittest.TestCase): assert kw['a'] == 'aaa', kw['a'] assert kw['bbb'] == 'b', kw['bbb'] - def test_subst_list(self): + def test_subst_list(self) -> None: """Test substituting construction variables in command lists """ env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') @@ -516,7 +516,7 @@ class SubstitutionTestCase(unittest.TestCase): # This will take some serious surgery to subst() and # subst_list(), so just leave these tests out until we can # do that. - def bar(arg): + def bar(arg) -> None: pass env = SubstitutionEnvironment(BAR=bar, FOO='$BAR') @@ -527,21 +527,21 @@ class SubstitutionTestCase(unittest.TestCase): subst = env.subst_list('$FOO', call=None) assert subst is bar, subst - def test_subst_path(self): + def test_subst_path(self) -> None: """Test substituting a path list """ class MyProxy: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def get(self): return self.val + '-proxy' class MyNode: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def get_subst_proxy(self): return self - def __str__(self): + def __str__(self) -> str: return self.val class MyObj: @@ -577,9 +577,9 @@ class SubstitutionTestCase(unittest.TestCase): assert r == ['my1-proxy', 'my2-proxy', n], r class StringableObj: - def __init__(self, s): + def __init__(self, s) -> None: self.s = s - def __str__(self): + def __str__(self) -> str: return self.s env = SubstitutionEnvironment(FOO=StringableObj("foo"), @@ -594,13 +594,13 @@ class SubstitutionTestCase(unittest.TestCase): r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ]) assert r == [ "bar/foo/bar", "baz/bar/baz" ], r - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test the base environment subst_target_source() method""" env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') mystr = env.subst_target_source("$AAA ${AAA}A $BBBB $BBB") assert mystr == "a aA b", mystr - def test_backtick(self): + def test_backtick(self) -> None: """Test the backtick() method for capturing command output""" env = SubstitutionEnvironment() @@ -665,7 +665,7 @@ sys.exit(0) finally: sys.stderr = save_stderr - def test_AddMethod(self): + def test_AddMethod(self) -> None: """Test the AddMethod() method""" env = SubstitutionEnvironment(FOO = 'foo') @@ -682,7 +682,7 @@ sys.exit(0) r = env.bar() assert r == 'func-foo', r - def func2(self, arg=''): + def func2(self, arg: str=''): return 'func2-' + self['FOO'] + arg env.AddMethod(func2) @@ -715,7 +715,7 @@ sys.exit(0) # Test that clones don't re-bind an attribute that the user set. env1 = Environment(FOO = '1') env1.AddMethod(func2) - def replace_func2(): + def replace_func2() -> str: return 'replace_func2' env1.func2 = replace_func2 env2 = env1.Clone(FOO = '2') @@ -734,7 +734,7 @@ sys.exit(0) assert r == 'func2-2', r - def test_Override(self): + def test_Override(self) -> None: """Test overriding construction variables""" env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4) assert env['ONE'] == 1, env['ONE'] @@ -759,7 +759,7 @@ sys.exit(0) assert env2['ONE'] == "won", env2['ONE'] assert env['ONE'] == 1, env['ONE'] - def test_ParseFlags(self): + def test_ParseFlags(self) -> None: """Test the ParseFlags() method """ env = SubstitutionEnvironment() @@ -866,7 +866,7 @@ sys.exit(0) assert d['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], d['RPATH'] - def test_MergeFlags(self): + def test_MergeFlags(self) -> None: """Test the MergeFlags() method.""" env = SubstitutionEnvironment() @@ -936,7 +936,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): 'UNCHANGED_TARGETS', ] - def test___init__(self): + def test___init__(self) -> None: """Test construction Environment creation Create two with identical arguments and check that @@ -949,16 +949,16 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert '__env__' not in env1 assert '__env__' not in env2 - def test_variables(self): + def test_variables(self) -> None: """Test that variables only get applied once.""" class FakeOptions: - def __init__(self, key, val): + def __init__(self, key, val) -> None: self.calls = 0 self.key = key self.val = val def keys(self): return [self.key] - def Update(self, env): + def Update(self, env) -> None: env[self.key] = self.val self.calls = self.calls + 1 @@ -967,7 +967,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert o.calls == 1, o.calls assert env['AAA'] == 'fake_opt', env['AAA'] - def test_get(self): + def test_get(self) -> None: """Test the get() method.""" env = self.TestEnvironment(aaa = 'AAA') @@ -980,7 +980,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): x = env.get('bbb', 'XXX') assert x == 'XXX', x - def test_Builder_calls(self): + def test_Builder_calls(self) -> None: """Test Builder calls through different environments """ global called_it @@ -1008,7 +1008,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert called_it['target'] is None, called_it assert called_it['source'] is None, called_it - def test_BuilderWrapper_attributes(self): + def test_BuilderWrapper_attributes(self) -> None: """Test getting and setting of BuilderWrapper attributes.""" b1 = Builder() b2 = Builder() @@ -1034,7 +1034,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): # underlying method it tests (Environment.BuilderWrapper.execute()) # is necessary, but we're leaving the code here for now in case # that's mistaken. - def _DO_NOT_test_Builder_execs(self): + def _DO_NOT_test_Builder_execs(self) -> None: """Test Builder execution through different environments One environment is initialized with a single @@ -1083,7 +1083,7 @@ env4.builder1.env, env3) - def test_Scanners(self): + def test_Scanners(self) -> None: """Test setting SCANNERS in various ways One environment is initialized with a single @@ -1182,7 +1182,7 @@ env4.builder1.env, env3) s = list(map(env.get_scanner, suffixes)) assert s == [None, None, None, None, None], s - def test_ENV(self): + def test_ENV(self) -> None: """Test setting the external ENV in Environments """ env = Environment() @@ -1191,7 +1191,7 @@ env4.builder1.env, env3) env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' }) assert env.Dictionary('ENV')['PATH'] == '/foo:/bar' - def test_ReservedVariables(self): + def test_ReservedVariables(self) -> None: """Test warning generation when reserved variable names are set""" reserved_variables = [ @@ -1222,7 +1222,7 @@ env4.builder1.env, env3) finally: SCons.Warnings.warningAsException(old) - def test_FutureReservedVariables(self): + def test_FutureReservedVariables(self) -> None: """Test warning generation when future reserved variable names are set""" future_reserved_variables = [] @@ -1244,10 +1244,10 @@ env4.builder1.env, env3) finally: SCons.Warnings.warningAsException(old) - def test_IllegalVariables(self): + def test_IllegalVariables(self) -> None: """Test that use of illegal variables raises an exception""" env = Environment() - def test_it(var, env=env): + def test_it(var, env=env) -> None: exc_caught = None try: env[var] = 1 @@ -1260,7 +1260,7 @@ env4.builder1.env, env3) test_it('foo.bar') test_it('foo-bar') - def test_autogenerate(self): + def test_autogenerate(self) -> None: """Test autogenerating variables in a dictionary.""" drive, p = os.path.splitdrive(os.getcwd()) @@ -1349,13 +1349,13 @@ env4.builder1.env, env3) flags = list(map(normalize_if_path, flags)) assert flags == expect, flags - def test_platform(self): + def test_platform(self) -> None: """Test specifying a platform callable when instantiating.""" class platform: - def __str__(self): return "TestPlatform" - def __call__(self, env): env['XYZZY'] = 777 + def __str__(self) -> str: return "TestPlatform" + def __call__(self, env) -> None: env['XYZZY'] = 777 - def tool(env): + def tool(env) -> None: env['SET_TOOL'] = 'initialized' assert env['PLATFORM'] == "TestPlatform" @@ -1364,13 +1364,13 @@ env4.builder1.env, env3) assert env['PLATFORM'] == "TestPlatform" assert env['SET_TOOL'] == "initialized" - def test_Default_PLATFORM(self): + def test_Default_PLATFORM(self) -> None: """Test overriding the default PLATFORM variable""" class platform: - def __str__(self): return "DefaultTestPlatform" - def __call__(self, env): env['XYZZY'] = 888 + def __str__(self) -> str: return "DefaultTestPlatform" + def __call__(self, env) -> None: env['XYZZY'] = 888 - def tool(env): + def tool(env) -> None: env['SET_TOOL'] = 'abcde' assert env['PLATFORM'] == "DefaultTestPlatform" @@ -1388,15 +1388,15 @@ env4.builder1.env, env3) finally: SCons.Defaults.ConstructionEnvironment = save - def test_tools(self): + def test_tools(self) -> None: """Test specifying a tool callable when instantiating.""" - def t1(env): + def t1(env) -> None: env['TOOL1'] = 111 - def t2(env): + def t2(env) -> None: env['TOOL2'] = 222 - def t3(env): + def t3(env) -> None: env['AAA'] = env['XYZ'] - def t4(env): + def t4(env) -> None: env['TOOL4'] = 444 env = self.TestEnvironment(tools = [t1, t2, t3], XYZ = 'aaa') assert env['TOOL1'] == 111, env['TOOL1'] @@ -1421,15 +1421,15 @@ def exists(env): assert env['b'] == 2, env['b'] assert env['c'] == 3, env['c'] - def test_Default_TOOLS(self): + def test_Default_TOOLS(self) -> None: """Test overriding the default TOOLS variable""" - def t5(env): + def t5(env) -> None: env['TOOL5'] = 555 - def t6(env): + def t6(env) -> None: env['TOOL6'] = 666 - def t7(env): + def t7(env) -> None: env['BBB'] = env['XYZ'] - def t8(env): + def t8(env) -> None: env['TOOL8'] = 888 import SCons.Defaults @@ -1447,11 +1447,11 @@ def exists(env): finally: SCons.Defaults.ConstructionEnvironment = save - def test_null_tools(self): + def test_null_tools(self) -> None: """Test specifying a tool of None is OK.""" - def t1(env): + def t1(env) -> None: env['TOOL1'] = 111 - def t2(env): + def t2(env) -> None: env['TOOL2'] = 222 env = self.TestEnvironment(tools = [t1, None, t2], XYZ = 'aaa') assert env['TOOL1'] == 111, env['TOOL1'] @@ -1464,10 +1464,10 @@ def exists(env): assert env['TOOL2'] == 222, env assert env['XYZ'] == 'ddd', env - def test_default_copy_cache(self): + def test_default_copy_cache(self) -> None: copied = False - def copy2(self, src, dst): + def copy2(self, src, dst) -> None: nonlocal copied copied = True @@ -1489,7 +1489,7 @@ def exists(env): SCons.CacheDir.CacheDir.copy_from_cache = save_copy_from_cache SCons.CacheDir.CacheDir.copy_to_cache = save_copy_to_cache - def test_concat(self): + def test_concat(self) -> None: """Test _concat()""" e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b']) s = e1.subst @@ -1507,7 +1507,7 @@ def exists(env): assert x == '$( preasuf prebsuf $)', x - def test_concat_nested(self): + def test_concat_nested(self) -> None: """Test _concat() on a nested substitution strings.""" e = self.TestEnvironment(PRE='pre', SUF='suf', L1=['a', 'b'], @@ -1522,7 +1522,7 @@ def exists(env): x = e.subst('$( ${_concat(PRE, L1, SUF, __env__)} $)') assert x == 'preasuf prebsuf precsuf predsuf precsuf predsuf', x - def test_gvars(self): + def test_gvars(self) -> None: """Test the Environment gvars() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z') gvars = env.gvars() @@ -1530,7 +1530,7 @@ def exists(env): assert gvars['YYY'] == 'y', gvars['YYY'] assert gvars['ZZZ'] == 'z', gvars['ZZZ'] - def test__update(self): + def test__update(self) -> None: """Test the _update() method""" env = self.TestEnvironment(X = 'x', Y = 'y', Z = 'z') assert env['X'] == 'x', env['X'] @@ -1550,7 +1550,7 @@ def exists(env): assert env['SOURCE'] == 's', env['SOURCE'] assert env['SOURCES'] == 'sss', env['SOURCES'] - def test_Append(self): + def test_Append(self) -> None: """Test appending to construction variables in an Environment """ @@ -1679,9 +1679,9 @@ def exists(env): assert result == ['foo', 'bar'], result class C: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def __eq__(self, other): raise Exception("should not compare") @@ -1708,7 +1708,7 @@ def exists(env): assert hasattr(env4, 'z1') assert hasattr(env4, 'z2') - def test_AppendENVPath(self): + def test_AppendENVPath(self) -> None: """Test appending to an ENV path.""" env1 = self.TestEnvironment( ENV={'PATH': r'C:\dir\num\one;C:\dir\num\two'}, @@ -1738,7 +1738,7 @@ def exists(env): env1.AppendENVPath('PATH', env1.fs.Dir('sub2'), sep=';') assert env1['ENV']['PATH'] == p + ';sub1;sub2', env1['ENV']['PATH'] - def test_AppendUnique(self): + def test_AppendUnique(self) -> None: """Test appending to unique values to construction variables This strips values that are already present when lists are @@ -1815,7 +1815,7 @@ def exists(env): assert isinstance(result, CLVar), repr(result) assert result == ['bar'], result - def test_Clone(self): + def test_Clone(self) -> None: """Test construction environment cloning. The clone should compare equal if there are no overrides. @@ -1900,13 +1900,13 @@ def exists(env): # Ensure that specifying new tools in a copied environment works. with self.subTest(): - def foo(env): + def foo(env) -> None: env['FOO'] = 1 - def bar(env): + def bar(env) -> None: env['BAR'] = 2 - def baz(env): + def baz(env) -> None: env['BAZ'] = 3 env1 = self.TestEnvironment(tools=[foo]) @@ -1989,7 +1989,7 @@ def generate(env): with self.subTest(): real_value = [4] - def my_tool(env, rv=real_value): + def my_tool(env, rv=real_value) -> None: assert env['KEY_THAT_I_WANT'] == rv[0] env['KEY_THAT_I_WANT'] = rv[0] + 1 @@ -2010,7 +2010,7 @@ def generate(env): assert ('BUILDERS' in env) is False env2 = env.Clone() - def test_Detect(self): + def test_Detect(self) -> None: """Test Detect()ing tools""" test = TestCmd.TestCmd(workdir = '') test.subdir('sub1', 'sub2') @@ -2065,7 +2065,7 @@ def generate(env): x = env.Detect('xxx.exe') assert x is None, x - def test_Dictionary(self): + def test_Dictionary(self) -> None: """Test retrieval of known construction variables Fetch them from the Dictionary and check for well-known @@ -2089,7 +2089,7 @@ def generate(env): del env['XXX'] assert 'XXX' not in env.Dictionary() - def test_FindIxes(self): + def test_FindIxes(self) -> None: """Test FindIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', @@ -2111,7 +2111,7 @@ def generate(env): assert None is env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX') assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX') - def test_ParseConfig(self): + def test_ParseConfig(self) -> None: """Test the ParseConfig() method""" env = self.TestEnvironment(COMMAND='command', ASFLAGS='assembler', @@ -2132,7 +2132,7 @@ def generate(env): Just returns the string it was given. """ - def __init__(self, save_command, output): + def __init__(self, save_command, output) -> None: self.save_command = save_command self.output = output def __call__(self, command): @@ -2198,7 +2198,7 @@ def generate(env): # check that we can pass our own function, # and that it works for both values of unique - def my_function(myenv, flags, unique=True): + def my_function(myenv, flags, unique: bool=True) -> None: import json args = json.loads(flags) @@ -2221,7 +2221,7 @@ def generate(env): assert env2['LIBS'] == ['xxx', 'yyy', 'xxx', 'yyy'], env2['LIBS'] - def test_ParseDepends(self): + def test_ParseDepends(self) -> None: """Test the ParseDepends() method""" test = TestCmd.TestCmd(workdir = '') @@ -2250,7 +2250,7 @@ f5: \ tlist = [] dlist = [] - def my_depends(target, dependency, tlist=tlist, dlist=dlist): + def my_depends(target, dependency, tlist=tlist, dlist=dlist) -> None: tlist.extend(target) dlist.extend(dependency) @@ -2290,7 +2290,7 @@ f5: \ exc_caught = 1 assert exc_caught, "did not catch expected UserError" - def test_Platform(self): + def test_Platform(self) -> None: """Test the Platform() method""" env = self.TestEnvironment(WIN32='win32', NONE='no-such-platform') @@ -2314,7 +2314,7 @@ f5: \ env.Platform('$WIN32') assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX'] - def test_Prepend(self): + def test_Prepend(self) -> None: """Test prepending to construction variables in an Environment """ cases = [ @@ -2450,7 +2450,7 @@ f5: \ assert hasattr(env4, 'z1') assert hasattr(env4, 'z2') - def test_PrependENVPath(self): + def test_PrependENVPath(self) -> None: """Test prepending to an ENV path.""" env1 = self.TestEnvironment( ENV={'PATH': r'C:\dir\num\one;C:\dir\num\two'}, @@ -2480,7 +2480,7 @@ f5: \ env1.PrependENVPath('PATH', env1.fs.Dir('sub2'), sep=';') assert env1['ENV']['PATH'] == 'sub2;sub1;' + p, env1['ENV']['PATH'] - def test_PrependUnique(self): + def test_PrependUnique(self) -> None: """Test prepending unique values to construction variables This strips values that are already present when lists are @@ -2551,7 +2551,7 @@ f5: \ assert isinstance(result, CLVar), repr(result) assert result == ['bar'], result - def test_Replace(self): + def test_Replace(self) -> None: """Test replacing construction variables in an Environment After creation of the Environment, of course. @@ -2570,7 +2570,7 @@ f5: \ assert not hasattr(env3, 'b1'), "b1 was not cleared" assert hasattr(env3, 'b2'), "b2 was not set" - def test_ReplaceIxes(self): + def test_ReplaceIxes(self) -> None: """Test ReplaceIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', @@ -2591,7 +2591,7 @@ f5: \ 'PREFIX', 'SUFFIX', 'LIBPREFIX', 'LIBSUFFIX') - def test_SetDefault(self): + def test_SetDefault(self) -> None: """Test the SetDefault method""" env = self.TestEnvironment(tools = []) env.SetDefault(V1 = 1) @@ -2601,7 +2601,7 @@ f5: \ env.SetDefault(V2 = 1) assert env['V2'] == 2 - def test_Tool(self): + def test_Tool(self) -> None: """Test the Tool() method""" env = self.TestEnvironment(LINK='link', NONE='no-such-tool') @@ -2652,7 +2652,7 @@ def generate(env): env.Tool('yyy') assert env['YYY'] == 'two', env['YYY'] - def test_WhereIs(self): + def test_WhereIs(self) -> None: """Test the WhereIs() method""" test = TestCmd.TestCmd(workdir = '') @@ -2731,7 +2731,7 @@ def generate(env): - def test_Action(self): + def test_Action(self) -> None: """Test the Action() method""" import SCons.Action @@ -2753,13 +2753,13 @@ def generate(env): assert a, a assert a.__class__ is SCons.Action.ListAction, a.__class__ - def func(arg): + def func(arg) -> None: pass a = env.Action(func) assert a, a assert a.__class__ is SCons.Action.FunctionAction, a.__class__ - def test_AddPostAction(self): + def test_AddPostAction(self) -> None: """Test the AddPostAction() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') @@ -2770,7 +2770,7 @@ def generate(env): assert str(n[0]) == 'ggg', n[0] assert str(n[1]) == 'bbb', n[1] - def test_AddPreAction(self): + def test_AddPreAction(self) -> None: """Test the AddPreAction() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') @@ -2781,7 +2781,7 @@ def generate(env): assert str(n[0]) == 'ggg', n[0] assert str(n[1]) == 'bbb', n[1] - def test_Alias(self): + def test_Alias(self) -> None: """Test the Alias() method""" env = self.TestEnvironment(FOO='kkk', BAR='lll', EA='export_alias') @@ -2843,7 +2843,7 @@ def generate(env): s = str(tgt.builder.action) assert s == "action1\naction2\naction3", s - def test_AlwaysBuild(self): + def test_AlwaysBuild(self) -> None: """Test the AlwaysBuild() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR', @@ -2870,12 +2870,12 @@ def generate(env): assert t[6].get_internal_path() == 'file' assert t[6].always_build - def test_VariantDir(self): + def test_VariantDir(self) -> None: """Test the VariantDir() method""" class MyFS: def Dir(self, name): return name - def VariantDir(self, variant_dir, src_dir, duplicate): + def VariantDir(self, variant_dir, src_dir, duplicate) -> None: self.variant_dir = variant_dir self.src_dir = src_dir self.duplicate = duplicate @@ -2893,7 +2893,7 @@ def generate(env): assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir assert env.fs.duplicate == 0, env.fs.duplicate - def test_Builder(self): + def test_Builder(self) -> None: """Test the Builder() method""" env = self.TestEnvironment(FOO = 'xyzzy') @@ -2906,14 +2906,14 @@ def generate(env): b = env.Builder(action = ['$FOO', 'foo']) assert b is not None, b - def func(arg): + def func(arg) -> None: pass b = env.Builder(action = func) assert b is not None, b b = env.Builder(generator = func) assert b is not None, b - def test_CacheDir(self): + def test_CacheDir(self) -> None: """Test the CacheDir() method""" test = TestCmd.TestCmd(workdir = '') @@ -2943,7 +2943,7 @@ def generate(env): assert not os.path.isfile(test_foo1_config), "No file %s"%test_foo1_config - def test_Clean(self): + def test_Clean(self) -> None: """Test the Clean() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -2969,7 +2969,7 @@ def generate(env): l = list(map(str, CT[fff])) assert l == ['ddd', 'eee', 'fff'], l - def test_Command(self): + def test_Command(self) -> None: """Test the Command() method.""" env = Environment() t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'], @@ -2985,7 +2985,7 @@ def generate(env): action='buildbar $target $source')[0] assert 'sub' in [x.get_internal_path() for x in t.sources] - def testFunc(env, target, source): + def testFunc(env, target, source) -> int: assert str(target[0]) == 'foo.out' srcs = list(map(str, source)) assert 'foo1.in' in srcs and 'foo2.in' in srcs, srcs @@ -3002,7 +3002,7 @@ def generate(env): assert 'foo2.in' in [x.get_internal_path() for x in t.sources] x = [] - def test2(baz, x=x): + def test2(baz, x=x) -> None: x.append(baz) env = self.TestEnvironment(TEST2 = test2) t = env.Command(target='baz.out', source='baz.in', @@ -3024,7 +3024,7 @@ def generate(env): source_scanner = 'fake')[0] assert t.builder.source_scanner == 'fake', t.builder.source_scanner - def test_Configure(self): + def test_Configure(self) -> None: """Test the Configure() method""" # Configure() will write to a local temporary file. test = TestCmd.TestCmd(workdir = '') @@ -3035,7 +3035,7 @@ def generate(env): env = self.TestEnvironment(FOO = 'xyzzy') - def func(arg): + def func(arg) -> None: pass c = env.Configure() @@ -3050,7 +3050,7 @@ def generate(env): finally: os.chdir(save) - def test_Depends(self): + def test_Depends(self) -> None: """Test the explicit Depends method.""" env = self.TestEnvironment(FOO = 'xxx', BAR='yyy') env.Dir('dir1') @@ -3082,10 +3082,10 @@ def generate(env): assert d.__class__.__name__ == 'Dir', d.__class__.__name__ assert d.get_internal_path() == 'dir2' - def test_Dir(self): + def test_Dir(self) -> None: """Test the Dir() method""" class MyFS: - def Dir(self, name): + def Dir(self, name) -> str: return 'Dir(%s)' % name env = self.TestEnvironment(FOO = 'foodir', BAR = 'bardir') @@ -3106,7 +3106,7 @@ def generate(env): d = env.Dir(['dir1', 'dir2']) assert d == ['Dir(dir1)', 'Dir(dir2)'], d - def test_NoClean(self): + def test_NoClean(self) -> None: """Test the NoClean() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3129,7 +3129,7 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].noclean - def test_Dump(self): + def test_Dump(self) -> None: """Test the Dump() method""" env = self.TestEnvironment(FOO = 'foo') @@ -3148,7 +3148,7 @@ def generate(env): else: self.fail("Did not catch expected ValueError.") - def test_Environment(self): + def test_Environment(self) -> None: """Test the Environment() method""" env = self.TestEnvironment(FOO = 'xxx', BAR = 'yyy') @@ -3156,13 +3156,13 @@ def generate(env): assert e2['X'] == 'xxx', e2['X'] assert e2['Y'] == 'yyy', e2['Y'] - def test_Execute(self): + def test_Execute(self) -> None: """Test the Execute() method""" class MyAction: - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: self.args = args - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> str: return "%s executed" % self.args env = Environment() @@ -3171,10 +3171,10 @@ def generate(env): result = env.Execute("foo") assert result == "foo executed", result - def test_Entry(self): + def test_Entry(self) -> None: """Test the Entry() method""" class MyFS: - def Entry(self, name): + def Entry(self, name) -> str: return 'Entry(%s)' % name env = self.TestEnvironment(FOO = 'fooentry', BAR = 'barentry') @@ -3195,10 +3195,10 @@ def generate(env): e = env.Entry(['entry1', 'entry2']) assert e == ['Entry(entry1)', 'Entry(entry2)'], e - def test_File(self): + def test_File(self) -> None: """Test the File() method""" class MyFS: - def File(self, name): + def File(self, name) -> str: return 'File(%s)' % name env = self.TestEnvironment(FOO = 'foofile', BAR = 'barfile') @@ -3219,7 +3219,7 @@ def generate(env): f = env.File(['file1', 'file2']) assert f == ['File(file1)', 'File(file2)'], f - def test_FindFile(self): + def test_FindFile(self) -> None: """Test the FindFile() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -3228,7 +3228,7 @@ def generate(env): # XXX - def test_Flatten(self): + def test_Flatten(self) -> None: """Test the Flatten() method""" env = Environment() l = env.Flatten([1]) @@ -3236,7 +3236,7 @@ def generate(env): l = env.Flatten([1, [2, [3, [4]]]]) assert l == [1, 2, 3, 4], l - def test_GetBuildPath(self): + def test_GetBuildPath(self) -> None: """Test the GetBuildPath() method.""" env = self.TestEnvironment(MAGIC = 'xyzzy') @@ -3246,7 +3246,7 @@ def generate(env): p = env.GetBuildPath('$MAGIC') assert p == 'xyzzy', p - def test_Ignore(self): + def test_Ignore(self) -> None: """Test the explicit Ignore method.""" env = self.TestEnvironment(FOO='yyy', BAR='zzz') env.Dir('dir1') @@ -3278,7 +3278,7 @@ def generate(env): assert i.__class__.__name__ == 'Dir', i.__class__.__name__ assert i.get_internal_path() == 'dir2' - def test_Literal(self): + def test_Literal(self) -> None: """Test the Literal() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0] @@ -3286,7 +3286,7 @@ def generate(env): list = env.subst_list(['$FOO', env.Literal('$BAR')])[0] assert list == ['fff', '$BAR'], list - def test_Local(self): + def test_Local(self) -> None: """Test the Local() method.""" env = self.TestEnvironment(FOO='lll') @@ -3297,7 +3297,7 @@ def generate(env): assert str(l[0]) == 'ggg', l[0] assert str(l[1]) == 'lll', l[1] - def test_Precious(self): + def test_Precious(self) -> None: """Test the Precious() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3320,7 +3320,7 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].precious - def test_Pseudo(self): + def test_Pseudo(self) -> None: """Test the Pseudo() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3343,12 +3343,12 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].pseudo - def test_Repository(self): + def test_Repository(self) -> None: """Test the Repository() method.""" class MyFS: - def __init__(self): + def __init__(self) -> None: self.list = [] - def Repository(self, *dirs): + def Repository(self, *dirs) -> None: self.list.extend(list(dirs)) def Dir(self, name): return name @@ -3359,9 +3359,9 @@ def generate(env): expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo'] assert env.fs.list == expect, env.fs.list - def test_Scanner(self): + def test_Scanner(self) -> None: """Test the Scanner() method""" - def scan(node, env, target, arg): + def scan(node, env, target, arg) -> None: pass env = self.TestEnvironment(FOO = scan) @@ -3379,7 +3379,7 @@ def generate(env): s = env.Scanner(function = '$FOO') assert s is not None, s - def test_SConsignFile(self): + def test_SConsignFile(self) -> None: """Test the SConsignFile() method""" import SCons.SConsign @@ -3394,7 +3394,7 @@ def generate(env): try: fnames = [] dbms = [] - def capture(name, dbm_module, fnames=fnames, dbms=dbms): + def capture(name, dbm_module, fnames=fnames, dbms=dbms) -> None: fnames.append(name) dbms.append(dbm_module) @@ -3435,7 +3435,7 @@ def generate(env): finally: SCons.SConsign.File = save_SConsign_File - def test_SideEffect(self): + def test_SideEffect(self) -> None: """Test the SideEffect() method""" env = self.TestEnvironment(LIB='lll', FOO='fff', BAR='bbb') env.File('mylll.pdb') @@ -3480,7 +3480,7 @@ def generate(env): assert len(s) == 0, len(s) assert len(ggg.side_effects) == before, len(ggg.side_effects) - def test_Split(self): + def test_Split(self) -> None: """Test the Split() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') s = env.Split("foo bar") @@ -3497,7 +3497,7 @@ def generate(env): assert s == ["fffbbb"], s - def test_Value(self): + def test_Value(self) -> None: """Test creating a Value() object """ env = Environment() @@ -3519,7 +3519,7 @@ def generate(env): assert v4.name == 'name', v4.name - def test_Environment_global_variable(self): + def test_Environment_global_variable(self) -> None: """Test setting Environment variable to an Environment.Base subclass""" class MyEnv(SCons.Environment.Base): def xxx(self, string): @@ -3535,7 +3535,7 @@ def generate(env): f = env.xxx('$FOO') assert f == 'foo', f - def test_bad_keywords(self): + def test_bad_keywords(self) -> None: """Test trying to use reserved keywords in an Environment""" added = [] @@ -3658,7 +3658,7 @@ def generate(env): for x in added + ['OVERRIDE']: assert x in over, bad_msg % x - def test_parse_flags(self): + def test_parse_flags(self) -> None: """Test the Base class parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools=[], parse_flags = '-X') @@ -3672,7 +3672,7 @@ def generate(env): assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] self.assertEqual(list(env['CPPDEFINES']), ['FOO', 'BAR']) - def test_clone_parse_flags(self): + def test_clone_parse_flags(self) -> None: """Test the env.Clone() parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools = []) @@ -3697,10 +3697,10 @@ def generate(env): class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): - def setUp(self): + def setUp(self) -> None: env = Environment() env._dict = {'XXX' : 'x', 'YYY' : 'y'} - def verify_value(env, key, value, *args, **kwargs): + def verify_value(env, key, value, *args, **kwargs) -> None: """Verifies that key is value on the env this is called with.""" assert env[key] == value env.AddMethod(verify_value) @@ -3711,7 +3711,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): def checkpath(self, node, expect): return str(node) == os.path.normpath(expect) - def test___init__(self): + def test___init__(self) -> None: """Test OverrideEnvironment initialization""" env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] @@ -3721,7 +3721,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert env2['YYY'] == 'y', env2['YYY'] assert env3['YYY'] == 'y3', env3['YYY'] - def test___delitem__(self): + def test___delitem__(self) -> None: """Test deleting variables from an OverrideEnvironment""" env, env2, env3 = self.envs @@ -3740,7 +3740,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'ZZZ' not in env2, "env2 has ZZZ?" assert 'ZZZ' not in env3, "env3 has ZZZ?" - def test_get(self): + def test_get(self) -> None: """Test the OverrideEnvironment get() method""" env, env2, env3 = self.envs assert env.get('XXX') == 'x', env.get('XXX') @@ -3753,7 +3753,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert env2.get('ZZZ') is None, env2.get('ZZZ') assert env3.get('ZZZ') == 'z3', env3.get('ZZZ') - def test_contains(self): + def test_contains(self) -> None: """Test the OverrideEnvironment __contains__() method""" env, env2, env3 = self.envs assert 'XXX' in env, 'XXX' in env @@ -3766,7 +3766,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'ZZZ' not in env2, 'ZZZ' in env2 assert 'ZZZ' in env3, 'ZZZ' in env3 - def test_Dictionary(self): + def test_Dictionary(self) -> None: """Test the OverrideEnvironment Dictionary() method""" env, env2, env3 = self.envs # nothing overrriden @@ -3788,7 +3788,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'XXX' not in env2.Dictionary() assert 'XXX' not in env.Dictionary() - def test_items(self): + def test_items(self) -> None: """Test the OverrideEnvironment items() method""" env, env2, env3 = self.envs items = sorted(env.items()) @@ -3798,7 +3798,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): items = sorted(env3.items()) assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items - def test_keys(self): + def test_keys(self) -> None: """Test the OverrideEnvironment keys() method""" env, env2, env3 = self.envs keys = sorted(env.keys()) @@ -3808,7 +3808,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): keys = sorted(env3.keys()) assert keys == ['XXX', 'YYY', 'ZZZ'], keys - def test_values(self): + def test_values(self) -> None: """Test the OverrideEnvironment values() method""" env, env2, env3 = self.envs values = sorted(env.values()) @@ -3818,7 +3818,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): values = sorted(env3.values()) assert values == ['x3', 'y3', 'z3'], values - def test_setdefault(self): + def test_setdefault(self) -> None: """Test the OverrideEnvironment setdefault() method.""" env, env2, env3 = self.envs # does not set for existing key @@ -3828,7 +3828,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # set did not leak through to base env assert 'ZZZ' not in env - def test_gvars(self): + def test_gvars(self) -> None: """Test the OverrideEnvironment gvars() method""" env, env2, env3 = self.envs gvars = env.gvars() @@ -3838,7 +3838,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): gvars = env3.gvars() assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars - def test_lvars(self): + def test_lvars(self) -> None: """Test the OverrideEnvironment lvars() method""" env, env2, env3 = self.envs lvars = env.lvars() @@ -3848,7 +3848,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): lvars = env3.lvars() assert lvars == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, lvars - def test_Replace(self): + def test_Replace(self) -> None: """Test the OverrideEnvironment Replace() method""" env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] @@ -3895,7 +3895,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # """Test the OverrideEnvironment Clone() method""" # pass - def test_FindIxes(self): + def test_FindIxes(self) -> None: """Test the OverrideEnvironment FindIxes() method""" env, env2, env3 = self.envs x = env.FindIxes(['xaaay'], 'XXX', 'YYY') @@ -3905,7 +3905,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.FindIxes(['x3aaay3'], 'XXX', 'YYY') assert x == 'x3aaay3', x - def test_ReplaceIxes(self): + def test_ReplaceIxes(self) -> None: """Test the OverrideEnvironment ReplaceIxes() method""" env, env2, env3 = self.envs x = env.ReplaceIxes('xaaay', 'XXX', 'YYY', 'YYY', 'XXX') @@ -3921,14 +3921,14 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # """Test the OverrideEnvironment WhereIs() method""" # pass - def test_PseudoBuilderInherits(self): + def test_PseudoBuilderInherits(self) -> None: """Test that pseudo-builders inherit the overrided values.""" env, env2, env3 = self.envs env.verify_value('XXX', 'x') env2.verify_value('XXX', 'x2') env3.verify_value('XXX', 'x3') - def test_Dir(self): + def test_Dir(self) -> None: """Test the OverrideEnvironment Dir() method""" env, env2, env3 = self.envs x = env.Dir('ddir/$XXX') @@ -3938,7 +3938,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Dir('ddir/$XXX') assert self.checkpath(x, 'ddir/x3'), str(x) - def test_Entry(self): + def test_Entry(self) -> None: """Test the OverrideEnvironment Entry() method""" env, env2, env3 = self.envs x = env.Entry('edir/$XXX') @@ -3948,7 +3948,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Entry('edir/$XXX') assert self.checkpath(x, 'edir/x3'), str(x) - def test_File(self): + def test_File(self) -> None: """Test the OverrideEnvironment File() method""" env, env2, env3 = self.envs x = env.File('fdir/$XXX') @@ -3958,7 +3958,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.File('fdir/$XXX') assert self.checkpath(x, 'fdir/x3'), str(x) - def test_Split(self): + def test_Split(self) -> None: """Test the OverrideEnvironment Split() method""" env, env2, env3 = self.envs env['AAA'] = '$XXX $YYY $ZZZ' @@ -3969,7 +3969,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Split('$AAA') assert x == ['x3', 'y3', 'z3'], x - def test_parse_flags(self): + def test_parse_flags(self) -> None: """Test the OverrideEnvironment parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = SubstitutionEnvironment() @@ -3996,7 +3996,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): - def test___init__(self): + def test___init__(self) -> None: """Test NoSubstitutionProxy initialization""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4006,7 +4006,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): assert proxy['XXX'] == 'x', proxy['XXX'] assert proxy['YYY'] == 'y', proxy['YYY'] - def test_attributes(self): + def test_attributes(self) -> None: """Test getting and setting NoSubstitutionProxy attributes""" env = Environment() setattr(env, 'env_attr', 'value1') @@ -4024,7 +4024,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = getattr(proxy, 'proxy_attr') assert x == 'value2', x - def test_subst(self): + def test_subst(self) -> None: """Test the NoSubstitutionProxy.subst() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4044,7 +4044,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): extra_meaningless_keyword_argument=None) assert x == '$YYY', x - def test_subst_kw(self): + def test_subst_kw(self) -> None: """Test the NoSubstitutionProxy.subst_kw() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4059,7 +4059,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = proxy.subst_kw({'$XXX':'$YYY'}) assert x == {'$XXX':'$YYY'}, x - def test_subst_list(self): + def test_subst_list(self) -> None: """Test the NoSubstitutionProxy.subst_list() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4077,7 +4077,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = proxy.subst_list('$YYY', raw=0, target=None, source=None, conv=None) assert x == [[]], x - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test the NoSubstitutionProxy.subst_target_source() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4096,7 +4096,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): class EnvironmentVariableTestCase(unittest.TestCase): - def test_is_valid_construction_var(self): + def test_is_valid_construction_var(self) -> None: """Testing is_valid_construction_var()""" r = is_valid_construction_var("_a") assert r is not None, r diff --git a/SCons/EnvironmentValues.py b/SCons/EnvironmentValues.py index c5eb972..51368c9 100644 --- a/SCons/EnvironmentValues.py +++ b/SCons/EnvironmentValues.py @@ -72,7 +72,7 @@ class EnvironmentValue: Hold a single value. We're going to cache parsed version of the file We're going to keep track of variables which feed into this values evaluation """ - def __init__(self, value): + def __init__(self, value) -> None: self.value = value self.var_type = ValueTypes.UNKNOWN @@ -82,7 +82,7 @@ class EnvironmentValue: self.parse_value() - def parse_value(self): + def parse_value(self) -> None: """ Scan the string and break into component values """ @@ -99,7 +99,7 @@ class EnvironmentValue: # likely callable? either way we don't parse self._parsed = self.value - def parse_trial(self): + def parse_trial(self) -> None: """ Try alternate parsing methods. :return: @@ -113,7 +113,7 @@ class EnvironmentValues: """ A class to hold all the environment variables """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} for k in kw: self._dict[k] = EnvironmentValue(kw[k]) diff --git a/SCons/EnvironmentValuesTest.py b/SCons/EnvironmentValuesTest.py index 074aa85..25d8804 100644 --- a/SCons/EnvironmentValuesTest.py +++ b/SCons/EnvironmentValuesTest.py @@ -26,7 +26,7 @@ import unittest from SCons.EnvironmentValues import EnvironmentValues class MyTestCase(unittest.TestCase): - def test_simple_environmentValues(self): + def test_simple_environmentValues(self) -> None: """Test comparing SubstitutionEnvironments """ diff --git a/SCons/Errors.py b/SCons/Errors.py index d37cb6d..b40ba0e 100644 --- a/SCons/Errors.py +++ b/SCons/Errors.py @@ -71,9 +71,9 @@ class BuildError(Exception): """ def __init__(self, - node=None, errstr="Unknown error", status=2, exitstatus=2, + node=None, errstr: str="Unknown error", status: int=2, exitstatus: int=2, filename=None, executor=None, action=None, command=None, - exc_info=(None, None, None)): + exc_info=(None, None, None)) -> None: # py3: errstr should be string and not bytes. @@ -91,7 +91,7 @@ class BuildError(Exception): super().__init__(node, errstr, status, exitstatus, filename, executor, action, command, exc_info) - def __str__(self): + def __str__(self) -> str: if self.filename: return self.filename + ': ' + self.errstr else: @@ -113,7 +113,7 @@ class MSVCError(IOError): pass class ExplicitExit(Exception): - def __init__(self, node=None, status=None, *args): + def __init__(self, node=None, status=None, *args) -> None: self.node = node self.status = status self.exitstatus = status diff --git a/SCons/ErrorsTests.py b/SCons/ErrorsTests.py index 9f2f1a2..9743f0d 100644 --- a/SCons/ErrorsTests.py +++ b/SCons/ErrorsTests.py @@ -95,7 +95,7 @@ class ErrorsTestCase(unittest.TestCase): except SCons.Errors.ExplicitExit as e: assert e.node == "node" - def test_convert_EnvironmentError_to_BuildError(self): + def test_convert_EnvironmentError_to_BuildError(self) -> None: """Test the convert_to_BuildError function on SConsEnvironmentError exceptions. """ @@ -106,7 +106,7 @@ class ErrorsTestCase(unittest.TestCase): assert be.exitstatus == 2 assert be.filename is None - def test_convert_OSError_to_BuildError(self): + def test_convert_OSError_to_BuildError(self) -> None: """Test the convert_to_BuildError function on OSError exceptions. """ diff --git a/SCons/Executor.py b/SCons/Executor.py index 274af6a..153b010 100644 --- a/SCons/Executor.py +++ b/SCons/Executor.py @@ -39,7 +39,7 @@ class Batch: __slots__ = ('targets', 'sources') - def __init__(self, targets=[], sources=[]): + def __init__(self, targets=[], sources=[]) -> None: self.targets = targets self.sources = sources @@ -55,7 +55,7 @@ class TSList(collections.UserList): a list during variable expansion. We're not really using any collections.UserList methods in practice. """ - def __init__(self, func): + def __init__(self, func) -> None: self.func = func def __getattr__(self, attr): nl = self.func() @@ -63,10 +63,10 @@ class TSList(collections.UserList): def __getitem__(self, i): nl = self.func() return nl[i] - def __str__(self): + def __str__(self) -> str: nl = self.func() return str(nl) - def __repr__(self): + def __repr__(self) -> str: nl = self.func() return repr(nl) @@ -74,17 +74,17 @@ class TSObject: """A class that implements $TARGET or $SOURCE expansions by wrapping an Executor method. """ - def __init__(self, func): + def __init__(self, func) -> None: self.func = func def __getattr__(self, attr): n = self.func() return getattr(n, attr) - def __str__(self): + def __str__(self) -> str: n = self.func() if n: return str(n) return '' - def __repr__(self): + def __repr__(self) -> str: n = self.func() if n: return repr(n) @@ -104,7 +104,7 @@ def rfile(node): return rfile() -def execute_nothing(obj, target, kw): +def execute_nothing(obj, target, kw) -> int: return 0 def execute_action_list(obj, target, kw): @@ -138,7 +138,7 @@ def execute_actions_str(obj): env) for action in obj.get_action_list()]) -def execute_null_str(obj): +def execute_null_str(obj) -> str: return '' _execute_str_map = {0 : execute_null_str, @@ -170,7 +170,7 @@ class Executor(object, metaclass=NoSlotsPyPy): '_execute_str') def __init__(self, action, env=None, overridelist=[{}], - targets=[], sources=[], builder_kw={}): + targets=[], sources=[], builder_kw={}) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Executor') self.set_action_list(action) self.pre_actions = [] @@ -202,7 +202,7 @@ class Executor(object, metaclass=NoSlotsPyPy): } return self.lvars - def _get_changes(self): + def _get_changes(self) -> None: cs = [] ct = [] us = [] @@ -383,10 +383,10 @@ class Executor(object, metaclass=NoSlotsPyPy): def __call__(self, target, **kw): return _do_execute_map[self._do_execute](self, target, kw) - def cleanup(self): + def cleanup(self) -> None: self._memo = {} - def add_sources(self, sources): + def add_sources(self, sources) -> None: """Add source files to this Executor's list. This is necessary for "multi" Builders that can be called repeatedly to build up a source file list for a given target.""" @@ -399,7 +399,7 @@ class Executor(object, metaclass=NoSlotsPyPy): def get_sources(self): return self.batches[0].sources - def add_batch(self, targets, sources): + def add_batch(self, targets, sources) -> None: """Add pair of associated target and source to this Executor's list. This is necessary for "batch" Builders that can be called repeatedly to build up a list of matching target and source files that will be @@ -417,18 +417,18 @@ class Executor(object, metaclass=NoSlotsPyPy): msg = "Source `%s' not found, needed by target `%s'." raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0])) - def add_pre_action(self, action): + def add_pre_action(self, action) -> None: self.pre_actions.append(action) - def add_post_action(self, action): + def add_post_action(self, action) -> None: self.post_actions.append(action) # another extra indirection for new-style objects and nullify... - def __str__(self): + def __str__(self) -> str: return _execute_str_map[self._execute_str](self) - def nullify(self): + def nullify(self) -> None: self.cleanup() self._do_execute = 0 self._execute_str = 0 @@ -459,23 +459,23 @@ class Executor(object, metaclass=NoSlotsPyPy): self._memo['get_contents'] = result return result - def get_timestamp(self): + def get_timestamp(self) -> int: """Fetch a time stamp for this Executor. We don't have one, of course (only files do), but this is the interface used by the timestamp module. """ return 0 - def scan_targets(self, scanner): + def scan_targets(self, scanner) -> None: # TODO(batch): scan by batches self.scan(scanner, self.get_all_targets()) - def scan_sources(self, scanner): + def scan_sources(self, scanner) -> None: # TODO(batch): scan by batches if self.batches[0].sources: self.scan(scanner, self.get_all_sources()) - def scan(self, scanner, node_list): + def scan(self, scanner, node_list) -> None: """Scan a list of this Executor's files (targets or sources) for implicit dependencies and update all of the targets with them. This essentially short-circuits an N*M scan of the sources for @@ -553,7 +553,7 @@ _batch_executors = {} def GetBatchExecutor(key): return _batch_executors[key] -def AddBatchExecutor(key, executor): +def AddBatchExecutor(key, executor) -> None: assert key not in _batch_executors _batch_executors[key] = executor @@ -601,7 +601,7 @@ class Null(object, metaclass=NoSlotsPyPy): '_do_execute', '_execute_str') - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Null') self.batches = [Batch(kw['targets'][:], [])] @@ -609,9 +609,9 @@ class Null(object, metaclass=NoSlotsPyPy): return get_NullEnvironment() def get_build_scanner_path(self): return None - def cleanup(self): + def cleanup(self) -> None: pass - def prepare(self): + def prepare(self) -> None: pass def get_unignored_sources(self, *args, **kw): return tuple(()) @@ -629,11 +629,11 @@ class Null(object, metaclass=NoSlotsPyPy): return [] def get_action_side_effects(self): return [] - def __call__(self, *args, **kw): + def __call__(self, *args, **kw) -> int: return 0 - def get_contents(self): + def get_contents(self) -> str: return '' - def _morph(self): + def _morph(self) -> None: """Morph this Null executor to a real Executor object.""" batches = self.batches self.__class__ = Executor @@ -643,13 +643,13 @@ class Null(object, metaclass=NoSlotsPyPy): # The following methods require morphing this Null Executor to a # real Executor object. - def add_pre_action(self, action): + def add_pre_action(self, action) -> None: self._morph() self.add_pre_action(action) - def add_post_action(self, action): + def add_post_action(self, action) -> None: self._morph() self.add_post_action(action) - def set_action_list(self, action): + def set_action_list(self, action) -> None: self._morph() self.set_action_list(action) diff --git a/SCons/ExecutorTests.py b/SCons/ExecutorTests.py index c43c450..24df8e7 100644 --- a/SCons/ExecutorTests.py +++ b/SCons/ExecutorTests.py @@ -27,7 +27,7 @@ import SCons.Executor class MyEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} self._dict.update(kw) def __getitem__(self, key): @@ -36,13 +36,13 @@ class MyEnvironment: d = self._dict.copy() d.update(overrides) return MyEnvironment(**d) - def _update(self, dict): + def _update(self, dict) -> None: self._dict.update(dict) class MyAction: - def __init__(self, actions=['action1', 'action2']): + def __init__(self, actions=['action1', 'action2']) -> None: self.actions = actions - def __call__(self, target, source, env, **kw): + def __call__(self, target, source, env, **kw) -> None: for action in self.actions: action(target, source, env, **kw) def genstring(self, target, source, env): @@ -57,13 +57,13 @@ class MyAction: return [] class MyBuilder: - def __init__(self, env, overrides): + def __init__(self, env, overrides) -> None: self.env = env self.overrides = overrides self.action = MyAction() class MyNode: - def __init__(self, name=None, pre=[], post=[]): + def __init__(self, name=None, pre=[], post=[]) -> None: self.name = name self.implicit = [] self.pre_actions = pre @@ -72,10 +72,10 @@ class MyNode: self.always_build = False self.up_to_date = False - def __str__(self): + def __str__(self) -> str: return self.name - def build(self): + def build(self) -> None: executor = SCons.Executor.Executor(MyAction(self.pre_actions + [self.builder.action] + self.post_actions), @@ -90,7 +90,7 @@ class MyNode: if not scanner: scanner = self.get_env_scanner(env, kw) return [scanner.prefix + str(self)] - def add_to_implicit(self, deps): + def add_to_implicit(self, deps) -> None: self.implicit.extend(deps) def missing(self): return self.missing_val @@ -103,7 +103,7 @@ class MyNode: return self.up_to_date class MyScanner: - def __init__(self, prefix): + def __init__(self, prefix) -> None: self.prefix = prefix def path(self, env, cwd, target, source): return () @@ -131,7 +131,7 @@ class ExecutorTestCase(unittest.TestCase): else: raise Exception("Did not catch expected UserError") - def test__action_list(self): + def test__action_list(self) -> None: """Test the {get,set}_action_list() methods""" x = SCons.Executor.Executor('a', 'e', 'o', 't', ['s1', 's2']) @@ -151,7 +151,7 @@ class ExecutorTestCase(unittest.TestCase): l = x.get_action_list() assert l == ['pre', 'c', 'post'], l - def test_get_build_env(self): + def test_get_build_env(self) -> None: """Test fetching and generating a build environment""" x = SCons.Executor.Executor(MyAction(), MyEnvironment(e=1), [], 't', ['s1', 's2']) @@ -181,7 +181,7 @@ class ExecutorTestCase(unittest.TestCase): assert be['O'] == 'ob3', be['O'] assert be['Y'] == 'yyy', be['Y'] - def test_get_build_scanner_path(self): + def test_get_build_scanner_path(self) -> None: """Test fetching the path for the specified scanner.""" t = MyNode('t') t.cwd = 'here' @@ -192,7 +192,7 @@ class ExecutorTestCase(unittest.TestCase): ['s1', 's2']) class LocalScanner: - def path(self, env, dir, target, source): + def path(self, env, dir, target, source) -> str: target = list(map(str, target)) source = list(map(str, source)) return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source) @@ -201,7 +201,7 @@ class ExecutorTestCase(unittest.TestCase): p = x.get_build_scanner_path(s) assert p == "scanner: sss, here, ['t'], ['s1', 's2']", p - def test_get_kw(self): + def test_get_kw(self) -> None: """Test the get_kw() method""" t = MyNode('t') x = SCons.Executor.Executor(MyAction(), @@ -220,13 +220,13 @@ class ExecutorTestCase(unittest.TestCase): def test__call__(self): """Test calling an Executor""" result = [] - def pre(target, source, env, result=result, **kw): + def pre(target, source, env, result=result, **kw) -> None: result.append('pre') - def action1(target, source, env, result=result, **kw): + def action1(target, source, env, result=result, **kw) -> None: result.append('action1') - def action2(target, source, env, result=result, **kw): + def action2(target, source, env, result=result, **kw) -> None: result.append('action2') - def post(target, source, env, result=result, **kw): + def post(target, source, env, result=result, **kw) -> None: result.append('post') env = MyEnvironment() @@ -240,7 +240,7 @@ class ExecutorTestCase(unittest.TestCase): assert result == ['pre', 'action1', 'action2', 'post'], result del result[:] - def pre_err(target, source, env, result=result, **kw): + def pre_err(target, source, env, result=result, **kw) -> int: result.append('pre_err') return 1 @@ -256,7 +256,7 @@ class ExecutorTestCase(unittest.TestCase): assert result == ['pre_err'], result del result[:] - def test_cleanup(self): + def test_cleanup(self) -> None: """Test cleaning up an Executor""" orig_env = MyEnvironment(e=1) x = SCons.Executor.Executor('b', orig_env, [{'o':1}], @@ -276,7 +276,7 @@ class ExecutorTestCase(unittest.TestCase): be = x.get_build_env() assert be['eee'] == 1, be['eee'] - def test_add_sources(self): + def test_add_sources(self) -> None: """Test adding sources to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) sources = x.get_all_sources() @@ -290,7 +290,7 @@ class ExecutorTestCase(unittest.TestCase): sources = x.get_all_sources() assert sources == ['s1', 's2', 's3', 's4'], sources - def test_get_sources(self): + def test_get_sources(self) -> None: """Test getting sources from an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) sources = x.get_sources() @@ -322,7 +322,7 @@ class ExecutorTestCase(unittest.TestCase): else: raise AssertionError("did not catch expected StopError: %s" % r) - def test_add_pre_action(self): + def test_add_pre_action(self) -> None: """Test adding pre-actions to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) x.add_pre_action('a1') @@ -330,7 +330,7 @@ class ExecutorTestCase(unittest.TestCase): x.add_pre_action('a2') assert x.pre_actions == ['a1', 'a2'] - def test_add_post_action(self): + def test_add_post_action(self) -> None: """Test adding post-actions to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) x.add_post_action('a1') @@ -338,7 +338,7 @@ class ExecutorTestCase(unittest.TestCase): x.add_post_action('a2') assert x.post_actions == ['a1', 'a2'] - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method""" env = MyEnvironment(S='string') @@ -355,12 +355,12 @@ class ExecutorTestCase(unittest.TestCase): 'GENSTRING post t s' assert c == expect, c - def test_nullify(self): + def test_nullify(self) -> None: """Test the nullify() method""" env = MyEnvironment(S='string') result = [] - def action1(target, source, env, result=result, **kw): + def action1(target, source, env, result=result, **kw) -> None: result.append('action1') env = MyEnvironment() @@ -381,7 +381,7 @@ class ExecutorTestCase(unittest.TestCase): s = str(x) assert s == '', s - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the signatures contents""" env = MyEnvironment(C='contents') @@ -396,13 +396,13 @@ class ExecutorTestCase(unittest.TestCase): c = x.get_contents() assert c == b'pre t sgrow t spost t s', c - def test_get_timestamp(self): + def test_get_timestamp(self) -> None: """Test fetching the "timestamp" """ x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) ts = x.get_timestamp() assert ts == 0, ts - def test_scan_targets(self): + def test_scan_targets(self) -> None: """Test scanning the targets for implicit dependencies""" env = MyEnvironment(S='string') t1 = MyNode('t1') @@ -421,7 +421,7 @@ class ExecutorTestCase(unittest.TestCase): assert t1.implicit == ['scanner-t1', 'scanner-t2'], t1.implicit assert t2.implicit == ['scanner-t1', 'scanner-t2'], t2.implicit - def test_scan_sources(self): + def test_scan_sources(self) -> None: """Test scanning the sources for implicit dependencies""" env = MyEnvironment(S='string') t1 = MyNode('t1') @@ -440,7 +440,7 @@ class ExecutorTestCase(unittest.TestCase): assert t1.implicit == ['scanner-s1', 'scanner-s2'], t1.implicit assert t2.implicit == ['scanner-s1', 'scanner-s2'], t2.implicit - def test_get_unignored_sources(self): + def test_get_unignored_sources(self) -> None: """Test fetching the unignored source list""" env = MyEnvironment() s1 = MyNode('s1') @@ -457,7 +457,7 @@ class ExecutorTestCase(unittest.TestCase): r = x.get_unignored_sources(None, [s1, s3]) assert r == [s2], list(map(str, r)) - def test_changed_sources_for_alwaysBuild(self): + def test_changed_sources_for_alwaysBuild(self) -> None: """ Ensure if a target is marked always build that the sources are always marked changed sources :return: diff --git a/SCons/Memoize.py b/SCons/Memoize.py index b02c144..c594348 100644 --- a/SCons/Memoize.py +++ b/SCons/Memoize.py @@ -111,7 +111,7 @@ class Counter: fill in the correct class name and method name that represents the name of the function being counted. """ - def __init__(self, cls_name, method_name): + def __init__(self, cls_name, method_name) -> None: """ """ self.cls_name = cls_name @@ -120,7 +120,7 @@ class Counter: self.miss = 0 def key(self): return self.cls_name+'.'+self.method_name - def display(self): + def display(self) -> None: print(" {:7d} hits {:7d} misses {}()".format(self.hit, self.miss, self.key())) def __eq__(self, other): try: @@ -136,7 +136,7 @@ class CountValue(Counter): the class's methods that memoizes its return value by simply storing the return value in its _memo dictionary. """ - def count(self, *args, **kw): + def count(self, *args, **kw) -> None: """ Counts whether the memoized value has already been set (a hit) or not (a miss). """ @@ -156,12 +156,12 @@ class CountDict(Counter): indexed by some key that can be computed from one or more of its input arguments. """ - def __init__(self, cls_name, method_name, keymaker): + def __init__(self, cls_name, method_name, keymaker) -> None: """ """ super().__init__(cls_name, method_name) self.keymaker = keymaker - def count(self, *args, **kw): + def count(self, *args, **kw) -> None: """ Counts whether the computed key value is already present in the memoization dictionary (a hit) or not (a miss). """ @@ -177,7 +177,7 @@ class CountDict(Counter): else: self.miss = self.miss + 1 -def Dump(title=None): +def Dump(title=None) -> None: """ Dump the hit/miss count for all the counters collected so far. """ @@ -186,7 +186,7 @@ def Dump(title=None): for counter in sorted(CounterList): CounterList[counter].display() -def EnableMemoization(): +def EnableMemoization() -> None: global use_memoizer use_memoizer = 1 diff --git a/SCons/MemoizeTests.py b/SCons/MemoizeTests.py index 7830d99..825256c 100644 --- a/SCons/MemoizeTests.py +++ b/SCons/MemoizeTests.py @@ -29,7 +29,7 @@ import SCons.Memoize SCons.Memoize.EnableMemoization() class FakeObject: - def __init__(self): + def __init__(self) -> None: self._memo = {} def _dict_key(self, argument): @@ -74,7 +74,7 @@ class FakeObject: return SCons.Memoize.CounterList.get(self.__class__.__name__+'.'+name, None) class Returner: - def __init__(self, result): + def __init__(self, result) -> None: self.result = result self.calls = 0 def __call__(self, *args, **kw): @@ -84,7 +84,7 @@ class Returner: class CountDictTestCase(unittest.TestCase): - def test___call__(self): + def test___call__(self) -> None: """Calling a Memoized dict method """ obj = FakeObject() @@ -126,7 +126,7 @@ class CountDictTestCase(unittest.TestCase): class CountValueTestCase(unittest.TestCase): - def test___call__(self): + def test___call__(self) -> None: """Calling a Memoized value method """ obj = FakeObject() diff --git a/SCons/Node/Alias.py b/SCons/Node/Alias.py index 1125c22..55c4795 100644 --- a/SCons/Node/Alias.py +++ b/SCons/Node/Alias.py @@ -78,7 +78,7 @@ class AliasNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -98,7 +98,7 @@ class Alias(SCons.Node.Node): NodeInfo = AliasNodeInfo BuildInfo = AliasBuildInfo - def __init__(self, name): + def __init__(self, name) -> None: super().__init__() self.name = name self.changed_since_last_build = 1 @@ -107,16 +107,16 @@ class Alias(SCons.Node.Node): def str_for_display(self): return '"' + self.__str__() + '"' - def __str__(self): + def __str__(self) -> str: return self.name - def make_ready(self): + def make_ready(self) -> None: self.get_csig() really_build = SCons.Node.Node.build is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir): + def is_under(self, dir) -> int: # Make Alias nodes get built regardless of # what directory scons was run from. Alias nodes # are outside the filesystem: @@ -128,7 +128,7 @@ class Alias(SCons.Node.Node): childsigs = [n.get_csig() for n in self.children()] return ''.join(childsigs) - def sconsign(self): + def sconsign(self) -> None: """An Alias is not recorded in .sconsign files""" pass @@ -136,11 +136,11 @@ class Alias(SCons.Node.Node): # # - def build(self): + def build(self) -> None: """A "builder" for aliases.""" pass - def convert(self): + def convert(self) -> None: try: del self.builder except AttributeError: pass self.reset_executor() diff --git a/SCons/Node/AliasTests.py b/SCons/Node/AliasTests.py index 14662fd..78138f9 100644 --- a/SCons/Node/AliasTests.py +++ b/SCons/Node/AliasTests.py @@ -28,13 +28,13 @@ import SCons.Node.Alias class AliasTestCase(unittest.TestCase): - def test_AliasNameSpace(self): + def test_AliasNameSpace(self) -> None: """Test creating an Alias name space """ ans = SCons.Node.Alias.AliasNameSpace() assert ans is not None, ans - def test_ANS_Alias(self): + def test_ANS_Alias(self) -> None: """Test the Alias() factory """ ans = SCons.Node.Alias.AliasNameSpace() @@ -45,11 +45,11 @@ class AliasTestCase(unittest.TestCase): a2 = ans.Alias('a1') assert a1 is a2, (a1, a2) - def test_get_contents(self): + def test_get_contents(self) -> None: """Test the get_contents() method """ class DummyNode: - def __init__(self, contents): + def __init__(self, contents) -> None: self.contents = contents def get_csig(self): return self.contents @@ -66,7 +66,7 @@ class AliasTestCase(unittest.TestCase): c = a.get_contents() assert c == 'onetwothree', c - def test_lookup(self): + def test_lookup(self) -> None: """Test the lookup() method """ ans = SCons.Node.Alias.AliasNameSpace() @@ -81,7 +81,7 @@ class AliasTestCase(unittest.TestCase): a = ans.lookup('a2') assert a is None, a - def test_Alias(self): + def test_Alias(self) -> None: """Test creating an Alias() object """ a1 = SCons.Node.Alias.Alias('a') @@ -94,14 +94,14 @@ class AliasTestCase(unittest.TestCase): assert a1.name == a2.name class AliasNodeInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test AliasNodeInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') ni = SCons.Node.Alias.AliasNodeInfo() class AliasBuildInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test AliasBuildInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 67e1ff6..58b8a5c 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -81,11 +81,11 @@ class EntryProxyAttributeError(AttributeError): An AttributeError subclass for recording and displaying the name of the underlying Entry involved in an AttributeError exception. """ - def __init__(self, entry_proxy, attribute): + def __init__(self, entry_proxy, attribute) -> None: super().__init__() self.entry_proxy = entry_proxy self.attribute = attribute - def __str__(self): + def __str__(self) -> str: entry = self.entry_proxy.get() fmt = "%s instance %s has no attribute %s" return fmt % (entry.__class__.__name__, @@ -116,7 +116,7 @@ default_max_drift = 2*24*60*60 # Save_Strings = None -def save_strings(val): +def save_strings(val) -> None: global Save_Strings Save_Strings = val @@ -130,7 +130,7 @@ def save_strings(val): do_splitdrive = None _my_splitdrive =None -def initialize_do_splitdrive(): +def initialize_do_splitdrive() -> None: global do_splitdrive global has_unc drive, path = os.path.splitdrive('X:/foo') @@ -231,7 +231,7 @@ needs_normpath_match = needs_normpath_check.match # TODO: See if theres a reasonable way to enable using links on win32/64 if hasattr(os, 'link') and sys.platform != 'win32': - def _hardlink_func(fs, src, dst): + def _hardlink_func(fs, src, dst) -> None: # If the source is a symlink, we can't just hard-link to it # because a relative symlink may point somewhere completely # different. We must disambiguate the symlink and then @@ -247,12 +247,12 @@ else: _hardlink_func = None if hasattr(os, 'symlink') and sys.platform != 'win32': - def _softlink_func(fs, src, dst): + def _softlink_func(fs, src, dst) -> None: fs.symlink(src, dst) else: _softlink_func = None -def _copy_func(fs, src, dest): +def _copy_func(fs, src, dest) -> None: shutil.copy2(src, dest) st = fs.stat(src) fs.chmod(dest, stat.S_IMODE(st.st_mode) | stat.S_IWRITE) @@ -286,7 +286,7 @@ def set_duplicate(duplicate): if link_dict[func]: Link_Funcs.append(link_dict[func]) -def LinkFunc(target, source, env): +def LinkFunc(target, source, env) -> int: """ Relative paths cause problems with symbolic links, so we use absolute paths, which may be a problem for people @@ -321,19 +321,19 @@ def LinkFunc(target, source, env): return 0 Link = SCons.Action.Action(LinkFunc, None) -def LocalString(target, source, env): +def LocalString(target, source, env) -> str: return 'Local copy of %s from %s' % (target[0], source[0]) LocalCopy = SCons.Action.Action(LinkFunc, LocalString) -def UnlinkFunc(target, source, env): +def UnlinkFunc(target, source, env) -> int: t = target[0] t.fs.unlink(t.get_abspath()) return 0 Unlink = SCons.Action.Action(UnlinkFunc, None) -def MkdirFunc(target, source, env): +def MkdirFunc(target, source, env) -> int: t = target[0] # This os.path.exists test looks redundant, but it's possible # when using Install() to install multiple dirs outside the @@ -385,7 +385,7 @@ class DiskChecker: This Class will hold functions to determine what this particular disk checking implementation should do when enabled or disabled. """ - def __init__(self, disk_check_type, do_check_function, ignore_check_function): + def __init__(self, disk_check_type, do_check_function, ignore_check_function) -> None: self.disk_check_type = disk_check_type self.do_check_function = do_check_function self.ignore_check_function = ignore_check_function @@ -394,7 +394,7 @@ class DiskChecker: def __call__(self, *args, **kw): return self.func(*args, **kw) - def enable(self, disk_check_type_list): + def enable(self, disk_check_type_list) -> None: """ If the current object's disk_check_type matches any in the list passed :param disk_check_type_list: List of disk checks to enable @@ -423,7 +423,7 @@ def do_diskcheck_match(node, predicate, errorfmt): raise TypeError(errorfmt % node.get_abspath()) -def ignore_diskcheck_match(node, predicate, errorfmt): +def ignore_diskcheck_match(node, predicate, errorfmt) -> None: pass @@ -434,7 +434,7 @@ diskcheckers = [ ] -def set_diskcheck(enabled_checkers): +def set_diskcheck(enabled_checkers) -> None: for dc in diskcheckers: dc.enable(enabled_checkers) @@ -584,7 +584,7 @@ class Base(SCons.Node.Node): '_proxy', '_func_sconsign'] - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: """Initialize a generic Node.FS.Base object. Call the superclass initialization, take care of setting up @@ -663,7 +663,7 @@ class Base(SCons.Node.Node): raise AttributeError("%r object has no attribute %r" % (self.__class__, attr)) - def __str__(self): + def __str__(self) -> str: """A Node.FS.Base object's string representation is its path name.""" global Save_Strings @@ -775,7 +775,7 @@ class Base(SCons.Node.Node): st = self.lstat() return st is not None and stat.S_ISLNK(st.st_mode) else: - def islink(self): + def islink(self) -> bool: return False # no symlinks def is_under(self, dir): @@ -784,7 +784,7 @@ class Base(SCons.Node.Node): else: return self.dir.is_under(dir) - def set_local(self): + def set_local(self) -> None: self._local = 1 def srcnode(self): @@ -817,7 +817,7 @@ class Base(SCons.Node.Node): pathname += p.dirname return pathname + path_elems[-1].name - def set_src_builder(self, builder): + def set_src_builder(self, builder) -> None: """Set the source code builder for this node.""" self.sbuilder = builder if not self.has_builder(): @@ -951,7 +951,7 @@ class Base(SCons.Node.Node): self._memo['rentry'] = result return result - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): return [] # Dict that provides a simple backward compatibility @@ -989,12 +989,12 @@ class Entry(Base): 'released_target_info', 'contentsig'] - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: super().__init__(name, directory, fs) self._func_exists = 3 self._func_get_contents = 1 - def diskcheck_match(self): + def diskcheck_match(self) -> None: pass def disambiguate(self, must_exist=None): @@ -1066,7 +1066,7 @@ class Entry(Base): else: return self.get_text_contents() - def must_be_same(self, klass): + def must_be_same(self, klass) -> None: """Called to make sure a Node is a Dir. Since we're an Entry, we can morph into one.""" if self.__class__ is not klass: @@ -1097,7 +1097,7 @@ class Entry(Base): def new_ninfo(self): return self.disambiguate().new_ninfo() - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): return self.disambiguate()._glob1(pattern, ondisk, source, strings) def get_subst_proxy(self): @@ -1162,10 +1162,10 @@ class LocalFS: def scandir(self, path): return os.scandir(path) - def makedirs(self, path, mode=0o777, exist_ok=False): + def makedirs(self, path, mode: int=0o777, exist_ok: bool=False): return os.makedirs(path, mode=mode, exist_ok=exist_ok) - def mkdir(self, path, mode=0o777): + def mkdir(self, path, mode: int=0o777): return os.mkdir(path, mode=mode) def rename(self, old, new): @@ -1190,7 +1190,7 @@ class LocalFS: else: - def islink(self, path): + def islink(self, path) -> bool: return False # no symlinks if hasattr(os, 'readlink'): @@ -1200,13 +1200,13 @@ class LocalFS: else: - def readlink(self, file): + def readlink(self, file) -> str: return '' class FS(LocalFS): - def __init__(self, path = None): + def __init__(self, path = None) -> None: """Initialize the Node.FS subsystem. The supplied path is the top of the source tree, where we @@ -1238,13 +1238,13 @@ class FS(LocalFS): DirNodeInfo.fs = self FileNodeInfo.fs = self - def set_SConstruct_dir(self, dir): + def set_SConstruct_dir(self, dir) -> None: self.SConstruct_dir = dir def get_max_drift(self): return self.max_drift - def set_max_drift(self, max_drift): + def set_max_drift(self, max_drift) -> None: self.max_drift = max_drift def getcwd(self): @@ -1253,7 +1253,7 @@ class FS(LocalFS): else: return "" - def chdir(self, dir, change_os_dir=False): + def chdir(self, dir, change_os_dir: bool=False): """Change the current working directory for lookups. If change_os_dir is true, we will also change the "real" cwd to match. @@ -1285,7 +1285,7 @@ class FS(LocalFS): self.Root[''] = root return root - def _lookup(self, p, directory, fsclass, create=1): + def _lookup(self, p, directory, fsclass, create: int=1): """ The generic entry point for Node lookup with user-supplied data. @@ -1421,7 +1421,7 @@ class FS(LocalFS): return root._lookup_abs(p, fsclass, create) - def Entry(self, name, directory = None, create = 1): + def Entry(self, name, directory = None, create: int = 1): """Look up or create a generic Entry node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory @@ -1430,7 +1430,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, Entry, create) - def File(self, name, directory = None, create = 1): + def File(self, name, directory = None, create: int = 1): """Look up or create a File node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, @@ -1442,7 +1442,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, File, create) - def Dir(self, name, directory = None, create = True): + def Dir(self, name, directory = None, create: bool = True): """Look up or create a Dir node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, @@ -1454,7 +1454,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, Dir, create) - def VariantDir(self, variant_dir, src_dir, duplicate=1): + def VariantDir(self, variant_dir, src_dir, duplicate: int=1): """Link the supplied variant directory to the source directory for purposes of building files.""" @@ -1470,7 +1470,7 @@ class FS(LocalFS): raise SCons.Errors.UserError("'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir)) variant_dir.link(src_dir, duplicate) - def Repository(self, *dirs): + def Repository(self, *dirs) -> None: """Specify Repository directories to search.""" for d in dirs: if not isinstance(d, SCons.Node.Node): @@ -1521,7 +1521,7 @@ class FS(LocalFS): message = fmt % ' '.join(map(str, targets)) return targets, message - def Glob(self, pathname, ondisk=True, source=True, strings=False, exclude=None, cwd=None): + def Glob(self, pathname, ondisk: bool=True, source: bool=True, strings: bool=False, exclude=None, cwd=None): """ Globs @@ -1555,7 +1555,7 @@ class DirBuildInfo(SCons.Node.BuildInfoBase): glob_magic_check = re.compile('[*?[]') -def has_glob_magic(s): +def has_glob_magic(s) -> bool: return glob_magic_check.search(s) is not None class Dir(Base): @@ -1580,12 +1580,12 @@ class Dir(Base): NodeInfo = DirNodeInfo BuildInfo = DirBuildInfo - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Dir') super().__init__(name, directory, fs) self._morph() - def _morph(self): + def _morph(self) -> None: """Turn a file system Node (either a freshly initialized directory object or a separate Entry object) into a proper directory object. @@ -1649,11 +1649,11 @@ class Dir(Base): l.insert(0, a) self.get_executor().set_action_list(l) - def diskcheck_match(self): + def diskcheck_match(self) -> None: diskcheck_match(self, self.isfile, "File %s found where directory expected.") - def __clearRepositoryCache(self, duplicate=None): + def __clearRepositoryCache(self, duplicate=None) -> None: """Called when we change the repository(ies) for a directory. This clears any cached information that is invalidated by changing the repository.""" @@ -1671,7 +1671,7 @@ class Dir(Base): if duplicate is not None: node.duplicate = duplicate - def __resetDuplicate(self, node): + def __resetDuplicate(self, node) -> None: if node != self: node.duplicate = node.get_dir().duplicate @@ -1682,7 +1682,7 @@ class Dir(Base): """ return self.fs.Entry(name, self) - def Dir(self, name, create=True): + def Dir(self, name, create: bool=True): """ Looks up or creates a directory node named 'name' relative to this directory. @@ -1696,7 +1696,7 @@ class Dir(Base): """ return self.fs.File(name, self) - def link(self, srcdir, duplicate): + def link(self, srcdir, duplicate) -> None: """Set this directory as the variant directory for the supplied source directory.""" self.srcdir = srcdir @@ -1734,7 +1734,7 @@ class Dir(Base): return result - def addRepository(self, dir): + def addRepository(self, dir) -> None: if dir != self and dir not in self.repositories: self.repositories.append(dir) dir._tpath = '.' @@ -1834,10 +1834,10 @@ class Dir(Base): # Taskmaster interface subsystem # - def prepare(self): + def prepare(self) -> None: pass - def build(self, **kw): + def build(self, **kw) -> None: """A null "builder" for directories.""" global MkdirBuilder if self.builder is not MkdirBuilder: @@ -1911,10 +1911,10 @@ class Dir(Base): contents = self.get_contents() return hash_signature(contents) - def do_duplicate(self, src): + def do_duplicate(self, src) -> None: pass - def is_up_to_date(self): + def is_up_to_date(self) -> int: """If any child is not up-to-date, then this directory isn't, either.""" if self.builder is not MkdirBuilder and not self.exists(): @@ -2145,7 +2145,7 @@ class Dir(Base): return None return node - def walk(self, func, arg): + def walk(self, func, arg) -> None: """ Walk this directory tree by calling the specified function for each directory in the tree. @@ -2171,7 +2171,7 @@ class Dir(Base): for dirname in [n for n in names if isinstance(entries[n], Dir)]: entries[dirname].walk(func, arg) - def glob(self, pathname, ondisk=True, source=False, strings=False, exclude=None) -> list: + def glob(self, pathname, ondisk: bool=True, source: bool=False, strings: bool=False, exclude=None) -> list: """Returns a list of Nodes (or strings) matching a pathname pattern. Pathname patterns follow POSIX shell syntax:: @@ -2234,7 +2234,7 @@ class Dir(Base): result = [x for x in result if not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes))] return sorted(result, key=lambda a: str(a)) - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): """ Globs for and returns a list of entry names matching a single pattern in this directory. @@ -2313,7 +2313,7 @@ class RootDir(Dir): __slots__ = ('_lookupDict', 'abspath', 'path') - def __init__(self, drive, fs): + def __init__(self, drive, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir') SCons.Node.Node.__init__(self) @@ -2371,7 +2371,7 @@ class RootDir(Dir): if not has_unc: self._lookupDict['//'] = self - def _morph(self): + def _morph(self) -> None: """Turn a file system Node (either a freshly initialized directory object or a separate Entry object) into a proper directory object. @@ -2412,12 +2412,12 @@ class RootDir(Dir): self.get_executor().set_action_list(l) - def must_be_same(self, klass): + def must_be_same(self, klass) -> None: if klass is Dir: return Base.must_be_same(self, klass) - def _lookup_abs(self, p, klass, create=True): + def _lookup_abs(self, p, klass, create: bool=True): """ Fast (?) lookup of a *normalized* absolute path. @@ -2459,7 +2459,7 @@ class RootDir(Dir): result.must_be_same(klass) return result - def __str__(self): + def __str__(self) -> str: return self._abspath def entry_abspath(self, name): @@ -2474,7 +2474,7 @@ class RootDir(Dir): def entry_tpath(self, name): return self._tpath + name - def is_under(self, dir): + def is_under(self, dir) -> int: if self is dir: return 1 else: @@ -2531,7 +2531,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -2544,7 +2544,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): def __eq__(self, other): return self.csig == other.csig and self.timestamp == other.timestamp and self.size == other.size - def __ne__(self, other): + def __ne__(self, other) -> bool: return not self.__eq__(other) @@ -2577,7 +2577,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): return super().__setattr__(key, value) - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: """ Converts this FileBuildInfo object for writing to a .sconsign file @@ -2604,7 +2604,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): else: setattr(self, attr, list(map(node_to_str, val))) - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: """ Converts a newly-read FileBuildInfo object for in-SCons use @@ -2613,7 +2613,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): """ pass - def prepare_dependencies(self): + def prepare_dependencies(self) -> None: """ Prepares a FileBuildInfo object for explaining what changed @@ -2642,7 +2642,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): nodes.append(s) setattr(self, nattr, nodes) - def format(self, names=0): + def format(self, names: int=0): result = [] bkids = self.bsources + self.bdepends + self.bimplicit bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs @@ -2680,11 +2680,11 @@ class File(Base): # Although the command-line argument is in kilobytes, this is in bytes. hash_chunksize = 65536 - def diskcheck_match(self): + def diskcheck_match(self) -> None: diskcheck_match(self, self.isdir, "Directory %s found where file expected.") - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.File') super().__init__(name, directory, fs) self._morph() @@ -2694,7 +2694,7 @@ class File(Base): the directory of this file.""" return self.dir.Entry(name) - def Dir(self, name, create=True): + def Dir(self, name, create: bool=True): """Create a directory node named 'name' relative to the directory of this file.""" return self.dir.Dir(name, create=create) @@ -2709,7 +2709,7 @@ class File(Base): the directory of this file.""" return self.dir.File(name) - def _morph(self): + def _morph(self) -> None: """Turn a file system node into a File object.""" self.scanner_paths = {} if not hasattr(self, '_local'): @@ -2997,12 +2997,12 @@ class File(Base): return result - def _createDir(self): + def _createDir(self) -> None: # ensure that the directories for this node are # created. self.dir._create() - def push_to_cache(self): + def push_to_cache(self) -> None: """Try to push the node into a cache """ # This should get called before the Nodes' .built() method is @@ -3033,7 +3033,7 @@ class File(Base): return None return self.get_build_env().get_CacheDir().retrieve(self) - def visited(self): + def visited(self) -> None: if self.exists() and self.executor is not None: self.get_build_env().get_CacheDir().push_if_forced(self) @@ -3056,7 +3056,7 @@ class File(Base): SCons.Node.store_info_map[self.store_info](self) - def release_target_info(self): + def release_target_info(self) -> None: """Called just after this node has been marked up-to-date or was built completely. @@ -3123,7 +3123,7 @@ class File(Base): self.builder_set(scb) return scb - def has_src_builder(self): + def has_src_builder(self) -> bool: """Return whether this Node has a source builder or not. If this Node doesn't have an explicit source code builder, this @@ -3159,7 +3159,7 @@ class File(Base): # Taskmaster interface subsystem # - def make_ready(self): + def make_ready(self) -> None: self.has_src_builder() self.get_binfo() @@ -3282,11 +3282,11 @@ class File(Base): # DECISION SUBSYSTEM # - def builder_set(self, builder): + def builder_set(self, builder) -> None: SCons.Node.Node.builder_set(self, builder) self.changed_since_last_build = 5 - def built(self): + def built(self) -> None: """Called just after this File node is successfully built. Just like for 'release_target_info' we try to release @@ -3310,7 +3310,7 @@ class File(Base): self.scanner_paths = None - def changed(self, node=None, allowcache=False): + def changed(self, node=None, allowcache: bool=False): """ Returns if the node is up-to-date with respect to the BuildInfo stored last time it was built. @@ -3728,7 +3728,7 @@ class FileFinder: """ """ - def __init__(self): + def __init__(self) -> None: self._memo = {} def filedir_lookup(self, p, fd=None): @@ -3826,7 +3826,7 @@ class FileFinder: find_file = FileFinder().find_file -def invalidate_node_memos(targets): +def invalidate_node_memos(targets) -> None: """ Invalidate the memoized values of all Nodes (files or directories) that are associated with the given entries. Has been added to diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py index f3aface..e2eb0af 100644 --- a/SCons/Node/FSTests.py +++ b/SCons/Node/FSTests.py @@ -44,7 +44,7 @@ scanner_count = 0 class Scanner: - def __init__(self, node=None): + def __init__(self, node=None) -> None: global scanner_count scanner_count = scanner_count + 1 self.hash = scanner_count @@ -67,7 +67,7 @@ class Scanner: class Environment: - def __init__(self): + def __init__(self) -> None: self.scanner = Scanner() def Dictionary(self, *args): @@ -82,27 +82,27 @@ class Environment: def Override(self, overrides): return self - def _update(self, dict): + def _update(self, dict) -> None: pass class Action: - def __call__(self, targets, sources, env, **kw): + def __call__(self, targets, sources, env, **kw) -> int: global built_it if kw.get('execute', 1): built_it = 1 return 0 - def show(self, string): + def show(self, string) -> None: pass def get_contents(self, target, source, env): return bytearray("", 'utf-8') - def genstring(self, target, source, env): + def genstring(self, target, source, env) -> str: return "" - def strfunction(self, targets, sources, env): + def strfunction(self, targets, sources, env) -> str: return "" def get_implicit_deps(self, target, source, env): @@ -110,7 +110,7 @@ class Action: class Builder: - def __init__(self, factory, action=Action()): + def __init__(self, factory, action=Action()) -> None: self.factory = factory self.env = Environment() self.overrides = {} @@ -126,19 +126,19 @@ class Builder: class _tempdirTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.save_cwd = os.getcwd() self.test = TestCmd(workdir='') # FS doesn't like the cwd to be something other than its root. os.chdir(self.test.workpath("")) self.fs = SCons.Node.FS.FS() - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.save_cwd) class VariantDirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test variant dir functionality""" test = TestCmd(workdir='') @@ -316,10 +316,10 @@ class VariantDirTestCase(unittest.TestCase): f9 = fs.File('build/var2/new_dir/test9.out') class MkdirAction(Action): - def __init__(self, dir_made): + def __init__(self, dir_made) -> None: self.dir_made = dir_made - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> None: if executor: target = executor.get_all_targets() source = executor.get_all_sources() @@ -328,7 +328,7 @@ class VariantDirTestCase(unittest.TestCase): save_Link = SCons.Node.FS.Link link_made = [] - def link_func(target, source, env, link_made=link_made): + def link_func(target, source, env, link_made=link_made) -> None: link_made.append(target) SCons.Node.FS.Link = link_func @@ -458,7 +458,7 @@ class VariantDirTestCase(unittest.TestCase): class LinkSimulator: """A class to intercept os.[sym]link() calls and track them.""" - def __init__(self, duplicate, link, symlink, copy): + def __init__(self, duplicate, link, symlink, copy) -> None: self.duplicate = duplicate self.have = {'hard': link, 'soft': symlink, 'copy': copy} @@ -481,7 +481,7 @@ class VariantDirTestCase(unittest.TestCase): "instead of soft" % next_link raise OSError("Simulating symlink creation error.") - def copy(self, src, dest): + def copy(self, src, dest) -> None: next_link = self.links_to_be_called.pop(0) assert next_link == "copy", \ "Wrong link order: expected %s to be called " \ @@ -631,7 +631,7 @@ class VariantDirTestCase(unittest.TestCase): class BaseTestCase(_tempdirTestCase): - def test_stat(self): + def test_stat(self) -> None: """Test the Base.stat() method""" test = self.test test.write("e1", "e1\n") @@ -645,7 +645,7 @@ class BaseTestCase(_tempdirTestCase): s = e2.stat() assert s is None, s - def test_getmtime(self): + def test_getmtime(self) -> None: """Test the Base.getmtime() method""" test = self.test test.write("file", "file\n") @@ -658,7 +658,7 @@ class BaseTestCase(_tempdirTestCase): mtime = file.getmtime() assert mtime is None, mtime - def test_getsize(self): + def test_getsize(self) -> None: """Test the Base.getsize() method""" test = self.test test.write("file", "file\n") @@ -672,7 +672,7 @@ class BaseTestCase(_tempdirTestCase): size = file.getsize() assert size is None, size - def test_isdir(self): + def test_isdir(self) -> None: """Test the Base.isdir() method""" test = self.test test.subdir('dir') @@ -688,7 +688,7 @@ class BaseTestCase(_tempdirTestCase): nonexistent = fs.Entry('nonexistent') assert not nonexistent.isdir() - def test_isfile(self): + def test_isfile(self) -> None: """Test the Base.isfile() method""" test = self.test test.subdir('dir') @@ -706,7 +706,7 @@ class BaseTestCase(_tempdirTestCase): @unittest.skipUnless(sys.platform != 'win32' and hasattr(os, 'symlink'), "symlink is not used on Windows") - def test_islink(self): + def test_islink(self) -> None: """Test the Base.islink() method""" test = self.test test.subdir('dir') @@ -728,27 +728,27 @@ class BaseTestCase(_tempdirTestCase): class DirNodeInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test DirNodeInfo initialization""" ddd = self.fs.Dir('ddd') ni = SCons.Node.FS.DirNodeInfo() class DirBuildInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test DirBuildInfo initialization""" ddd = self.fs.Dir('ddd') bi = SCons.Node.FS.DirBuildInfo() class FileNodeInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test FileNodeInfo initialization""" fff = self.fs.File('fff') ni = SCons.Node.FS.FileNodeInfo() assert isinstance(ni, SCons.Node.FS.FileNodeInfo) - def test_update(self): + def test_update(self) -> None: """Test updating a File.NodeInfo with on-disk information""" test = self.test fff = self.fs.File('fff') @@ -788,31 +788,31 @@ class FileNodeInfoTestCase(_tempdirTestCase): class FileBuildInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test File.BuildInfo initialization""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert bi, bi - def test_convert_to_sconsign(self): + def test_convert_to_sconsign(self) -> None: """Test converting to .sconsign file format""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_to_sconsign') - def test_convert_from_sconsign(self): + def test_convert_from_sconsign(self) -> None: """Test converting from .sconsign file format""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_from_sconsign') - def test_prepare_dependencies(self): + def test_prepare_dependencies(self) -> None: """Test that we have a prepare_dependencies() method""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() bi.prepare_dependencies() - def test_format(self): + def test_format(self) -> None: """Test the format() method""" f1 = self.fs.File('f1') bi1 = SCons.Node.FS.FileBuildInfo() @@ -850,7 +850,7 @@ class FileBuildInfoTestCase(_tempdirTestCase): class FSTestCase(_tempdirTestCase): - def test_needs_normpath(self): + def test_needs_normpath(self) -> None: """Test the needs_normpath Regular expression This test case verifies that the regular expression used to @@ -1048,7 +1048,7 @@ class FSTestCase(_tempdirTestCase): drive, path = os.path.splitdrive(os.getcwd()) - def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive): + def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1194,7 +1194,7 @@ class FSTestCase(_tempdirTestCase): f1.build() assert built_it - def match(path, expect): + def match(path, expect) -> None: expect = expect.replace('/', os.sep) assert path == expect, "path %s != expected %s" % (path, expect) @@ -1569,7 +1569,7 @@ class FSTestCase(_tempdirTestCase): f.get_string(0) assert f.get_string(1) == 'baz', f.get_string(1) - def test_drive_letters(self): + def test_drive_letters(self) -> None: """Test drive-letter look-ups""" test = self.test @@ -1608,7 +1608,7 @@ class FSTestCase(_tempdirTestCase): if os.sep != '/': seps = seps + ['/'] - def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs): + def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1670,7 +1670,7 @@ class FSTestCase(_tempdirTestCase): os.sep = save_os_sep SCons.Node.FS.initialize_do_splitdrive() - def test_unc_path(self): + def test_unc_path(self) -> None: """Test UNC path look-ups""" test = self.test @@ -1719,7 +1719,7 @@ class FSTestCase(_tempdirTestCase): if os.sep != '/': seps = seps + ['/'] - def _do_Dir_test(lpath, path, up_path, sep, fileSys=fs): + def _do_Dir_test(lpath, path, up_path, sep, fileSys=fs) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1784,7 +1784,7 @@ class FSTestCase(_tempdirTestCase): os.sep = save_os_sep SCons.Node.FS.initialize_do_splitdrive() - def test_target_from_source(self): + def test_target_from_source(self) -> None: """Test the method for generating target nodes from sources""" fs = self.fs @@ -1813,7 +1813,7 @@ class FSTestCase(_tempdirTestCase): assert str(t) == 'pre-eee-suf', str(t) assert t.__class__ == SCons.Node.FS.Entry - def test_same_name(self): + def test_same_name(self) -> None: """Test that a local same-named file isn't found for a Dir lookup""" test = self.test fs = self.fs @@ -1825,7 +1825,7 @@ class FSTestCase(_tempdirTestCase): fs.chdir(subdir, change_os_dir=True) self.fs._lookup('#build/file', subdir, SCons.Node.FS.File) - def test_above_root(self): + def test_above_root(self) -> None: """Testing looking up a path above the root directory""" test = self.test fs = self.fs @@ -1836,7 +1836,7 @@ class FSTestCase(_tempdirTestCase): above_path = os.path.join(*['..'] * len(dirs) + ['above']) above = d2.Dir(above_path) - def test_lookup_abs(self): + def test_lookup_abs(self) -> None: """Exercise the _lookup_abs function""" test = self.test fs = self.fs @@ -1846,7 +1846,7 @@ class FSTestCase(_tempdirTestCase): assert d.__class__ == SCons.Node.FS.Dir, str(d.__class__) @unittest.skipUnless(sys.platform == "win32", "requires Windows") - def test_lookup_uncpath(self): + def test_lookup_uncpath(self) -> None: """Testing looking up a UNC path on Windows""" test = self.test fs = self.fs @@ -1858,13 +1858,13 @@ class FSTestCase(_tempdirTestCase): 'UNC path %s got looked up as %s' % (path, f) @unittest.skipUnless(sys.platform.startswith == "win32", "requires Windows") - def test_unc_drive_letter(self): + def test_unc_drive_letter(self) -> None: """Test drive-letter lookup for windows UNC-style directories""" share = self.fs.Dir(r'\\SERVER\SHARE\Directory') assert str(share) == r'\\SERVER\SHARE\Directory', str(share) @unittest.skipUnless(sys.platform == "win32", "requires Windows") - def test_UNC_dirs_2689(self): + def test_UNC_dirs_2689(self) -> None: """Test some UNC dirs that printed incorrectly and/or caused infinite recursion errors prior to r5180 (SCons 2.1).""" fs = self.fs @@ -1873,7 +1873,7 @@ class FSTestCase(_tempdirTestCase): p = fs.Dir(r"\\\computername\sharename").get_abspath() assert p == r"\\computername\sharename", p - def test_rel_path(self): + def test_rel_path(self) -> None: """Test the rel_path() method""" test = self.test fs = self.fs @@ -1956,7 +1956,7 @@ class FSTestCase(_tempdirTestCase): failed = failed + 1 assert failed == 0, "%d rel_path() cases failed" % failed - def test_proxy(self): + def test_proxy(self) -> None: """Test a Node.FS object wrapped in a proxy instance""" f1 = self.fs.File('fff') @@ -1970,7 +1970,7 @@ class FSTestCase(_tempdirTestCase): class DirTestCase(_tempdirTestCase): - def test__morph(self): + def test__morph(self) -> None: """Test handling of actions when morphing an Entry into a Dir""" test = self.test e = self.fs.Entry('eee') @@ -1982,7 +1982,7 @@ class DirTestCase(_tempdirTestCase): assert 'pre' in a, a assert 'post' in a, a - def test_subclass(self): + def test_subclass(self) -> None: """Test looking up subclass of Dir nodes""" class DirSubclass(SCons.Node.FS.Dir): @@ -1991,7 +1991,7 @@ class DirTestCase(_tempdirTestCase): sd = self.fs._lookup('special_dir', None, DirSubclass, create=1) sd.must_be_same(SCons.Node.FS.Dir) - def test_get_env_scanner(self): + def test_get_env_scanner(self) -> None: """Test the Dir.get_env_scanner() method """ import SCons.Defaults @@ -1999,7 +1999,7 @@ class DirTestCase(_tempdirTestCase): s = d.get_env_scanner(Environment()) assert s is SCons.Defaults.DirEntryScanner, s - def test_get_target_scanner(self): + def test_get_target_scanner(self) -> None: """Test the Dir.get_target_scanner() method """ import SCons.Defaults @@ -2007,7 +2007,7 @@ class DirTestCase(_tempdirTestCase): s = d.get_target_scanner() assert s is SCons.Defaults.DirEntryScanner, s - def test_scan(self): + def test_scan(self) -> None: """Test scanning a directory for in-memory entries """ fs = self.fs @@ -2026,7 +2026,7 @@ class DirTestCase(_tempdirTestCase): os.path.join('ddd', 'f2'), os.path.join('ddd', 'f3')], kids - def test_get_contents(self): + def test_get_contents(self) -> None: """Test getting the contents for a directory. """ test = self.test @@ -2113,7 +2113,7 @@ class DirTestCase(_tempdirTestCase): assert self.actual_get_contents_calls == len(expected_get_contents_calls), \ self.actual_get_contents_calls - def test_implicit_re_scans(self): + def test_implicit_re_scans(self) -> None: """Test that adding entries causes a directory to be re-scanned """ @@ -2132,7 +2132,7 @@ class DirTestCase(_tempdirTestCase): assert kids == [os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2')], kids - def test_entry_exists_on_disk(self): + def test_entry_exists_on_disk(self) -> None: """Test the Dir.entry_exists_on_disk() method """ test = self.test @@ -2151,7 +2151,7 @@ class DirTestCase(_tempdirTestCase): if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": assert d.entry_exists_on_disk('case-insensitive') - def test_rentry_exists_on_disk(self): + def test_rentry_exists_on_disk(self) -> None: """Test the Dir.rentry_exists_on_disk() method """ test = self.test @@ -2177,7 +2177,7 @@ class DirTestCase(_tempdirTestCase): if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": assert d.rentry_exists_on_disk('case-insensitive') - def test_srcdir_list(self): + def test_srcdir_list(self) -> None: """Test the Dir.srcdir_list() method """ src = self.fs.Dir('src') @@ -2188,7 +2188,7 @@ class DirTestCase(_tempdirTestCase): self.fs.VariantDir(bld, src, duplicate=0) self.fs.VariantDir(sub2, src, duplicate=0) - def check(result, expect): + def check(result, expect) -> None: result = list(map(str, result)) expect = list(map(os.path.normpath, expect)) assert result == expect, result @@ -2230,7 +2230,7 @@ class DirTestCase(_tempdirTestCase): s = b1_b2_b1_b2_sub.srcdir_list() check(s, ['src/b1/b2/sub']) - def test_srcdir_duplicate(self): + def test_srcdir_duplicate(self) -> None: """Test the Dir.srcdir_duplicate() method """ test = self.test @@ -2265,12 +2265,12 @@ class DirTestCase(_tempdirTestCase): assert str(n) == os.path.normpath('bld1/exists'), str(n) assert os.path.exists(test.workpath('bld1', 'exists')) - def test_srcdir_find_file(self): + def test_srcdir_find_file(self) -> None: """Test the Dir.srcdir_find_file() method """ test = self.test - def return_true(node): + def return_true(node) -> int: return 1 SCons.Node._is_derived_map[2] = return_true @@ -2296,7 +2296,7 @@ class DirTestCase(_tempdirTestCase): exists_e = src0.Entry('exists-e') exists_e._func_exists = 5 - def check(result, expect): + def check(result, expect) -> None: result = list(map(str, result)) expect = list(map(os.path.normpath, expect)) assert result == expect, result @@ -2393,7 +2393,7 @@ class DirTestCase(_tempdirTestCase): n = bld1.srcdir_find_file('on-disk-e2') check(n, ['bld1/on-disk-e2', 'bld1']) - def test_dir_on_disk(self): + def test_dir_on_disk(self) -> None: """Test the Dir.dir_on_disk() method""" self.test.subdir('sub', ['sub', 'exists']) self.test.write(['sub', 'file'], "self/file\n") @@ -2408,7 +2408,7 @@ class DirTestCase(_tempdirTestCase): r = sub.dir_on_disk('file') assert not r, r - def test_file_on_disk(self): + def test_file_on_disk(self) -> None: """Test the Dir.file_on_disk() method""" self.test.subdir('sub', ['sub', 'dir']) self.test.write(['sub', 'exists'], "self/exists\n") @@ -2425,7 +2425,7 @@ class DirTestCase(_tempdirTestCase): class EntryTestCase(_tempdirTestCase): - def test_runTest(self): + def test_runTest(self) -> None: """Test methods specific to the Entry sub-class. """ test = TestCmd(workdir='') @@ -2472,11 +2472,11 @@ class EntryTestCase(_tempdirTestCase): assert not exists, "e4n exists?" class MyCalc: - def __init__(self, val): + def __init__(self, val) -> None: self.max_drift = 0 class M: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def collect(self, args): @@ -2493,7 +2493,7 @@ class EntryTestCase(_tempdirTestCase): test.subdir('e5d') test.write('e5f', "e5f\n") - def test_Entry_Entry_lookup(self): + def test_Entry_Entry_lookup(self) -> None: """Test looking up an Entry within another Entry""" self.fs.Entry('#topdir') self.fs.Entry('#topdir/a/b/c') @@ -2501,7 +2501,7 @@ class EntryTestCase(_tempdirTestCase): class FileTestCase(_tempdirTestCase): - def test_subclass(self): + def test_subclass(self) -> None: """Test looking up subclass of File nodes""" class FileSubclass(SCons.Node.FS.File): @@ -2510,7 +2510,7 @@ class FileTestCase(_tempdirTestCase): sd = self.fs._lookup('special_file', None, FileSubclass, create=1) sd.must_be_same(SCons.Node.FS.File) - def test_Dirs(self): + def test_Dirs(self) -> None: """Test the File.Dirs() method""" fff = self.fs.File('subdir/fff') # This simulates that the SConscript file that defined @@ -2521,7 +2521,7 @@ class FileTestCase(_tempdirTestCase): dirs = fff.Dirs(['d1', 'd2']) assert dirs == [d1, d2], list(map(str, dirs)) - def test_exists(self): + def test_exists(self) -> None: """Test the File.exists() method""" fs = self.fs test = self.test @@ -2553,7 +2553,7 @@ class FileTestCase(_tempdirTestCase): assert not os.path.exists(build_f1.get_abspath()), "%s did not get removed after %s was removed" % ( build_f1, src_f1) - def test_changed(self): + def test_changed(self) -> None: """ Verify that changes between BuildInfo's list of souces, depends, and implicit dependencies do not corrupt content signature values written to .SConsign @@ -2567,7 +2567,7 @@ class FileTestCase(_tempdirTestCase): # N implicits (for example ['alpha.h', 'beta.h', 'gamma.h', '/usr/bin/g++']) class ChangedNode(SCons.Node.FS.File): - def __init__(self, name, directory=None, fs=None): + def __init__(self, name, directory=None, fs=None) -> None: super().__init__(name, directory, fs) self.name = name self.Tag('found_includes', []) @@ -2607,12 +2607,12 @@ class FileTestCase(_tempdirTestCase): class ChangedEnvironment(SCons.Environment.Base): - def __init__(self): + def __init__(self) -> None: super().__init__() self.decide_source = self._changed_timestamp_then_content class FakeNodeInfo: - def __init__(self, csig, timestamp): + def __init__(self, csig, timestamp) -> None: self.csig = csig self.timestamp = timestamp @@ -2693,7 +2693,7 @@ class FileTestCase(_tempdirTestCase): class GlobTestCase(_tempdirTestCase): - def setUp(self): + def setUp(self) -> None: _tempdirTestCase.setUp(self) fs = SCons.Node.FS.FS() @@ -2758,7 +2758,7 @@ class GlobTestCase(_tempdirTestCase): self.sub_dir3_jjj = self.sub_dir3.File('jjj') self.sub_dir3_lll = self.sub_dir3.File('lll') - def do_cases(self, cases, **kwargs): + def do_cases(self, cases, **kwargs) -> None: # First, execute all of the cases with string=True and verify # that we get the expected strings returned. We do this first @@ -2800,7 +2800,7 @@ class GlobTestCase(_tempdirTestCase): pprint.pprint(list(map(fmt, r))) self.fail() - def test_exact_match(self): + def test_exact_match(self) -> None: """Test globbing for exact Node matches""" join = os.path.join @@ -2820,7 +2820,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_matches(self): + def test_subdir_matches(self) -> None: """Test globbing for exact Node matches in subdirectories""" join = os.path.join @@ -2836,7 +2836,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_asterisk1(self): + def test_asterisk1(self) -> None: """Test globbing for simple asterisk Node matches (1)""" cases = ( ('h*', @@ -2858,7 +2858,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases, ondisk=False) - def test_asterisk2(self): + def test_asterisk2(self) -> None: """Test globbing for simple asterisk Node matches (2)""" cases = ( ('disk-b*', @@ -2882,7 +2882,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_question_mark(self): + def test_question_mark(self) -> None: """Test globbing for simple question-mark Node matches""" join = os.path.join @@ -2906,7 +2906,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_does_not_exist(self): + def test_does_not_exist(self) -> None: """Test globbing for things that don't exist""" cases = ( @@ -2917,7 +2917,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_asterisk(self): + def test_subdir_asterisk(self) -> None: """Test globbing for asterisk Node matches in subdirectories""" join = os.path.join @@ -2979,7 +2979,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_question(self): + def test_subdir_question(self) -> None: """Test globbing for question-mark Node matches in subdirectories""" join = os.path.join @@ -3003,7 +3003,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_sort(self): + def test_sort(self) -> None: """Test whether globbing sorts""" join = os.path.join # At least sometimes this should return out-of-order items @@ -3025,7 +3025,7 @@ class GlobTestCase(_tempdirTestCase): class RepositoryTestCase(_tempdirTestCase): - def setUp(self): + def setUp(self) -> None: _tempdirTestCase.setUp(self) self.test.subdir('rep1', 'rep2', 'rep3', 'work') @@ -3039,7 +3039,7 @@ class RepositoryTestCase(_tempdirTestCase): self.fs = SCons.Node.FS.FS() self.fs.Repository(self.rep1, self.rep2, self.rep3) - def test_getRepositories(self): + def test_getRepositories(self) -> None: """Test the Dir.getRepositories() method""" self.fs.Repository('foo') self.fs.Repository(os.path.join('foo', 'bar')) @@ -3060,7 +3060,7 @@ class RepositoryTestCase(_tempdirTestCase): r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r - def test_get_all_rdirs(self): + def test_get_all_rdirs(self) -> None: """Test the Dir.get_all_rdirs() method""" self.fs.Repository('foo') self.fs.Repository(os.path.join('foo', 'bar')) @@ -3082,7 +3082,7 @@ class RepositoryTestCase(_tempdirTestCase): r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r - def test_rentry(self): + def test_rentry(self) -> None: """Test the Base.entry() method""" return_true = lambda: 1 return_false = lambda: 0 @@ -3150,13 +3150,13 @@ class RepositoryTestCase(_tempdirTestCase): r = str(r) assert r == os.path.join(self.rep2, 'f3'), r - def test_rdir(self): + def test_rdir(self) -> None: """Test the Dir.rdir() method""" - def return_true(obj): + def return_true(obj) -> int: return 1 - def return_false(obj): + def return_false(obj) -> int: return 0 SCons.Node._exists_map[5] = return_true @@ -3206,13 +3206,13 @@ class RepositoryTestCase(_tempdirTestCase): r = e2.rdir() assert r is re2, r - def test_rfile(self): + def test_rfile(self) -> None: """Test the File.rfile() method""" - def return_true(obj): + def return_true(obj) -> int: return 1 - def return_false(obj): + def return_false(obj) -> int: return 0 SCons.Node._exists_map[5] = return_true @@ -3262,7 +3262,7 @@ class RepositoryTestCase(_tempdirTestCase): r = e2.rfile() assert r is re2, r - def test_Rfindalldirs(self): + def test_Rfindalldirs(self) -> None: """Test the Rfindalldirs() methods""" fs = self.fs test = self.test @@ -3299,7 +3299,7 @@ class RepositoryTestCase(_tempdirTestCase): r = fs.Top.Rfindalldirs(('d1', d2)) assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], list(map(str, r)) - def test_rexists(self): + def test_rexists(self) -> None: """Test the Entry.rexists() method""" fs = self.fs test = self.test @@ -3325,7 +3325,7 @@ class RepositoryTestCase(_tempdirTestCase): f2 = fs.File(os.path.join('build', 'f2')) assert f2.rexists() - def test_FAT_timestamps(self): + def test_FAT_timestamps(self) -> None: """Test repository timestamps on FAT file systems""" fs = self.fs test = self.test @@ -3345,7 +3345,7 @@ class RepositoryTestCase(_tempdirTestCase): finally: test.unlink(["rep2", "tstamp"]) - def test_get_contents(self): + def test_get_contents(self) -> None: """Ensure get_contents() returns binary contents from Repositories""" fs = self.fs test = self.test @@ -3357,7 +3357,7 @@ class RepositoryTestCase(_tempdirTestCase): finally: test.unlink(["rep3", "contents"]) - def test_get_text_contents(self): + def test_get_text_contents(self) -> None: """Ensure get_text_contents() returns text contents from Repositories""" fs = self.fs @@ -3395,7 +3395,7 @@ class RepositoryTestCase(_tempdirTestCase): class find_fileTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Testing find_file function""" test = TestCmd(workdir='') test.write('./foo', 'Some file\n') @@ -3468,7 +3468,7 @@ class find_fileTestCase(unittest.TestCase): class StringDirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test using a string as the second argument of File() and Dir()""" @@ -3485,7 +3485,7 @@ class StringDirTestCase(unittest.TestCase): class stored_infoTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test how we store build information""" test = TestCmd(workdir='') test.subdir('sub') @@ -3498,7 +3498,7 @@ class stored_infoTestCase(unittest.TestCase): class MySConsign: class Null: - def __init__(self): + def __init__(self) -> None: self.xyzzy = 7 def get_entry(self, name): @@ -3515,7 +3515,7 @@ class stored_infoTestCase(unittest.TestCase): class has_src_builderTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test the has_src_builder() method""" test = TestCmd(workdir='') fs = SCons.Node.FS.FS(test.workpath('')) @@ -3552,7 +3552,7 @@ class has_src_builderTestCase(unittest.TestCase): class prepareTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test the prepare() method""" class MyFile(SCons.Node.FS.File): @@ -3573,10 +3573,10 @@ class prepareTestCase(unittest.TestCase): assert exc_caught, "Should have caught a StopError." class MkdirAction(Action): - def __init__(self, dir_made): + def __init__(self, dir_made) -> None: self.dir_made = dir_made - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> None: if executor: target = executor.get_all_targets() source = executor.get_all_sources() @@ -3603,7 +3603,7 @@ class prepareTestCase(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'symlink'), "Platform doesn't support symlink") class CleanSymlinksTestCase(_tempdirTestCase): - def test_cleans_symlinks(self): + def test_cleans_symlinks(self) -> None: """Test the prepare() method will cleanup symlinks.""" test = self.test @@ -3629,7 +3629,7 @@ class CleanSymlinksTestCase(_tempdirTestCase): except FileNotFoundError: test.fail('Real file %s should not be removed'%test.workpath('foo')) - def test_cleans_dangling_symlinks(self): + def test_cleans_dangling_symlinks(self) -> None: """Test the prepare() method will cleanup dangling symlinks.""" test = self.test @@ -3660,7 +3660,7 @@ class CleanSymlinksTestCase(_tempdirTestCase): class SConstruct_dirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test setting the SConstruct directory""" fs = SCons.Node.FS.FS() @@ -3670,7 +3670,7 @@ class SConstruct_dirTestCase(unittest.TestCase): class CacheDirTestCase(unittest.TestCase): - def test_get_cachedir_csig(self): + def test_get_cachedir_csig(self) -> None: fs = SCons.Node.FS.FS() f9 = fs.File('f9') @@ -3680,7 +3680,7 @@ class CacheDirTestCase(unittest.TestCase): class clearTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test clearing FS nodes of cached data.""" fs = SCons.Node.FS.FS() test = TestCmd(workdir='') @@ -3735,7 +3735,7 @@ class clearTestCase(unittest.TestCase): class disambiguateTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test calling the disambiguate() method.""" test = TestCmd(workdir='') @@ -3797,7 +3797,7 @@ class disambiguateTestCase(unittest.TestCase): class postprocessTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test calling the postprocess() method.""" fs = SCons.Node.FS.FS() @@ -3812,7 +3812,7 @@ class postprocessTestCase(unittest.TestCase): class SpecialAttrTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test special attributes of file nodes.""" test = TestCmd(workdir='') fs = SCons.Node.FS.FS(test.workpath('work')) @@ -3970,7 +3970,7 @@ class SpecialAttrTestCase(unittest.TestCase): class SaveStringsTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test caching string values of nodes.""" test = TestCmd(workdir='') @@ -3990,7 +3990,7 @@ class SaveStringsTestCase(unittest.TestCase): return [d0_f, d1_f, d0_b, d1_b] - def modify(nodes): + def modify(nodes) -> None: d0_f, d1_f, d0_b, d1_b = nodes d1_f.duplicate = 0 d1_b.duplicate = 0 @@ -4030,7 +4030,7 @@ class SaveStringsTestCase(unittest.TestCase): class AbsolutePathTestCase(unittest.TestCase): - def test_root_lookup_equivalence(self): + def test_root_lookup_equivalence(self) -> None: """Test looking up /fff vs. fff in the / directory""" test = TestCmd(workdir='') diff --git a/SCons/Node/NodeTests.py b/SCons/Node/NodeTests.py index ee4d080..e7c9e9a 100644 --- a/SCons/Node/NodeTests.py +++ b/SCons/Node/NodeTests.py @@ -60,10 +60,10 @@ class MyActionBase: return _actionAppend(other, self) class MyAction(MyActionBase): - def __init__(self): + def __init__(self) -> None: self.order = 0 - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> int: global built_it, built_target, built_source, built_args, built_order if executor: target = executor.get_all_targets() @@ -80,23 +80,23 @@ class MyAction(MyActionBase): return [] class MyExecutor: - def __init__(self, env=None, targets=[], sources=[]): + def __init__(self, env=None, targets=[], sources=[]) -> None: self.env = env self.targets = targets self.sources = sources def get_build_env(self): return self.env - def get_build_scanner_path(self, scanner): + def get_build_scanner_path(self, scanner) -> str: return 'executor would call %s' % scanner - def cleanup(self): + def cleanup(self) -> None: self.cleaned_up = 1 - def scan_targets(self, scanner): + def scan_targets(self, scanner) -> None: if not scanner: return d = scanner(self.targets) for t in self.targets: t.implicit.extend(d) - def scan_sources(self, scanner): + def scan_sources(self, scanner) -> None: if not scanner: return d = scanner(self.sources) @@ -104,14 +104,14 @@ class MyExecutor: t.implicit.extend(d) class MyListAction(MyActionBase): - def __init__(self, list): + def __init__(self, list) -> None: self.list = list - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> None: for A in self.list: A(target, source, env) class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} self._dict.update(kw) def __getitem__(self, key): @@ -124,7 +124,7 @@ class Environment: d = self._dict.copy() d.update(overrides) return Environment(**d) - def _update(self, dict): + def _update(self, dict) -> None: self._dict.update(dict) def get_factory(self, factory): return factory or MyNode @@ -137,7 +137,7 @@ class Environment: return [] class Builder: - def __init__(self, env=None, is_explicit=1): + def __init__(self, env=None, is_explicit: int=1) -> None: if env is None: env = Environment() self.env = env self.overrides = {} @@ -150,7 +150,7 @@ class Builder: return [t] def get_actions(self): return [self.action] - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> int: return 7 class NoneBuilder(Builder): @@ -159,7 +159,7 @@ class NoneBuilder(Builder): return None class ListBuilder(Builder): - def __init__(self, *nodes): + def __init__(self, *nodes) -> None: super().__init__() self.nodes = nodes def execute(self, target, source, env): @@ -171,7 +171,7 @@ class ListBuilder(Builder): self.status = Builder.execute(self, target, source, env) class FailBuilder: - def execute(self, target, source, env): + def execute(self, target, source, env) -> int: return 1 class ExceptBuilder: @@ -199,20 +199,20 @@ class MyNode(SCons.Node.Node): we expect to be overridden by real, functional Node subclasses. So simulate a real, functional Node subclass. """ - def __init__(self, name): + def __init__(self, name) -> None: super().__init__() self.name = name self.Tag('found_includes', []) - def __str__(self): + def __str__(self) -> str: return self.name def get_found_includes(self, env, scanner, target): return scanner(self) class Calculator: - def __init__(self, val): + def __init__(self, val) -> None: self.max_drift = 0 class M: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def signature(self, args): return self.val @@ -230,7 +230,7 @@ class NodeInfoBaseTestCase(unittest.TestCase): # the merge and format test (arbitrary attributes do not work). Do it with a # derived class that does provide the slots. - def test_merge(self): + def test_merge(self) -> None: """Test merging NodeInfoBase attributes""" class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -250,12 +250,12 @@ class NodeInfoBaseTestCase(unittest.TestCase): assert ni1.a2 == 222, ni1.a2 assert ni1.a3 == 333, ni1.a3 - def test_update(self): + def test_update(self) -> None: """Test the update() method""" ni = SCons.Node.NodeInfoBase() ni.update(SCons.Node.Node()) - def test_format(self): + def test_format(self) -> None: """Test the NodeInfoBase.format() method""" class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -278,13 +278,13 @@ class NodeInfoBaseTestCase(unittest.TestCase): class BuildInfoBaseTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test BuildInfoBase initialization""" n = SCons.Node.Node() bi = SCons.Node.BuildInfoBase() assert bi - def test_merge(self): + def test_merge(self) -> None: """Test merging BuildInfoBase attributes""" n1 = SCons.Node.Node() bi1 = SCons.Node.BuildInfoBase() @@ -305,7 +305,7 @@ class BuildInfoBaseTestCase(unittest.TestCase): class NodeTestCase(unittest.TestCase): - def test_build(self): + def test_build(self) -> None: """Test building a node """ global built_it, built_order @@ -379,7 +379,7 @@ class NodeTestCase(unittest.TestCase): assert built_args["on"] == 3, built_args assert built_args["off"] == 4, built_args - def test_get_build_scanner_path(self): + def test_get_build_scanner_path(self) -> None: """Test the get_build_scanner_path() method""" n = SCons.Node.Node() x = MyExecutor() @@ -387,7 +387,7 @@ class NodeTestCase(unittest.TestCase): p = n.get_build_scanner_path('fake_scanner') assert p == "executor would call fake_scanner", p - def test_get_executor(self): + def test_get_executor(self) -> None: """Test the get_executor() method""" n = SCons.Node.Node() @@ -414,13 +414,13 @@ class NodeTestCase(unittest.TestCase): x = n.get_executor() assert x.env == 'env2', x.env - def test_set_executor(self): + def test_set_executor(self) -> None: """Test the set_executor() method""" n = SCons.Node.Node() n.set_executor(1) assert n.executor == 1, n.executor - def test_executor_cleanup(self): + def test_executor_cleanup(self) -> None: """Test letting the executor cleanup its cache""" n = SCons.Node.Node() x = MyExecutor() @@ -428,7 +428,7 @@ class NodeTestCase(unittest.TestCase): n.executor_cleanup() assert x.cleaned_up - def test_reset_executor(self): + def test_reset_executor(self) -> None: """Test the reset_executor() method""" n = SCons.Node.Node() n.set_executor(1) @@ -436,14 +436,14 @@ class NodeTestCase(unittest.TestCase): n.reset_executor() assert not hasattr(n, 'executor'), "unexpected executor attribute" - def test_built(self): + def test_built(self) -> None: """Test the built() method""" class SubNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('updated',) - def update(self, node): + def update(self, node) -> None: self.updated = 1 class SubNode(SCons.Node.Node): - def clear(self): + def clear(self) -> None: self.cleared = 1 n = SubNode() @@ -452,19 +452,19 @@ class NodeTestCase(unittest.TestCase): assert n.cleared, n.cleared assert n.ninfo.updated, n.ninfo.cleared - def test_push_to_cache(self): + def test_push_to_cache(self) -> None: """Test the base push_to_cache() method""" n = SCons.Node.Node() r = n.push_to_cache() assert r is None, r - def test_retrieve_from_cache(self): + def test_retrieve_from_cache(self) -> None: """Test the base retrieve_from_cache() method""" n = SCons.Node.Node() r = n.retrieve_from_cache() assert r == 0, r - def test_visited(self): + def test_visited(self) -> None: """Test the base visited() method Just make sure it's there and we can call it. @@ -472,7 +472,7 @@ class NodeTestCase(unittest.TestCase): n = SCons.Node.Node() n.visited() - def test_builder_set(self): + def test_builder_set(self) -> None: """Test setting a Node's Builder """ node = SCons.Node.Node() @@ -480,7 +480,7 @@ class NodeTestCase(unittest.TestCase): node.builder_set(b) assert node.builder == b - def test_has_builder(self): + def test_has_builder(self) -> None: """Test the has_builder() method """ n1 = SCons.Node.Node() @@ -488,7 +488,7 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder()) assert n1.has_builder() == 1 - def test_has_explicit_builder(self): + def test_has_explicit_builder(self) -> None: """Test the has_explicit_builder() method """ n1 = SCons.Node.Node() @@ -498,7 +498,7 @@ class NodeTestCase(unittest.TestCase): n1.set_explicit(None) assert not n1.has_explicit_builder() - def test_get_builder(self): + def test_get_builder(self) -> None: """Test the get_builder() method""" n1 = SCons.Node.Node() b = n1.get_builder() @@ -511,7 +511,7 @@ class NodeTestCase(unittest.TestCase): b = n1.get_builder(999) assert b == 888, b - def test_multiple_side_effect_has_builder(self): + def test_multiple_side_effect_has_builder(self) -> None: """Test the multiple_side_effect_has_builder() method """ n1 = SCons.Node.Node() @@ -519,7 +519,7 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder()) assert n1.multiple_side_effect_has_builder() == 1 - def test_is_derived(self): + def test_is_derived(self) -> None: """Test the is_derived() method """ n1 = SCons.Node.Node() @@ -533,7 +533,7 @@ class NodeTestCase(unittest.TestCase): assert n2.is_derived() == 1 assert n3.is_derived() == 1 - def test_alter_targets(self): + def test_alter_targets(self) -> None: """Test the alter_targets() method """ n = SCons.Node.Node() @@ -541,13 +541,13 @@ class NodeTestCase(unittest.TestCase): assert t == [], t assert m is None, m - def test_is_up_to_date(self): + def test_is_up_to_date(self) -> None: """Test the default is_up_to_date() method """ node = SCons.Node.Node() assert node.is_up_to_date() is None - def test_children_are_up_to_date(self): + def test_children_are_up_to_date(self) -> None: """Test the children_are_up_to_date() method used by subclasses """ n1 = SCons.Node.Node() @@ -562,7 +562,7 @@ class NodeTestCase(unittest.TestCase): n1.always_build = 1 assert not n1.children_are_up_to_date(), "expected not up to date" - def test_env_set(self): + def test_env_set(self) -> None: """Test setting a Node's Environment """ node = SCons.Node.Node() @@ -570,7 +570,7 @@ class NodeTestCase(unittest.TestCase): node.env_set(e) assert node.env == e - def test_get_actions(self): + def test_get_actions(self) -> None: """Test fetching a Node's action list """ node = SCons.Node.Node() @@ -578,7 +578,7 @@ class NodeTestCase(unittest.TestCase): a = node.builder.get_actions() assert isinstance(a[0], MyAction), a[0] - def test_get_csig(self): + def test_get_csig(self) -> None: """Test generic content signature calculation """ @@ -586,7 +586,7 @@ class NodeTestCase(unittest.TestCase): __slots__ = ('csig',) try: SCons.Node.Node.NodeInfo = TestNodeInfo - def my_contents(obj): + def my_contents(obj) -> int: return 444 SCons.Node._get_contents_map[4] = my_contents node = SCons.Node.Node() @@ -596,14 +596,14 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase - def test_get_cachedir_csig(self): + def test_get_cachedir_csig(self) -> None: """Test content signature calculation for CacheDir """ class TestNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('csig',) try: SCons.Node.Node.NodeInfo = TestNodeInfo - def my_contents(obj): + def my_contents(obj) -> int: return 555 SCons.Node._get_contents_map[4] = my_contents node = SCons.Node.Node() @@ -613,7 +613,7 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase - def test_get_binfo(self): + def test_get_binfo(self) -> None: """Test fetching/creating a build information structure """ class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -643,11 +643,11 @@ class NodeTestCase(unittest.TestCase): assert binfo.bimplicit == [i] assert hasattr(binfo, 'bimplicitsigs') - def test_explain(self): + def test_explain(self) -> None: """Test explaining why a Node must be rebuilt """ class testNode(SCons.Node.Node): - def __str__(self): return 'xyzzy' + def __str__(self) -> str: return 'xyzzy' node = testNode() node.exists = lambda: None # Can't do this with new-style classes (python bug #1066490) @@ -656,7 +656,7 @@ class NodeTestCase(unittest.TestCase): assert result == "building `xyzzy' because it doesn't exist\n", result class testNode2(SCons.Node.Node): - def __str__(self): return 'null_binfo' + def __str__(self) -> str: return 'null_binfo' class FS: pass node = testNode2() @@ -668,7 +668,7 @@ class NodeTestCase(unittest.TestCase): def get_null_info(): class Null_SConsignEntry: class Null_BuildInfo: - def prepare_dependencies(self): + def prepare_dependencies(self) -> None: pass binfo = Null_BuildInfo() return Null_SConsignEntry() @@ -688,20 +688,20 @@ class NodeTestCase(unittest.TestCase): # node.del_binfo() # assert not hasattr(node, 'binfo'), node - def test_store_info(self): + def test_store_info(self) -> None: """Test calling the method to store build information """ node = SCons.Node.Node() SCons.Node.store_info_map[node.store_info](node) - def test_get_stored_info(self): + def test_get_stored_info(self) -> None: """Test calling the method to fetch stored build information """ node = SCons.Node.Node() result = node.get_stored_info() assert result is None, result - def test_set_always_build(self): + def test_set_always_build(self) -> None: """Test setting a Node's always_build value """ node = SCons.Node.Node() @@ -710,7 +710,7 @@ class NodeTestCase(unittest.TestCase): node.set_always_build(3) assert node.always_build == 3 - def test_set_noclean(self): + def test_set_noclean(self) -> None: """Test setting a Node's noclean value """ node = SCons.Node.Node() @@ -723,7 +723,7 @@ class NodeTestCase(unittest.TestCase): node.set_noclean(None) assert node.noclean == 0, node.noclean - def test_set_precious(self): + def test_set_precious(self) -> None: """Test setting a Node's precious value """ node = SCons.Node.Node() @@ -732,7 +732,7 @@ class NodeTestCase(unittest.TestCase): node.set_precious(7) assert node.precious == 7 - def test_set_pseudo(self): + def test_set_pseudo(self) -> None: """Test setting a Node's pseudo value """ node = SCons.Node.Node() @@ -741,14 +741,14 @@ class NodeTestCase(unittest.TestCase): node.set_pseudo(False) assert not node.pseudo - def test_exists(self): + def test_exists(self) -> None: """Test evaluating whether a Node exists. """ node = SCons.Node.Node() e = node.exists() assert e == 1, e - def test_exists_repo(self): + def test_exists_repo(self) -> None: """Test evaluating whether a Node exists locally or in a repository. """ node = SCons.Node.Node() @@ -756,14 +756,14 @@ class NodeTestCase(unittest.TestCase): assert e == 1, e class MyNode(SCons.Node.Node): - def exists(self): + def exists(self) -> str: return 'xyz' node = MyNode() e = node.rexists() assert e == 'xyz', e - def test_prepare(self): + def test_prepare(self) -> None: """Test preparing a node to be built By extension, this also tests the missing() method. @@ -902,7 +902,7 @@ class NodeTestCase(unittest.TestCase): raise Exception("did not catch expected exception") assert node.ignore == [zero, one, two, three, four] - def test_get_found_includes(self): + def test_get_found_includes(self) -> None: """Test the default get_found_includes() method """ node = SCons.Node.Node() @@ -911,7 +911,7 @@ class NodeTestCase(unittest.TestCase): deps = node.get_found_includes(e, None, target) assert deps == [], deps - def test_get_implicit_deps(self): + def test_get_implicit_deps(self) -> None: """Test get_implicit_deps() """ node = MyNode("nnn") @@ -958,7 +958,7 @@ class NodeTestCase(unittest.TestCase): deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2], list(map(str, deps)) - def test_get_env_scanner(self): + def test_get_env_scanner(self) -> None: """Test fetching the environment scanner for a Node """ node = SCons.Node.Node() @@ -969,7 +969,7 @@ class NodeTestCase(unittest.TestCase): s = node.get_env_scanner(env, {'X':1}) assert s == scanner, s - def test_get_target_scanner(self): + def test_get_target_scanner(self) -> None: """Test fetching the target scanner for a Node """ s = Scanner() @@ -980,7 +980,7 @@ class NodeTestCase(unittest.TestCase): x = n.get_target_scanner() assert x is s, x - def test_get_source_scanner(self): + def test_get_source_scanner(self) -> None: """Test fetching the source scanner for a Node """ target = SCons.Node.Node() @@ -998,7 +998,7 @@ class NodeTestCase(unittest.TestCase): r.builder = self return [r] class Builder2(Builder1): - def __init__(self, scanner): + def __init__(self, scanner) -> None: self.source_scanner = scanner builder = Builder2(ts1) @@ -1020,7 +1020,7 @@ class NodeTestCase(unittest.TestCase): assert s is ts3, s - def test_scan(self): + def test_scan(self) -> None: """Test Scanner functionality """ env = Environment() @@ -1068,11 +1068,11 @@ class NodeTestCase(unittest.TestCase): SCons.Node.implicit_deps_changed = save_implicit_deps_changed SCons.Node.implicit_deps_unchanged = save_implicit_deps_unchanged - def test_scanner_key(self): + def test_scanner_key(self) -> None: """Test that a scanner_key() method exists""" assert SCons.Node.Node().scanner_key() is None - def test_children(self): + def test_children(self) -> None: """Test fetching the non-ignored "children" of a Node. """ node = SCons.Node.Node() @@ -1103,7 +1103,7 @@ class NodeTestCase(unittest.TestCase): for kid in [n2, n5, n8, n11]: assert kid not in kids, kid - def test_all_children(self): + def test_all_children(self) -> None: """Test fetching all the "children" of a Node. """ node = SCons.Node.Node() @@ -1132,7 +1132,7 @@ class NodeTestCase(unittest.TestCase): for kid in [n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12]: assert kid in kids, kid - def test_state(self): + def test_state(self) -> None: """Test setting and getting the state of a node """ node = SCons.Node.Node() @@ -1144,7 +1144,7 @@ class NodeTestCase(unittest.TestCase): assert SCons.Node.up_to_date < SCons.Node.executed assert SCons.Node.executed < SCons.Node.failed - def test_walker(self): + def test_walker(self) -> None: """Test walking a Node tree. """ @@ -1194,7 +1194,7 @@ class NodeTestCase(unittest.TestCase): n8.add_dependency([n3]) n7.add_dependency([n8]) - def cycle(node, stack): + def cycle(node, stack) -> None: global cycle_detected cycle_detected = 1 @@ -1212,20 +1212,20 @@ class NodeTestCase(unittest.TestCase): n = nw.get_next() assert nw.get_next() is None - def test_abspath(self): + def test_abspath(self) -> None: """Test the get_abspath() method.""" n = MyNode("foo") assert n.get_abspath() == str(n), n.get_abspath() - def test_for_signature(self): + def test_for_signature(self) -> None: """Test the for_signature() method.""" n = MyNode("foo") assert n.for_signature() == str(n), n.get_abspath() - def test_get_string(self): + def test_get_string(self) -> None: """Test the get_string() method.""" class TestNode(MyNode): - def __init__(self, name, sig): + def __init__(self, name, sig) -> None: super().__init__(name) self.sig = sig @@ -1236,12 +1236,12 @@ class NodeTestCase(unittest.TestCase): assert n.get_string(0) == "foo", n.get_string(0) assert n.get_string(1) == "bar", n.get_string(1) - def test_literal(self): + def test_literal(self) -> None: """Test the is_literal() function.""" n=SCons.Node.Node() assert n.is_literal() - def test_sconscripts(self): + def test_sconscripts(self) -> None: """Test the is_sconscript() function.""" # check nodes are not sconscript unless added to the list n=SCons.Node.Node() @@ -1254,7 +1254,7 @@ class NodeTestCase(unittest.TestCase): assert not n.is_sconscript() assert n2.is_sconscript() - def test_conftests(self): + def test_conftests(self) -> None: """Test the is_conftest() function.""" # check nodes are not sconscript unless added to the list n=SCons.Node.Node() @@ -1267,9 +1267,9 @@ class NodeTestCase(unittest.TestCase): assert not n.is_conftest() assert n2.is_conftest() - def test_Annotate(self): + def test_Annotate(self) -> None: """Test using an interface-specific Annotate function.""" - def my_annotate(node, self=self): + def my_annotate(node, self=self) -> None: node.Tag('annotation', self.node_string) save_Annotate = SCons.Node.Annotate @@ -1288,7 +1288,7 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Annotate = save_Annotate - def test_clear(self): + def test_clear(self) -> None: """Test clearing all cached state information.""" n = SCons.Node.Node() @@ -1308,25 +1308,25 @@ class NodeTestCase(unittest.TestCase): assert n.cached == 0, n.cached assert x.cleaned_up - def test_get_subst_proxy(self): + def test_get_subst_proxy(self) -> None: """Test the get_subst_proxy method.""" n = MyNode("test") assert n.get_subst_proxy() == n, n.get_subst_proxy() - def test_new_binfo(self): + def test_new_binfo(self) -> None: """Test the new_binfo() method""" n = SCons.Node.Node() result = n.new_binfo() assert isinstance(result, SCons.Node.BuildInfoBase), result - def test_get_suffix(self): + def test_get_suffix(self) -> None: """Test the base Node get_suffix() method""" n = SCons.Node.Node() s = n.get_suffix() assert s == '', s - def test_postprocess(self): + def test_postprocess(self) -> None: """Test calling the base Node postprocess() method""" n = SCons.Node.Node() n.waiting_parents = {'foo', 'bar'} @@ -1334,7 +1334,7 @@ class NodeTestCase(unittest.TestCase): n.postprocess() assert n.waiting_parents == set(), n.waiting_parents - def test_add_to_waiting_parents(self): + def test_add_to_waiting_parents(self) -> None: """Test the add_to_waiting_parents() method""" n1 = SCons.Node.Node() n2 = SCons.Node.Node() @@ -1347,7 +1347,7 @@ class NodeTestCase(unittest.TestCase): class NodeListTestCase(unittest.TestCase): - def test___str__(self): + def test___str__(self) -> None: """Test""" n1 = MyNode("n1") n2 = MyNode("n2") diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py index 57416ef..008787a 100644 --- a/SCons/Node/Python.py +++ b/SCons/Node/Python.py @@ -58,7 +58,7 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -87,7 +87,7 @@ class Value(SCons.Node.Node): NodeInfo = ValueNodeInfo BuildInfo = ValueBuildInfo - def __init__(self, value, built_value=None, name=None): + def __init__(self, value, built_value=None, name=None) -> None: super().__init__() self.value = value self.changed_since_last_build = 6 @@ -105,25 +105,25 @@ class Value(SCons.Node.Node): def str_for_display(self): return repr(self.value) - def __str__(self): + def __str__(self) -> str: return str(self.value) - def make_ready(self): + def make_ready(self) -> None: self.get_csig() - def build(self, **kw): + def build(self, **kw) -> None: if not hasattr(self, 'built_value'): SCons.Node.Node.build(self, **kw) is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir): + def is_under(self, dir) -> int: # Make Value nodes get built regardless of # what directory scons was run from. Value nodes # are outside the filesystem: return 1 - def write(self, built_value): + def write(self, built_value) -> None: """Set the value of the node.""" self.built_value = built_value diff --git a/SCons/Node/PythonTests.py b/SCons/Node/PythonTests.py index b6a3f79..2be2b29 100644 --- a/SCons/Node/PythonTests.py +++ b/SCons/Node/PythonTests.py @@ -28,7 +28,7 @@ import SCons.Node.Python class ValueTestCase(unittest.TestCase): - def test_Value(self): + def test_Value(self) -> None: """Test creating a Value() object """ v1 = SCons.Node.Python.Value('a') @@ -45,11 +45,11 @@ class ValueTestCase(unittest.TestCase): v3 = SCons.Node.Python.Value('c', 'cb') assert v3.built_value == 'cb' - def test_build(self): + def test_build(self) -> None: """Test "building" a Value Node """ class fake_executor: - def __call__(self, node): + def __call__(self, node) -> None: node.write('faked') v1 = SCons.Node.Python.Value('b', 'built') @@ -68,14 +68,14 @@ class ValueTestCase(unittest.TestCase): assert v3.name == 'name', v3.name assert v3.built_value == 'faked', v3.built_value - def test_read(self): + def test_read(self) -> None: """Test the Value.read() method """ v1 = SCons.Node.Python.Value('a') x = v1.read() assert x == 'a', x - def test_write(self): + def test_write(self) -> None: """Test the Value.write() method """ v1 = SCons.Node.Python.Value('a') @@ -86,7 +86,7 @@ class ValueTestCase(unittest.TestCase): assert v1.value == 'a', v1.value assert v1.built_value == 'new', v1.built_value - def test_get_csig(self): + def test_get_csig(self) -> None: """Test calculating the content signature of a Value() object """ v1 = SCons.Node.Python.Value('aaa') @@ -106,21 +106,21 @@ class ValueTestCase(unittest.TestCase): class ValueNodeInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test ValueNodeInfo initialization""" vvv = SCons.Node.Python.Value('vvv') ni = SCons.Node.Python.ValueNodeInfo() class ValueBuildInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test ValueBuildInfo initialization""" vvv = SCons.Node.Python.Value('vvv') bi = SCons.Node.Python.ValueBuildInfo() class ValueChildTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test support for a Value() being an implicit dependency of a Node""" value = SCons.Node.Python.Value('v') node = SCons.Node.Node() @@ -132,7 +132,7 @@ class ValueChildTestCase(unittest.TestCase): class ValueMemoTestCase(unittest.TestCase): - def test_memo(self): + def test_memo(self) -> None: """Test memoization""" # First confirm that ValueWithMemo does memoization. value1 = SCons.Node.Python.ValueWithMemo('vvv') @@ -145,13 +145,13 @@ class ValueMemoTestCase(unittest.TestCase): value3 = ni.str_to_node('vvv') assert value1 is value3 - def test_built_value(self): + def test_built_value(self) -> None: """Confirm that built values are not memoized.""" v1 = SCons.Node.Python.ValueWithMemo('c', 'ca') v2 = SCons.Node.Python.ValueWithMemo('c', 'ca') assert v1 is not v2 - def test_non_primitive_values(self): + def test_non_primitive_values(self) -> None: """Confirm that non-primitive values are not memoized.""" d = {'a': 1} v1 = SCons.Node.Python.ValueWithMemo(d) @@ -163,7 +163,7 @@ class ValueMemoTestCase(unittest.TestCase): v4 = SCons.Node.Python.ValueWithMemo(a) assert v3 is not v4 - def test_value_set_name(self): + def test_value_set_name(self) -> None: """ Confirm setting name and caching takes the name into account """ v1 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name') diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index bb09868..81ff2ff 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -94,7 +94,7 @@ implicit_deps_changed = 0 # A variable that can be set to an interface-specific function be called # to annotate a Node with information about its creation. -def do_nothing_node(node): pass +def do_nothing_node(node) -> None: pass Annotate = do_nothing_node @@ -121,10 +121,10 @@ _is_derived_map = {0 : is_derived_none, def exists_none(node): raise NotImplementedError -def exists_always(node): +def exists_always(node) -> int: return 1 -def exists_base(node): +def exists_base(node) -> bool: return node.stat() is not None def exists_entry(node): @@ -326,10 +326,10 @@ do_store_info = True # First, the single info functions # -def store_info_pass(node): +def store_info_pass(node) -> None: pass -def store_info_file(node): +def store_info_file(node) -> None: # Merge our build information into the already-stored entry. # This accommodates "chained builds" where a file that's a target # in one build (SConstruct file) is a source in a different build. @@ -353,7 +353,7 @@ class NodeInfoBase: __slots__ = ('__weakref__',) current_version_id = 2 - def update(self, node): + def update(self, node) -> None: try: field_list = self.field_list except AttributeError: @@ -370,10 +370,10 @@ class NodeInfoBase: else: setattr(self, f, func()) - def convert(self, node, val): + def convert(self, node, val) -> None: pass - def merge(self, other): + def merge(self, other) -> None: """ Merge the fields of another object into this object. Already existing information is overwritten by the other instance's data. @@ -383,7 +383,7 @@ class NodeInfoBase: state = other.__getstate__() self.__setstate__(state) - def format(self, field_list=None, names=0): + def format(self, field_list=None, names: int=0): if field_list is None: try: field_list = self.field_list @@ -426,7 +426,7 @@ class NodeInfoBase: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. The version is discarded. """ @@ -452,7 +452,7 @@ class BuildInfoBase: "bsources", "bdepends", "bact", "bimplicit", "__weakref__") current_version_id = 2 - def __init__(self): + def __init__(self) -> None: # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. self.bsourcesigs = [] @@ -460,7 +460,7 @@ class BuildInfoBase: self.bimplicitsigs = [] self.bactsig = None - def merge(self, other): + def merge(self, other) -> None: """ Merge the fields of another object into this object. Already existing information is overwritten by the other instance's data. @@ -490,7 +490,7 @@ class BuildInfoBase: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -553,7 +553,7 @@ class Node(object, metaclass=NoSlotsPyPy): __slots__ = ('shared', '__dict__') - def __init__(self): + def __init__(self) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node') # Note that we no longer explicitly initialize a self.builder # attribute to None here. That's because the self.builder @@ -615,7 +615,7 @@ class Node(object, metaclass=NoSlotsPyPy): def disambiguate(self, must_exist=None): return self - def get_suffix(self): + def get_suffix(self) -> str: return '' @SCons.Memoize.CountMethodCall @@ -634,11 +634,11 @@ class Node(object, metaclass=NoSlotsPyPy): """Fetch the appropriate scanner path for this node.""" return self.get_executor().get_build_scanner_path(scanner) - def set_executor(self, executor): + def set_executor(self, executor) -> None: """Set the action executor for this node.""" self.executor = executor - def get_executor(self, create=1): + def get_executor(self, create: int=1): """Fetch the action executor for this node. Create one if there isn't already one, and requested to do so.""" try: @@ -659,7 +659,7 @@ class Node(object, metaclass=NoSlotsPyPy): self.executor = executor return executor - def executor_cleanup(self): + def executor_cleanup(self) -> None: """Let the executor clean up any cached information.""" try: executor = self.get_executor(create=None) @@ -669,19 +669,19 @@ class Node(object, metaclass=NoSlotsPyPy): if executor is not None: executor.cleanup() - def reset_executor(self): + def reset_executor(self) -> None: """Remove cached executor; forces recompute when needed.""" try: delattr(self, 'executor') except AttributeError: pass - def push_to_cache(self): + def push_to_cache(self) -> None: """Try to push a node into a cache """ pass - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> int: """Try to retrieve the node's content from a cache This method is called from multiple threads in a parallel build, @@ -696,7 +696,7 @@ class Node(object, metaclass=NoSlotsPyPy): # Taskmaster interface subsystem # - def make_ready(self): + def make_ready(self) -> None: """Get a Node ready for evaluation. This is called before the Taskmaster decides if the Node is @@ -795,7 +795,7 @@ class Node(object, metaclass=NoSlotsPyPy): "Cannot find target " + str(self) + " after building") self.ninfo.update(self) - def visited(self): + def visited(self) -> None: """Called just after this node has been visited (with or without a build).""" try: @@ -808,7 +808,7 @@ class Node(object, metaclass=NoSlotsPyPy): self.ninfo.update(self) SCons.Node.store_info_map[self.store_info](self) - def release_target_info(self): + def release_target_info(self) -> None: """Called just after this node has been marked up-to-date or was built completely. @@ -825,10 +825,10 @@ class Node(object, metaclass=NoSlotsPyPy): """ pass - def add_to_waiting_s_e(self, node): + def add_to_waiting_s_e(self, node) -> None: self.waiting_s_e.add(node) - def add_to_waiting_parents(self, node): + def add_to_waiting_parents(self, node) -> int: """ Returns the number of nodes added to our waiting parents list: 1 if we add a unique waiting parent, 0 if not. (Note that the @@ -842,13 +842,13 @@ class Node(object, metaclass=NoSlotsPyPy): wp.add(node) return 1 - def postprocess(self): + def postprocess(self) -> None: """Clean up anything we don't need to hang onto after we've been built.""" self.executor_cleanup() self.waiting_parents = set() - def clear(self): + def clear(self) -> None: """Completely clear a Node of all its cached state (so that it can be re-evaluated by interfaces that do continuous integration builds). @@ -868,17 +868,17 @@ class Node(object, metaclass=NoSlotsPyPy): self.cached = 0 self.includes = None - def clear_memoized_values(self): + def clear_memoized_values(self) -> None: self._memo = {} - def builder_set(self, builder): + def builder_set(self, builder) -> None: self.builder = builder try: del self.executor except AttributeError: pass - def has_builder(self): + def has_builder(self) -> bool: """Return whether this Node has a builder or not. In Boolean tests, this turns out to be a *lot* more efficient @@ -897,7 +897,7 @@ class Node(object, metaclass=NoSlotsPyPy): b = self.builder = None return b is not None - def set_explicit(self, is_explicit): + def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit def has_explicit_builder(self): @@ -934,11 +934,11 @@ class Node(object, metaclass=NoSlotsPyPy): """ return _is_derived_map[self._func_is_derived](self) - def is_sconscript(self): + def is_sconscript(self) -> bool: """ Returns true if this node is an sconscript """ return self in SConscriptNodes - def is_conftest(self): + def is_conftest(self) -> bool: """ Returns true if this node is an conftest node""" try: self.attributes.conftest_node @@ -1050,14 +1050,14 @@ class Node(object, metaclass=NoSlotsPyPy): scanner = scanner.select(node) return scanner - def add_to_implicit(self, deps): + def add_to_implicit(self, deps) -> None: if not hasattr(self, 'implicit') or self.implicit is None: self.implicit = [] self.implicit_set = set() self._children_reset() self._add_child(self.implicit, self.implicit_set, deps) - def scan(self): + def scan(self) -> None: """Scan this node's dependents for implicit dependencies.""" # Don't bother scanning non-derived files, because we don't # care what their dependencies are. @@ -1119,7 +1119,7 @@ class Node(object, metaclass=NoSlotsPyPy): """ return scanner.select(self) - def env_set(self, env, safe=0): + def env_set(self, env, safe: int=0) -> None: if safe and self.env: return self.env = env @@ -1197,7 +1197,7 @@ class Node(object, metaclass=NoSlotsPyPy): return binfo - def del_binfo(self): + def del_binfo(self) -> None: """Delete the build info from this node.""" try: delattr(self, 'binfo') @@ -1226,27 +1226,27 @@ class Node(object, metaclass=NoSlotsPyPy): # # - def set_precious(self, precious = 1): + def set_precious(self, precious: int = 1) -> None: """Set the Node's precious value.""" self.precious = precious - def set_pseudo(self, pseudo = True): + def set_pseudo(self, pseudo: bool = True) -> None: """Set the Node's precious value.""" self.pseudo = pseudo - def set_noclean(self, noclean = 1): + def set_noclean(self, noclean: int = 1) -> None: """Set the Node's noclean value.""" # Make sure noclean is an integer so the --debug=stree # output in Util.py can use it as an index. self.noclean = noclean and 1 or 0 - def set_nocache(self, nocache = 1): + def set_nocache(self, nocache: int = 1) -> None: """Set the Node's nocache value.""" # Make sure nocache is an integer so the --debug=stree # output in Util.py can use it as an index. self.nocache = nocache and 1 or 0 - def set_always_build(self, always_build = 1): + def set_always_build(self, always_build: int = 1) -> None: """Set the Node's always_build value.""" self.always_build = always_build @@ -1263,7 +1263,7 @@ class Node(object, metaclass=NoSlotsPyPy): """Fetch the contents of the entry.""" return _get_contents_map[self._func_get_contents](self) - def missing(self): + def missing(self) -> bool: return not self.is_derived() and \ not self.linked and \ not self.rexists() @@ -1284,7 +1284,7 @@ class Node(object, metaclass=NoSlotsPyPy): s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - def add_prerequisite(self, prerequisite): + def add_prerequisite(self, prerequisite) -> None: """Adds prerequisites""" if self.prerequisites is None: self.prerequisites = UniqueList() @@ -1317,7 +1317,7 @@ class Node(object, metaclass=NoSlotsPyPy): s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - def _add_child(self, collection, set, child): + def _add_child(self, collection, set, child) -> None: """Adds 'child' to 'collection', first checking 'set' to see if it's already present.""" added = None @@ -1329,16 +1329,16 @@ class Node(object, metaclass=NoSlotsPyPy): if added: self._children_reset() - def set_specific_source(self, source): + def set_specific_source(self, source) -> None: self.add_source(source) self._specific_sources = True - def add_wkid(self, wkid): + def add_wkid(self, wkid) -> None: """Add a node to the list of kids waiting to be evaluated""" if self.wkids is not None: self.wkids.append(wkid) - def _children_reset(self): + def _children_reset(self) -> None: self.clear_memoized_values() # We need to let the Executor clear out any calculated # build info that it's cached so we can re-calculate it. @@ -1381,7 +1381,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._memo['_children_get'] = children return children - def all_children(self, scan=1): + def all_children(self, scan: int=1): """Return a list of all the node's direct children.""" if scan: self.scan() @@ -1405,14 +1405,14 @@ class Node(object, metaclass=NoSlotsPyPy): # internally anyway...) return list(chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f])) - def children(self, scan=1): + def children(self, scan: int=1): """Return a list of the node's direct children, minus those that are ignored by this node.""" if scan: self.scan() return self._children_get() - def set_state(self, state): + def set_state(self, state) -> None: self.state = state def get_state(self): @@ -1425,7 +1425,7 @@ class Node(object, metaclass=NoSlotsPyPy): env = SCons.Defaults.DefaultEnvironment() return env - def Decider(self, function): + def Decider(self, function) -> None: foundkey = None for k, v in _decider_map.items(): if v == function: @@ -1436,7 +1436,7 @@ class Node(object, metaclass=NoSlotsPyPy): _decider_map[foundkey] = function self.changed_since_last_build = foundkey - def Tag(self, key, value): + def Tag(self, key, value) -> None: """ Add a user-defined tag. """ if not self._tags: self._tags = {} @@ -1448,7 +1448,7 @@ class Node(object, metaclass=NoSlotsPyPy): return None return self._tags.get(key, None) - def changed(self, node=None, allowcache=False): + def changed(self, node=None, allowcache: bool=False): """ Returns if the node is up-to-date with respect to the BuildInfo stored last time it was built. The default behavior is to compare @@ -1534,7 +1534,7 @@ class Node(object, metaclass=NoSlotsPyPy): state = s return (state == 0 or state == SCons.Node.up_to_date) - def is_literal(self): + def is_literal(self) -> int: """Always pass the string representation of a Node to the command interpreter literally.""" return 1 @@ -1710,12 +1710,12 @@ class Node(object, metaclass=NoSlotsPyPy): return ( ' '*11).join(lines) class NodeList(collections.UserList): - def __str__(self): + def __str__(self) -> str: return str(list(map(str, self.data))) def get_children(node, parent): return node.children() -def ignore_cycle(node, stack): pass -def do_nothing(node, parent): pass +def ignore_cycle(node, stack) -> None: pass +def do_nothing(node, parent) -> None: pass class Walker: """An iterator for walking a Node tree. @@ -1732,7 +1732,7 @@ class Walker: """ def __init__(self, node, kids_func=get_children, cycle_func=ignore_cycle, - eval_func=do_nothing): + eval_func=do_nothing) -> None: self.kids_func = kids_func self.cycle_func = cycle_func self.eval_func = eval_func @@ -1771,7 +1771,7 @@ class Walker: return node return None - def is_done(self): + def is_done(self) -> bool: return not self.stack diff --git a/SCons/PathList.py b/SCons/PathList.py index a7e666d..dab8b2c 100644 --- a/SCons/PathList.py +++ b/SCons/PathList.py @@ -67,7 +67,7 @@ class _PathList: """ An actual PathList object. """ - def __init__(self, pathlist): + def __init__(self, pathlist) -> None: """ Initializes a PathList object, canonicalizing the input and pre-processing it for quicker substitution later. @@ -113,7 +113,7 @@ class _PathList: self.pathlist = tuple(pl) - def __len__(self): return len(self.pathlist) + def __len__(self) -> int: return len(self.pathlist) def __getitem__(self, i): return self.pathlist[i] @@ -168,7 +168,7 @@ class PathListCache: cheaply avoid re-parsing both values of CPPPATH by using the common value from this cache. """ - def __init__(self): + def __init__(self) -> None: self._memo = {} def _PathList_key(self, pathlist): diff --git a/SCons/PathListTests.py b/SCons/PathListTests.py index e62baad..78fd1a4 100644 --- a/SCons/PathListTests.py +++ b/SCons/PathListTests.py @@ -28,10 +28,10 @@ import SCons.PathList class subst_pathTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: class FakeEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.kw = kw def subst(self, s, target=None, source=None, conv=lambda x: x): if s[0] == '$': @@ -48,7 +48,7 @@ class subst_pathTestCase(unittest.TestCase): from SCons.Environment import Environment self.env = Environment(AAA = 'aaa', NULL = '') - def test_node(self): + def test_node(self) -> None: """Test the subst_path() method on a Node """ @@ -65,12 +65,12 @@ class subst_pathTestCase(unittest.TestCase): assert result == (n,), result - def test_object(self): + def test_object(self) -> None: """Test the subst_path() method on a non-Node object """ class A: - def __str__(self): + def __str__(self) -> str: return '' a = A() @@ -81,12 +81,12 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('',), result - def test_object_get(self): + def test_object_get(self) -> None: """Test the subst_path() method on an object with a get() method """ class B: - def get(self): + def get(self) -> str: return 'b' b = B() @@ -97,7 +97,7 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('b',), result - def test_string(self): + def test_string(self) -> None: """Test the subst_path() method on a non-substitution string """ @@ -109,7 +109,7 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('x',), result - def test_subst(self): + def test_subst(self) -> None: """Test the subst_path() method on substitution strings """ @@ -119,14 +119,14 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('aaa',), result - def test_list_of_lists(self): + def test_list_of_lists(self) -> None: """Test the subst_path() method on substitution of nested lists. """ pl = SCons.PathList.PathList((['$AAA', '$AAA'], '$NULL')) result = pl.subst_path(self.env, 'y', 'z') assert result == ('aaa', 'aaa'), result - def test_subst_nested(self): + def test_subst_nested(self) -> None: """Test the subst_path() method on nested substitution of strings. """ self.env.Append(L1 = ['a', 'b'], @@ -144,7 +144,7 @@ class subst_pathTestCase(unittest.TestCase): result = pl.subst_path(self.env, 'y', 'z') assert result == ('a', 'b', 'c', 'd', 'c', 'd'), result - def test_another_env(self): + def test_another_env(self) -> None: """Test the subst_path does lazy evaluation. """ pl = SCons.PathList.PathList(('$AAA', '$NULL')) @@ -156,7 +156,7 @@ class subst_pathTestCase(unittest.TestCase): class PathListCacheTestCase(unittest.TestCase): - def test_no_PathListCache(self): + def test_no_PathListCache(self) -> None: """Make sure the PathListCache class is not visible """ try: @@ -169,7 +169,7 @@ class PathListCacheTestCase(unittest.TestCase): class PathListTestCase(unittest.TestCase): - def test_PathList(self): + def test_PathList(self) -> None: """Test the PathList() entry point """ diff --git a/SCons/Platform/PlatformTests.py b/SCons/Platform/PlatformTests.py index ee0ab75..852c763 100644 --- a/SCons/Platform/PlatformTests.py +++ b/SCons/Platform/PlatformTests.py @@ -36,12 +36,12 @@ class Environment(collections.UserDict): def Detect(self, cmd): return cmd - def AppendENVPath(self, key, value): + def AppendENVPath(self, key, value) -> None: pass class PlatformTestCase(unittest.TestCase): - def test_Platform(self): + def test_Platform(self) -> None: """Test the Platform() function""" p = SCons.Platform.Platform('cygwin') assert str(p) == 'cygwin', p @@ -132,7 +132,7 @@ class PlatformTestCase(unittest.TestCase): SCons.Platform.Platform()(env) assert env != {}, env - def test_win32_no_arch_shell_variables(self): + def test_win32_no_arch_shell_variables(self) -> None: """ Test that a usable HOST_ARCH is available when neither: PROCESSOR_ARCHITEW6432 nor PROCESSOR_ARCHITECTURE @@ -160,7 +160,7 @@ class PlatformTestCase(unittest.TestCase): class TempFileMungeTestCase(unittest.TestCase): - def test_MAXLINELENGTH(self): + def test_MAXLINELENGTH(self) -> None: """ Test different values for MAXLINELENGTH with the same size command string to ensure that the temp file mechanism kicks in only at MAXLINELENGTH+1, or higher @@ -196,7 +196,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert cmd != defined_cmd, cmd - def test_TEMPFILEARGJOINBYTE(self): + def test_TEMPFILEARGJOINBYTE(self) -> None: """ Test argument join byte TEMPFILEARGJOINBYTE """ @@ -231,7 +231,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert file_content != env['TEMPFILEARGJOINBYTE'].join(['test','command','line']) - def test_TEMPFILEARGESCFUNC(self): + def test_TEMPFILEARGESCFUNC(self) -> None: """ Test a custom TEMPFILEARGESCFUNC """ @@ -261,7 +261,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert b"newarg" in file_content - def test_tempfilecreation_once(self): + def test_tempfilecreation_once(self) -> None: """ Init class with cmd, such that the fully expanded string reads "a test command line". @@ -287,7 +287,7 @@ class TempFileMungeTestCase(unittest.TestCase): class Attrs: pass - def __init__(self): + def __init__(self) -> None: self.attributes = self.Attrs() target = [Node()] @@ -300,7 +300,7 @@ class TempFileMungeTestCase(unittest.TestCase): class PlatformEscapeTestCase(unittest.TestCase): - def test_posix_escape(self): + def test_posix_escape(self) -> None: """ Check that paths with parens are escaped properly """ import SCons.Platform.posix diff --git a/SCons/Platform/__init__.py b/SCons/Platform/__init__.py index 3fa5a75..77eea5c 100644 --- a/SCons/Platform/__init__.py +++ b/SCons/Platform/__init__.py @@ -130,14 +130,14 @@ def DefaultToolList(platform, env): class PlatformSpec: - def __init__(self, name, generate): + def __init__(self, name, generate) -> None: self.name = name self.generate = generate def __call__(self, *args, **kw): return self.generate(*args, **kw) - def __str__(self): + def __str__(self) -> str: return self.name @@ -192,7 +192,7 @@ class TempFileMunge: env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func """ - def __init__(self, cmd, cmdstr = None): + def __init__(self, cmd, cmdstr = None) -> None: self.cmd = cmd self.cmdstr = cmdstr @@ -323,7 +323,7 @@ class TempFileMunge: return cmdlist - def _print_cmd_str(self, target, source, env, cmdstr): + def _print_cmd_str(self, target, source, env, cmdstr) -> None: # check if the user has specified a cmd line print function print_func = None try: diff --git a/SCons/Platform/aix.py b/SCons/Platform/aix.py index e5f34b4..3afe506 100644 --- a/SCons/Platform/aix.py +++ b/SCons/Platform/aix.py @@ -67,7 +67,7 @@ def get_xlc(env, xlc=None, packages=[]): xlcPath, sep, xlc = filename.rpartition('/') return (xlcPath, xlc, xlcVersion) -def generate(env): +def generate(env) -> None: posix.generate(env) #Based on AIX 5.2: ARG_MAX=24576 - 3000 for environment expansion env['MAXLINELENGTH'] = 21576 diff --git a/SCons/Platform/cygwin.py b/SCons/Platform/cygwin.py index 82e1d61..c62a668 100644 --- a/SCons/Platform/cygwin.py +++ b/SCons/Platform/cygwin.py @@ -40,7 +40,7 @@ if sys.platform == 'win32': r'C:\cygwin\bin' ] -def generate(env): +def generate(env) -> None: posix.generate(env) env['PROGPREFIX'] = '' diff --git a/SCons/Platform/darwin.py b/SCons/Platform/darwin.py index dcaf5c8..f17968b 100644 --- a/SCons/Platform/darwin.py +++ b/SCons/Platform/darwin.py @@ -32,7 +32,7 @@ from . import posix import os -def generate(env): +def generate(env) -> None: posix.generate(env) env['SHLIBSUFFIX'] = '.dylib' env['HOST_OS'] = 'darwin' diff --git a/SCons/Platform/hpux.py b/SCons/Platform/hpux.py index 642f1fe..9d796db 100644 --- a/SCons/Platform/hpux.py +++ b/SCons/Platform/hpux.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) #Based on HP-UX11i: ARG_MAX=2048000 - 3000 for environment expansion env['MAXLINELENGTH'] = 2045000 diff --git a/SCons/Platform/irix.py b/SCons/Platform/irix.py index 4d6be54..19f619b 100644 --- a/SCons/Platform/irix.py +++ b/SCons/Platform/irix.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) env['HOST_OS'] = 'irix' diff --git a/SCons/Platform/os2.py b/SCons/Platform/os2.py index 6b412ee..7394aa8 100644 --- a/SCons/Platform/os2.py +++ b/SCons/Platform/os2.py @@ -30,7 +30,7 @@ selection method. from . import win32 -def generate(env): +def generate(env) -> None: if 'ENV' not in env: env['ENV'] = {} env['OBJPREFIX'] = '' diff --git a/SCons/Platform/posix.py b/SCons/Platform/posix.py index 75b6c0b..55b00b4 100644 --- a/SCons/Platform/posix.py +++ b/SCons/Platform/posix.py @@ -74,7 +74,7 @@ def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr): env, stdout, stderr) -def generate(env): +def generate(env) -> None: # Bearing in mind we have python 2.4 as a baseline, we can just do this: spawn = subprocess_spawn pspawn = piped_env_spawn diff --git a/SCons/Platform/sunos.py b/SCons/Platform/sunos.py index 8692433..4aa1fff 100644 --- a/SCons/Platform/sunos.py +++ b/SCons/Platform/sunos.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) # Based on sunSparc 8:32bit # ARG_MAX=1048320 - 3000 for environment expansion diff --git a/SCons/Platform/virtualenv.py b/SCons/Platform/virtualenv.py index 2204a59..df7ad57 100644 --- a/SCons/Platform/virtualenv.py +++ b/SCons/Platform/virtualenv.py @@ -51,7 +51,7 @@ def _running_in_virtualenv(): (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)) -def _is_path_in(path, base): +def _is_path_in(path, base) -> bool: """Returns true if **path** is located under the **base** directory.""" if not path or not base: # empty path may happen, base too return False @@ -59,7 +59,7 @@ def _is_path_in(path, base): return (not rp.startswith(os.path.pardir)) and (not rp == os.path.curdir) -def _inject_venv_variables(env): +def _inject_venv_variables(env) -> None: if 'ENV' not in env: env['ENV'] = {} ENV = env['ENV'] @@ -69,7 +69,7 @@ def _inject_venv_variables(env): except KeyError: pass -def _inject_venv_path(env, path_list=None): +def _inject_venv_path(env, path_list=None) -> None: """Modify environment such that SCons will take into account its virtualenv when running external tools.""" if path_list is None: @@ -86,7 +86,7 @@ def select_paths_in_venv(path_list): return [path for path in path_list if IsInVirtualenv(path)] -def ImportVirtualenv(env): +def ImportVirtualenv(env) -> None: """Copies virtualenv-related environment variables from OS environment to ``env['ENV']`` and prepends virtualenv's PATH to ``env['ENV']['PATH']``. """ diff --git a/SCons/Platform/virtualenvTests.py b/SCons/Platform/virtualenvTests.py index c840749..9591063 100644 --- a/SCons/Platform/virtualenvTests.py +++ b/SCons/Platform/virtualenvTests.py @@ -34,7 +34,7 @@ class Environment(collections.UserDict): def Detect(self, cmd): return cmd - def AppendENVPath(self, key, value): + def AppendENVPath(self, key, value) -> None: if SCons.Util.is_List(value): value = os.path.pathsep.join(value) if 'ENV' not in self: @@ -45,7 +45,7 @@ class Environment(collections.UserDict): else: self['ENV'][key] = os.path.pathsep.join([current, value]) - def PrependENVPath(self, key, value): + def PrependENVPath(self, key, value) -> None: if SCons.Util.is_List(value): value = os.path.pathsep.join(value) if 'ENV' not in self: @@ -58,12 +58,12 @@ class Environment(collections.UserDict): class SysPrefixes: """Used to temporarily mock sys.prefix, sys.real_prefix and sys.base_prefix""" - def __init__(self, prefix, real_prefix=None, base_prefix=None): + def __init__(self, prefix, real_prefix=None, base_prefix=None) -> None: self._prefix = prefix self._real_prefix = real_prefix self._base_prefix = base_prefix - def start(self): + def start(self) -> None: self._store() sys.prefix = self._prefix if self._real_prefix is None: @@ -77,7 +77,7 @@ class SysPrefixes: else: sys.base_prefix = self._base_prefix - def stop(self): + def stop(self) -> None: self._restore() def __enter__(self): @@ -85,10 +85,10 @@ class SysPrefixes: attrs = ('prefix', 'real_prefix', 'base_prefix') return {k: getattr(sys, k) for k in attrs if hasattr(sys, k)} - def __exit__(self, *args): + def __exit__(self, *args) -> None: self.stop() - def _store(self): + def _store(self) -> None: s = dict() if hasattr(sys, 'real_prefix'): s['real_prefix'] = sys.real_prefix @@ -97,7 +97,7 @@ class SysPrefixes: s['prefix'] = sys.prefix self._stored = s - def _restore(self): + def _restore(self) -> None: s = self._stored if 'real_prefix' in s: sys.real_prefix = s['real_prefix'] @@ -117,7 +117,7 @@ def _p(p): class _is_path_in_TestCase(unittest.TestCase): - def test_false(self): + def test_false(self) -> None: for args in [ ('',''), ('', _p('/foo/bar')), (_p('/foo/bar'), ''), @@ -127,7 +127,7 @@ class _is_path_in_TestCase(unittest.TestCase): (_p('foo'), _p('foo/bar')) ]: assert SCons.Platform.virtualenv._is_path_in(*args) is False, "_is_path_in(%r, %r) should be False" % args - def test__true(self): + def test__true(self) -> None: for args in [ (_p('/foo'), _p('/')), (_p('/foo/bar'), _p('/foo')), (_p('/foo/bar/geez'), _p('/foo/bar')), @@ -137,7 +137,7 @@ class _is_path_in_TestCase(unittest.TestCase): assert SCons.Platform.virtualenv._is_path_in(*args) is True, "_is_path_in(%r, %r) should be True" % args class IsInVirtualenvTestCase(unittest.TestCase): - def test_false(self): + def test_false(self) -> None: # "without wirtualenv" - always false with SysPrefixes(_p('/prefix')): for p in [ _p(''), @@ -166,7 +166,7 @@ class IsInVirtualenvTestCase(unittest.TestCase): _p('/virtualenv/bleah') ]: assert SCons.Platform.virtualenv.IsInVirtualenv(p) is False, "IsInVirtualenv(%r) should be False" % p - def test_true(self): + def test_true(self) -> None: # "with virtualenv" with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): for p in [ _p('/virtualenv/prefix/foo'), @@ -189,22 +189,22 @@ class _inject_venv_pathTestCase(unittest.TestCase): _p('/usr/bin'), _p('/opt/bin') ] - def test_with_path_string(self): + def test_with_path_string(self) -> None: env = Environment() path_string = os.path.pathsep.join(self.path_list()) with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): SCons.Platform.virtualenv._inject_venv_path(env, path_string) assert env['ENV']['PATH'] == _p('/virtualenv/prefix/bin'), env['ENV']['PATH'] - def test_with_path_list(self): + def test_with_path_list(self) -> None: env = Environment() with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): SCons.Platform.virtualenv._inject_venv_path(env, self.path_list()) assert env['ENV']['PATH'] == _p('/virtualenv/prefix/bin'), env['ENV']['PATH'] class VirtualenvTestCase(unittest.TestCase): - def test_none(self): - def _msg(given): + def test_none(self) -> None: + def _msg(given) -> str: return "Virtualenv() should be None, not %s" % repr(given) with SysPrefixes(_p('/prefix')): @@ -214,8 +214,8 @@ class VirtualenvTestCase(unittest.TestCase): ve = SCons.Platform.virtualenv.Virtualenv() assert ve is None, _msg(ve) - def test_not_none(self): - def _msg(expected, given): + def test_not_none(self) -> None: + def _msg(expected, given) -> str: return "Virtualenv() should == %r, not %s" % (_p(expected), repr(given)) with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): diff --git a/SCons/Platform/win32.py b/SCons/Platform/win32.py index 990794f..c9fcd95 100644 --- a/SCons/Platform/win32.py +++ b/SCons/Platform/win32.py @@ -58,7 +58,7 @@ if False: shutil.copy2 = CopyFile - def win_api_copyfile(src,dst): + def win_api_copyfile(src,dst) -> None: CopyFile(src,dst) os.utime(dst) @@ -283,7 +283,7 @@ class ArchDefinition: Determine which windows CPU were running on. A class for defining architecture-specific settings and logic. """ - def __init__(self, arch, synonyms=[]): + def __init__(self, arch, synonyms=[]) -> None: self.arch = arch self.synonyms = synonyms diff --git a/SCons/SConf.py b/SCons/SConf.py index 136be27..daece1a 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -61,7 +61,7 @@ SCons.Conftest.LogErrorMessages = 0 build_type = None build_types = ['clean', 'help'] -def SetBuildType(buildtype): +def SetBuildType(buildtype) -> None: global build_type build_type = buildtype @@ -73,7 +73,7 @@ FORCE=1 # force all tests to be rebuilt CACHE=2 # force all tests to be taken from cache (raise an error, if necessary) cache_mode = AUTO -def _set_conftest_node(node): +def _set_conftest_node(node) -> None: node.attributes.conftest_node = 1 def SetCacheMode(mode): @@ -90,7 +90,7 @@ def SetCacheMode(mode): raise ValueError("SCons.SConf.SetCacheMode: Unknown mode " + mode) progress_display = SCons.Util.display # will be overwritten by SCons.Script -def SetProgressDisplay(display): +def SetProgressDisplay(display) -> None: """Set the progress display to use (called from SCons.Script)""" global progress_display progress_display = display @@ -102,7 +102,7 @@ _ac_config_logs = {} # all config.log files created in this build _ac_config_hs = {} # all config.h files created in this build sconf_global = None # current sconf object -def _createConfigH(target, source, env): +def _createConfigH(target, source, env) -> None: t = open(str(target[0]), "w") defname = re.sub('[^A-Za-z0-9_]', '_', str(target[0]).upper()) t.write("""#ifndef %(DEFNAME)s_SEEN @@ -119,13 +119,13 @@ def _stringConfigH(target, source, env): return "scons: Configure: creating " + str(target[0]) -def NeedConfigHBuilder(): +def NeedConfigHBuilder() -> bool: if len(_ac_config_hs) == 0: return False else: return True -def CreateConfigHBuilder(env): +def CreateConfigHBuilder(env) -> None: """Called if necessary just before the building targets phase begins.""" action = SCons.Action.Action(_createConfigH, _stringConfigH) @@ -141,13 +141,13 @@ SCons.Warnings.enableWarningClass(SConfWarning) # some error definitions class SConfError(SCons.Errors.UserError): - def __init__(self,msg): + def __init__(self,msg) -> None: super().__init__(msg) class ConfigureDryRunError(SConfError): """Raised when a file or directory needs to be updated during a Configure process, but the user requested a dry-run""" - def __init__(self,target): + def __init__(self,target) -> None: if not isinstance(target, SCons.Node.FS.File): msg = 'Cannot create configure directory "%s" within a dry-run.' % str(target) else: @@ -157,12 +157,12 @@ class ConfigureDryRunError(SConfError): class ConfigureCacheError(SConfError): """Raised when a use explicitely requested the cache feature, but the test is run the first time.""" - def __init__(self,target): + def __init__(self,target) -> None: super().__init__('"%s" is not yet built and cache is forced.' % str(target)) # define actions for building text files -def _createSource(target, source, env): +def _createSource(target, source, env) -> None: fd = open(str(target[0]), "w") fd.write(source[0].get_contents().decode()) fd.close() @@ -180,11 +180,11 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo): """ __slots__ = ('result', 'string') - def __init__(self): + def __init__(self) -> None: self.result = None # -> 0/None -> no error, != 0 error self.string = None # the stdout / stderr output when building the target - def set_build_result(self, result, string): + def set_build_result(self, result, string) -> None: self.result = result self.string = string @@ -193,11 +193,11 @@ class Streamer: """ 'Sniffer' for a file-like writable object. Similar to the unix tool tee. """ - def __init__(self, orig): + def __init__(self, orig) -> None: self.orig = orig self.s = io.StringIO() - def write(self, str): + def write(self, str) -> None: if self.orig: self.orig.write(str) try: @@ -206,7 +206,7 @@ class Streamer: # "unicode argument expected" bug in IOStream (python 2.x) self.s.write(str.decode()) - def writelines(self, lines): + def writelines(self, lines) -> None: for l in lines: self.write(l + '\n') @@ -216,7 +216,7 @@ class Streamer: """ return self.s.getvalue() - def flush(self): + def flush(self) -> None: if self.orig: self.orig.flush() self.s.flush() @@ -229,11 +229,11 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): """ non_sconf_nodes = set() - def display(self, message): + def display(self, message) -> None: if sconf_global.logstream: sconf_global.logstream.write("scons: Configure: " + message + "\n") - def display_cached_string(self, bi): + def display_cached_string(self, bi) -> None: """ Logs the original builder messages, given the SConfBuildInfo instance bi. @@ -378,7 +378,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): sconsign.set_entry(t.name, sconsign_entry) sconsign.merge() - def make_ready_current(self): + def make_ready_current(self) -> None: # We're overriding make_ready_current() call to add to the list # of nodes used by this task, filtering out any nodes created # by the checker for it's own purpose. @@ -386,7 +386,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): super().make_ready_current() make_ready = make_ready_current - def postprocess(self): + def postprocess(self) -> None: # We're done executing this task, so now we'll go through all the # nodes used by this task which aren't nodes created for # Configure checkers, but rather are existing or built files @@ -410,8 +410,8 @@ class SConfBase: SConf run, we need to explicitly cache this error. """ - def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR', - log_file='$CONFIGURELOG', config_h = None, _depth = 0): + def __init__(self, env, custom_tests = {}, conf_dir: str='$CONFIGUREDIR', + log_file: str='$CONFIGURELOG', config_h = None, _depth: int = 0) -> None: """Constructor. Pass additional tests in the custom_tests-dictionary, e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest defines a custom test. @@ -432,7 +432,7 @@ class SConfBase: # and keep the build state consistent. def force_build(dependency, target, prev_ni, repo_node=None, - env_decider=env.decide_source): + env_decider=env.decide_source) -> bool: try: env_decider(dependency, target, prev_ni, repo_node) except Exception as e: @@ -496,7 +496,7 @@ class SConfBase: return self.env - def Define(self, name, value = None, comment = None): + def Define(self, name, value = None, comment = None) -> None: """ Define a pre processor symbol name, with the optional given value in the current config header. @@ -602,7 +602,7 @@ class SConfBase: """ return self.pspawn(sh, escape, cmd, args, env, self.logstream, self.logstream) - def TryBuild(self, builder, text=None, extension=""): + def TryBuild(self, builder, text=None, extension: str=""): """Low level TryBuild implementation. Normally you don't need to call that - you can use TryCompile / TryLink / TryRun instead """ @@ -673,7 +673,7 @@ class SConfBase: return result - def TryAction(self, action, text = None, extension = ""): + def TryAction(self, action, text = None, extension: str = ""): """Tries to execute the given action with optional source file contents and optional source file extension , Returns the status (0 : failed, 1 : ok) and the contents of the @@ -724,7 +724,7 @@ class SConfBase: class TestWrapper: """A wrapper around Tests (to ensure sanity)""" - def __init__(self, test, sconf): + def __init__(self, test, sconf) -> None: self.test = test self.sconf = sconf def __call__(self, *args, **kw): @@ -737,12 +737,12 @@ class SConfBase: context.Result("error: no result") return ret - def AddTest(self, test_name, test_instance): + def AddTest(self, test_name, test_instance) -> None: """Adds test_class to this SConf instance. It can be called with self.test_name(...)""" setattr(self, test_name, SConfBase.TestWrapper(test_instance, self)) - def AddTests(self, tests): + def AddTests(self, tests) -> None: """Adds all the tests given in the tests dictionary to this SConf instance """ @@ -758,7 +758,7 @@ class SConfBase: if not os.path.isdir( dirName ): os.makedirs( dirName ) - def _startup(self): + def _startup(self) -> None: """Private method. Set up logstream, and set the environment variables necessary for a piped build """ @@ -781,7 +781,7 @@ class SConfBase: log_mode = "w" fp = open(str(self.logfile), log_mode) - def conflog_cleanup(logf): + def conflog_cleanup(logf) -> None: logf.close() atexit.register(conflog_cleanup, fp) @@ -855,7 +855,7 @@ class CheckContext: changed. """ - def __init__(self, sconf): + def __init__(self, sconf) -> None: """Constructor. Pass the corresponding SConf instance.""" self.sconf = sconf self.did_show_result = 0 @@ -873,7 +873,7 @@ class CheckContext: # correctly. Note that we can't use Conftest.py's support for config.h, # cause we will need to specify a builder for the config.h file ... - def Message(self, text): + def Message(self, text) -> None: """Inform about what we are doing right now, e.g. 'Checking for SOMETHING ... ' """ @@ -881,7 +881,7 @@ class CheckContext: self.sconf.cached = 1 self.did_show_result = 0 - def Result(self, res): + def Result(self, res) -> None: """Inform about the result of the test. If res is not a string, displays 'yes' or 'no' depending on whether res is evaluated as true or false. The result is only displayed when self.did_show_result is not set. @@ -923,17 +923,17 @@ class CheckContext: #### Stuff used by Conftest.py (look there for explanations). - def BuildProg(self, text, ext): + def BuildProg(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. return not self.TryBuild(self.env.Program, text, ext) - def CompileProg(self, text, ext): + def CompileProg(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. return not self.TryBuild(self.env.Object, text, ext) - def CompileSharedObject(self, text, ext): + def CompileSharedObject(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $SHCC, $CPPFLAGS, etc. return not self.TryBuild(self.env.SharedObject, text, ext) @@ -944,7 +944,7 @@ class CheckContext: st, out = self.TryRun(text, ext) return not st, out - def AppendLIBS(self, lib_name_list, unique=False): + def AppendLIBS(self, lib_name_list, unique: bool=False): oldLIBS = self.env.get( 'LIBS', [] ) if unique: self.env.AppendUnique(LIBS = lib_name_list) @@ -952,7 +952,7 @@ class CheckContext: self.env.Append(LIBS = lib_name_list) return oldLIBS - def PrependLIBS(self, lib_name_list, unique=False): + def PrependLIBS(self, lib_name_list, unique: bool=False): oldLIBS = self.env.get( 'LIBS', [] ) if unique: self.env.PrependUnique(LIBS = lib_name_list) @@ -965,7 +965,7 @@ class CheckContext: self.env.Replace(LIBS = val) return oldLIBS - def Display(self, msg): + def Display(self, msg) -> None: if self.sconf.cached: # We assume that Display is called twice for each test here # once for the Checking for ... message and once for the result. @@ -975,7 +975,7 @@ class CheckContext: progress_display(msg, append_newline=0) self.Log("scons: Configure: " + msg + "\n") - def Log(self, msg): + def Log(self, msg) -> None: if self.sconf.logstream is not None: self.sconf.logstream.write(msg) @@ -995,39 +995,39 @@ def SConf(*args, **kw): return SCons.Util.Null() -def CheckFunc(context, function_name, header = None, language = None): +def CheckFunc(context, function_name, header = None, language = None) -> bool: res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language) context.did_show_result = 1 return not res -def CheckType(context, type_name, includes = "", language = None): +def CheckType(context, type_name, includes: str = "", language = None) -> bool: res = SCons.Conftest.CheckType(context, type_name, header = includes, language = language) context.did_show_result = 1 return not res -def CheckTypeSize(context, type_name, includes = "", language = None, expect = None): +def CheckTypeSize(context, type_name, includes: str = "", language = None, expect = None): res = SCons.Conftest.CheckTypeSize(context, type_name, header = includes, language = language, expect = expect) context.did_show_result = 1 return res -def CheckDeclaration(context, declaration, includes = "", language = None): +def CheckDeclaration(context, declaration, includes: str = "", language = None) -> bool: res = SCons.Conftest.CheckDeclaration(context, declaration, includes = includes, language = language) context.did_show_result = 1 return not res -def CheckMember(context, aggregate_member, header = None, language = None): +def CheckMember(context, aggregate_member, header = None, language = None) -> bool: '''Returns the status (False : failed, True : ok).''' res = SCons.Conftest.CheckMember(context, aggregate_member, header=header, language=language) context.did_show_result = 1 return not res -def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'): +def createIncludesFromHeaders(headers, leaveLast, include_quotes: str = '""'): # used by CheckHeader and CheckLibWithHeader to produce C - #include # statements from the specified header (list) if not SCons.Util.is_List(headers): @@ -1043,7 +1043,7 @@ def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'): % (include_quotes[0], s, include_quotes[1])) return ''.join(l), lastHeader -def CheckHeader(context, header, include_quotes = '<>', language = None): +def CheckHeader(context, header, include_quotes: str = '<>', language = None) -> bool: """ A test for a C or C++ header file. """ @@ -1055,29 +1055,29 @@ def CheckHeader(context, header, include_quotes = '<>', language = None): context.did_show_result = 1 return not res -def CheckCC(context): +def CheckCC(context) -> bool: res = SCons.Conftest.CheckCC(context) context.did_show_result = 1 return not res -def CheckCXX(context): +def CheckCXX(context) -> bool: res = SCons.Conftest.CheckCXX(context) context.did_show_result = 1 return not res -def CheckSHCC(context): +def CheckSHCC(context) -> bool: res = SCons.Conftest.CheckSHCC(context) context.did_show_result = 1 return not res -def CheckSHCXX(context): +def CheckSHCXX(context) -> bool: res = SCons.Conftest.CheckSHCXX(context) context.did_show_result = 1 return not res # Bram: Make this function obsolete? CheckHeader() is more generic. -def CheckCHeader(context, header, include_quotes = '""'): +def CheckCHeader(context, header, include_quotes: str = '""'): """ A test for a C header file. """ @@ -1086,16 +1086,16 @@ def CheckCHeader(context, header, include_quotes = '""'): # Bram: Make this function obsolete? CheckHeader() is more generic. -def CheckCXXHeader(context, header, include_quotes = '""'): +def CheckCXXHeader(context, header, include_quotes: str = '""'): """ A test for a C++ header file. """ return CheckHeader(context, header, include_quotes, language = "C++") -def CheckLib(context, library = None, symbol = "main", - header = None, language = None, autoadd=True, - append=True, unique=False) -> bool: +def CheckLib(context, library = None, symbol: str = "main", + header = None, language = None, autoadd: bool=True, + append: bool=True, unique: bool=False) -> bool: """ A test for a library. See also CheckLibWithHeader. Note that library may also be None to test whether the given symbol @@ -1119,7 +1119,7 @@ def CheckLib(context, library = None, symbol = "main", # Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H. def CheckLibWithHeader(context, libs, header, language, - call = None, autoadd=True, append=True, unique=False) -> bool: + call = None, autoadd: bool=True, append: bool=True, unique: bool=False) -> bool: # ToDo: accept path for library. Support system header files. """ Another (more sophisticated) test for a library. diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index 5d09848..e8e0fc7 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -40,13 +40,13 @@ else: class SConfTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: # we always want to start with a clean directory self.save_cwd = os.getcwd() self.test = TestCmd.TestCmd(workdir = '') os.chdir(self.test.workpath('')) - def tearDown(self): + def tearDown(self) -> None: self.test.cleanup() import SCons.SConsign SCons.SConsign.Reset() @@ -91,7 +91,7 @@ class SConfTestCase(unittest.TestCase): global existing_lib existing_lib = 'm' - def _baseTryXXX(self, TryFunc): + def _baseTryXXX(self, TryFunc) -> None: # TryCompile and TryLink are much the same, so we can test them # in one method, we pass the function as a string ('TryCompile', # 'TryLink'), so we are aware of reloading modules. @@ -148,7 +148,7 @@ class SConfTestCase(unittest.TestCase): finally: sconf.Finish() - def test_TryBuild(self): + def test_TryBuild(self) -> None: """Test SConf.TryBuild """ # 1 test that we can try a builder that returns a list of nodes @@ -160,14 +160,14 @@ class SConfTestCase(unittest.TestCase): import SCons.Node class MyAction: - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> str: return 'MyBuilder-MyAction $SOURCE $TARGET' class Attrs: __slots__ = ('shared', '__dict__') class MyBuilder(SCons.Builder.BuilderBase): - def __init__(self): + def __init__(self) -> None: self.prefix = '' self.suffix = '' # need action because temporary file name uses hash of actions get_contents() @@ -175,7 +175,7 @@ class SConfTestCase(unittest.TestCase): def __call__(self, env, target, source, *args, **kw): class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.state = SCons.Node.no_state self.waiting_parents = set() @@ -185,45 +185,45 @@ class SConfTestCase(unittest.TestCase): self.attributes = Attrs() def disambiguate(self): return self - def has_builder(self): + def has_builder(self) -> int: return 1 - def add_pre_action(self, *actions): + def add_pre_action(self, *actions) -> None: pass - def add_post_action(self, *actions): + def add_post_action(self, *actions) -> None: pass - def children(self, scan = 1): + def children(self, scan: int = 1): return [] def get_state(self): return self.state - def set_state(self, state): + def set_state(self, state) -> None: self.state = state def alter_targets(self): return [], None def depends_on(self, nodes): return None - def postprocess(self): + def postprocess(self) -> None: pass - def clear(self): + def clear(self) -> None: pass def is_up_to_date(self): return None - def prepare(self): + def prepare(self) -> None: pass - def push_to_cache(self): + def push_to_cache(self) -> None: pass - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> int: return 0 - def build(self, **kw): + def build(self, **kw) -> None: return - def built(self): + def built(self) -> None: pass - def get_stored_info(self): + def get_stored_info(self) -> None: pass - def is_conftest(self): + def is_conftest(self) -> bool: return True def get_executor(self): class Executor: - def __init__(self, targets): + def __init__(self, targets) -> None: self.targets = targets def get_all_targets(self): return self.targets @@ -235,17 +235,17 @@ class SConfTestCase(unittest.TestCase): finally: sconf.Finish() - def test_TryCompile(self): + def test_TryCompile(self) -> None: """Test SConf.TryCompile """ self._baseTryXXX( "TryCompile" ) #self.SConf.SConf.TryCompile ) - def test_TryLink(self): + def test_TryLink(self) -> None: """Test SConf.TryLink """ self._baseTryXXX( "TryLink" ) #self.SConf.SConf.TryLink ) - def test_TryRun(self): + def test_TryRun(self) -> None: """Test SConf.TryRun """ def checks(sconf): @@ -293,14 +293,14 @@ int main(void) { assert secondOcc is None, log - def test_TryAction(self): + def test_TryAction(self) -> None: """Test SConf.TryAction """ def actionOK(target, source, env): with open(str(target[0]), "w") as f: f.write("RUN OK\n") return None - def actionFAIL(target, source, env): + def actionFAIL(target, source, env) -> int: return 1 @@ -318,7 +318,7 @@ int main(void) { finally: sconf.Finish() - def _test_check_compilers(self, comp, func, name): + def _test_check_compilers(self, comp, func, name) -> None: """This is the implementation for CheckCC and CheckCXX tests.""" from copy import deepcopy @@ -413,7 +413,7 @@ int main(void) { sconf.Finish() - def test_CheckHeader(self): + def test_CheckHeader(self) -> None: """Test SConf.CheckHeader() """ self._resetSConfState() @@ -434,7 +434,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckCHeader(self): + def test_CheckCHeader(self) -> None: """Test SConf.CheckCHeader() """ self._resetSConfState() @@ -454,7 +454,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckCXXHeader(self): + def test_CheckCXXHeader(self) -> None: """Test SConf.CheckCXXHeader() """ self._resetSConfState() @@ -474,7 +474,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckLib(self): + def test_CheckLib(self) -> None: """Test SConf.CheckLib() """ self._resetSConfState() @@ -565,7 +565,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckLibWithHeader(self): + def test_CheckLibWithHeader(self) -> None: """Test SConf.CheckLibWithHeader() """ self._resetSConfState() @@ -664,7 +664,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckFunc(self): + def test_CheckFunc(self) -> None: """Test SConf.CheckFunc() """ self._resetSConfState() @@ -684,7 +684,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckProg(self): + def test_CheckProg(self) -> None: """Test SConf.CheckProg() """ self._resetSConfState() @@ -708,7 +708,7 @@ int main(void) { sconf.Finish() - def test_Define(self): + def test_Define(self) -> None: """Test SConf.Define() """ self._resetSConfState() @@ -744,7 +744,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckTypeSize(self): + def test_CheckTypeSize(self) -> None: """Test SConf.CheckTypeSize() """ self._resetSConfState() @@ -778,7 +778,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckDeclaration(self): + def test_CheckDeclaration(self) -> None: """Test SConf.CheckDeclaration() """ self._resetSConfState() @@ -799,7 +799,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckMember(self): + def test_CheckMember(self) -> None: """Test SConf.CheckMember() """ self._resetSConfState() @@ -820,7 +820,7 @@ int main(void) { sconf.Finish() - def test_(self): + def test_(self) -> None: """Test SConf.CheckType() """ self._resetSConfState() @@ -837,7 +837,7 @@ int main(void) { finally: sconf.Finish() - def test_CustomChecks(self): + def test_CustomChecks(self) -> None: """Test Custom Checks """ def CheckCustom(test): diff --git a/SCons/SConsign.py b/SCons/SConsign.py index ecca391..860d40b 100644 --- a/SCons/SConsign.py +++ b/SCons/SConsign.py @@ -35,7 +35,7 @@ from SCons.compat import PICKLE_PROTOCOL from SCons.Util import print_time -def corrupt_dblite_warning(filename): +def corrupt_dblite_warning(filename) -> None: SCons.Warnings.warn( SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt .sconsign file: %s" % filename, @@ -106,7 +106,7 @@ def Get_DataBase(dir): raise -def Reset(): +def Reset() -> None: """Reset global state. Used by unit tests that end up using SConsign multiple times to get a clean slate for each test.""" global sig_files, DB_sync_list @@ -116,7 +116,7 @@ def Reset(): normcase = os.path.normcase -def write(): +def write() -> None: global sig_files if print_time(): @@ -154,16 +154,16 @@ class SConsignEntry: __slots__ = ("binfo", "ninfo", "__weakref__") current_version_id = 2 - def __init__(self): + def __init__(self) -> None: # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. #_version_id = self.current_version_id pass - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: self.binfo.convert_to_sconsign() - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: self.binfo.convert_from_sconsign(dir, name) def __getstate__(self): @@ -180,7 +180,7 @@ class SConsignEntry: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: for key, value in state.items(): if key not in ('_version_id', '__weakref__'): setattr(self, key, value) @@ -195,7 +195,7 @@ class Base: methods for fetching and storing the individual bits of information that make up signature entry. """ - def __init__(self): + def __init__(self) -> None: self.entries = {} self.dirty = False self.to_be_merged = {} @@ -206,26 +206,26 @@ class Base: """ return self.entries[filename] - def set_entry(self, filename, obj): + def set_entry(self, filename, obj) -> None: """ Set the entry. """ self.entries[filename] = obj self.dirty = True - def do_not_set_entry(self, filename, obj): + def do_not_set_entry(self, filename, obj) -> None: pass - def store_info(self, filename, node): + def store_info(self, filename, node) -> None: entry = node.get_stored_info() entry.binfo.merge(node.get_binfo()) self.to_be_merged[filename] = node self.dirty = True - def do_not_store_info(self, filename, node): + def do_not_store_info(self, filename, node) -> None: pass - def merge(self): + def merge(self) -> None: for key, node in self.to_be_merged.items(): entry = node.get_stored_info() try: @@ -247,7 +247,7 @@ class DB(Base): from a global .sconsign.db* file--the actual file suffix is determined by the database module. """ - def __init__(self, dir): + def __init__(self, dir) -> None: super().__init__() self.dir = dir @@ -287,7 +287,7 @@ class DB(Base): global sig_files sig_files.append(self) - def write(self, sync=1): + def write(self, sync: int=1) -> None: if not self.dirty: return @@ -315,7 +315,7 @@ class DB(Base): class Dir(Base): - def __init__(self, fp=None, dir=None): + def __init__(self, fp=None, dir=None) -> None: """ fp - file pointer to read entries from """ @@ -338,7 +338,7 @@ class DirFile(Dir): """ Encapsulates reading and writing a per-directory .sconsign file. """ - def __init__(self, dir): + def __init__(self, dir) -> None: """ dir - the directory for the file """ @@ -367,7 +367,7 @@ class DirFile(Dir): global sig_files sig_files.append(self) - def write(self, sync=1): + def write(self, sync: int=1) -> None: """ Write the .sconsign file to disk. @@ -431,7 +431,7 @@ class DirFile(Dir): ForDirectory = DB -def File(name, dbm_module=None): +def File(name, dbm_module=None) -> None: """ Arrange for all signatures to be stored in a global .sconsign.db* file. diff --git a/SCons/SConsignTests.py b/SCons/SConsignTests.py index e9f2071..84bc200 100644 --- a/SCons/SConsignTests.py +++ b/SCons/SConsignTests.py @@ -31,25 +31,25 @@ import SCons.SConsign from SCons.Util import get_hash_format, get_current_hash_algorithm_used class BuildInfo: - def merge(self, object): + def merge(self, object) -> None: pass class DummySConsignEntry: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.binfo = BuildInfo() - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: self.c_to_s = 1 - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: self.c_from_s = 1 class FS: - def __init__(self, top): + def __init__(self, top) -> None: self.Top = top self.Top.repositories = [] class DummyNode: - def __init__(self, path='not_a_valid_path', binfo=None): + def __init__(self, path: str='not_a_valid_path', binfo=None) -> None: self.path = path self.tpath = path self.fs = FS(self) @@ -64,18 +64,18 @@ class DummyNode: return self.tpath class SConsignTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.save_cwd = os.getcwd() self.test = TestCmd.TestCmd(workdir = '') os.chdir(self.test.workpath('')) - def tearDown(self): + def tearDown(self) -> None: self.test.cleanup() SCons.SConsign.Reset() os.chdir(self.save_cwd) class BaseTestCase(SConsignTestCase): - def test_Base(self): + def test_Base(self) -> None: aaa = DummySConsignEntry('aaa') bbb = DummySConsignEntry('bbb') bbb.arg1 = 'bbb arg1' @@ -216,7 +216,7 @@ class BaseTestCase(SConsignTestCase): class SConsignDBTestCase(SConsignTestCase): - def test_SConsignDB(self): + def test_SConsignDB(self) -> None: save_DataBase = SCons.SConsign.DataBase SCons.SConsign.DataBase = {} try: @@ -262,7 +262,7 @@ class SConsignDBTestCase(SConsignTestCase): class SConsignDirFileTestCase(SConsignTestCase): - def test_SConsignDirFile(self): + def test_SConsignDirFile(self) -> None: bi_foo = DummySConsignEntry('foo') bi_bar = DummySConsignEntry('bar') @@ -291,7 +291,7 @@ class SConsignDirFileTestCase(SConsignTestCase): class SConsignFileTestCase(SConsignTestCase): - def test_SConsignFile(self): + def test_SConsignFile(self) -> None: test = self.test file = test.workpath('sconsign_file') @@ -319,9 +319,9 @@ class SConsignFileTestCase(SConsignTestCase): self.name = name self.mode = mode return self - def __getitem__(self, key): + def __getitem__(self, key) -> None: pass - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: pass fake_dbm = Fake_DBM() @@ -343,7 +343,7 @@ class SConsignFileTestCase(SConsignTestCase): class writeTestCase(SConsignTestCase): - def test_write(self): + def test_write(self) -> None: test = self.test file = test.workpath('sconsign_file') @@ -351,12 +351,12 @@ class writeTestCase(SConsignTestCase): class Fake_DBM: def __getitem__(self, key): return None - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: pass def open(self, name, mode): self.sync_count = 0 return self - def sync(self): + def sync(self) -> None: self.sync_count = self.sync_count + 1 fake_dbm = Fake_DBM() diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index 31ab7e6..5fa1bbb 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -41,11 +41,11 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): by Nodes, not strings; 2) we can keep track of the files that are missing. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.missing = [] - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = SCons.Util.UniqueList([fname]) def finalize_result(self, fname): @@ -131,7 +131,7 @@ class SConsCPPScannerWrapper: evaluation of #if/#ifdef/#else/#elif lines. """ - def __init__(self, name, variable): + def __init__(self, name, variable) -> None: self.name = name self.path = FindPathDirs(variable) @@ -185,12 +185,12 @@ class SConsCPPConditionalScanner(SCons.cpp.PreProcessor): missing. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.missing = [] self._known_paths = [] - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = SCons.Util.UniqueList([fname]) def find_include_file(self, t): @@ -228,7 +228,7 @@ class SConsCPPConditionalScannerWrapper: evaluation of #if/#ifdef/#else/#elif lines. """ - def __init__(self, name, variable): + def __init__(self, name, variable) -> None: self.name = name self.path = FindPathDirs(variable) diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index 0f62198..6860a10 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -201,7 +201,7 @@ test.write("f5b.h", "\n") # define some helpers: class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -241,7 +241,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -250,7 +250,7 @@ def deps_match(self, deps, headers): # define some tests: class CScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -260,7 +260,7 @@ class CScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find a file in a CPPPATH directory""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() @@ -270,7 +270,7 @@ class CScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() @@ -280,7 +280,7 @@ class CScannerTestCase3(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories""" env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() @@ -290,7 +290,7 @@ class CScannerTestCase4(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Make sure files in repositories will get scanned""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -315,7 +315,7 @@ class CScannerTestCase5(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find a same-named file in different directories when CPPPATH changes""" env1 = DummyEnvironment(CPPPATH=[test.workpath("d1")]) env2 = DummyEnvironment(CPPPATH=[test.workpath("d1/d2")]) @@ -330,7 +330,7 @@ class CScannerTestCase6(unittest.TestCase): deps_match(self, deps2, headers2) class CScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in a subdirectory relative to the current directory""" env = DummyEnvironment(CPPPATH=["include"]) s = SCons.Scanner.C.CScanner() @@ -347,11 +347,11 @@ class CScannerTestCase8(unittest.TestCase): deps_match(self, deps2, headers2) class CScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Generate a warning when we can't find a #included file""" SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -372,7 +372,7 @@ class CScannerTestCase9(unittest.TestCase): test.unlink('fa.h') class CScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in the local directory when the scanned file is elsewhere""" fs = SCons.Node.FS.FS(test.workpath('')) fs.chdir(fs.Dir('include')) @@ -387,7 +387,7 @@ class CScannerTestCase10(unittest.TestCase): test.unlink('include/fa.cpp') class CScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Handle dependencies on a derived .h file in a non-existent directory""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) @@ -407,7 +407,7 @@ class CScannerTestCase11(unittest.TestCase): os.chdir(test.workpath('')) class CScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in VariantDir() directories""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) @@ -429,7 +429,7 @@ class CScannerTestCase12(unittest.TestCase): os.chdir(test.workpath('')) class CScannerTestCase13(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in directories named in a substituted environment variable""" class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): @@ -445,7 +445,7 @@ class CScannerTestCase13(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase14(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files when there's no space between "#include" and the name""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -455,7 +455,7 @@ class CScannerTestCase14(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase15(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Verify scanner initialization with the suffixes in $CPPSUFFIXES""" suffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", @@ -468,7 +468,7 @@ class CScannerTestCase15(unittest.TestCase): class CConditionalScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CConditionalScanner() @@ -479,7 +479,7 @@ class CConditionalScannerTestCase1(unittest.TestCase): class CConditionalScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH based on #ifdef""" env = DummyEnvironment(CPPPATH=[], CPPDEFINES=["INCLUDE_F2"]) s = SCons.Scanner.C.CConditionalScanner() @@ -490,7 +490,7 @@ class CConditionalScannerTestCase2(unittest.TestCase): class CConditionalScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment( CPPPATH=[test.workpath("d1")], @@ -513,7 +513,7 @@ class CConditionalScannerTestCase3(unittest.TestCase): class CConditionalScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test that dependency is detected if #include uses a macro.""" with self.subTest("macro defined in the source file"): @@ -533,7 +533,7 @@ class CConditionalScannerTestCase4(unittest.TestCase): class dictify_CPPDEFINESTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Make sure CPPDEFINES converts correctly. Various types and combinations of types could fail if not handled diff --git a/SCons/Scanner/D.py b/SCons/Scanner/D.py index c9b1e36..f4366df 100644 --- a/SCons/Scanner/D.py +++ b/SCons/Scanner/D.py @@ -35,7 +35,7 @@ def DScanner(): return ds class D(Classic): - def __init__(self): + def __init__(self) -> None: super().__init__( name="DScanner", suffixes='$DSUFFIXES', diff --git a/SCons/Scanner/DTests.py b/SCons/Scanner/DTests.py index 25ccca3..358014d 100644 --- a/SCons/Scanner/DTests.py +++ b/SCons/Scanner/DTests.py @@ -33,7 +33,7 @@ test = TestCmd.TestCmd(workdir = '') class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -73,7 +73,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -222,44 +222,44 @@ void main() {} """) class DScannerTestCase(unittest.TestCase): - def helper(self, filename, headers): + def helper(self, filename, headers) -> None: env = DummyEnvironment() s = SCons.Scanner.D.DScanner() path = s.path(env) deps = s(env.File(filename), env, path) deps_match(self, deps, headers) - def test_BasicImport(self): + def test_BasicImport(self) -> None: self.helper('basic.d', ['A.d']) - def test_StaticImport(self): + def test_StaticImport(self) -> None: self.helper('static.d', ['A.d']) - def test_publicImport(self): + def test_publicImport(self) -> None: self.helper('public.d', ['A.d']) - def test_RenameImport(self): + def test_RenameImport(self) -> None: self.helper('rename.d', ['A.d']) - def test_SelectiveImport(self): + def test_SelectiveImport(self) -> None: self.helper('selective.d', ['A.d']) - def test_RenameAndSelectiveImport(self): + def test_RenameAndSelectiveImport(self) -> None: self.helper('renameAndSelective.d', ['A.d']) - def test_ScopedImport(self): + def test_ScopedImport(self) -> None: self.helper('scoped.d', ['A.d']) - def test_CombinatorialImport(self): + def test_CombinatorialImport(self) -> None: self.helper('combinatorial.d', ['A.d', 'B.d', 'C.d', 'D.d']) - def test_SubdirsImport(self): + def test_SubdirsImport(self) -> None: self.helper('subdirs.d', [os.path.join('X','X','X.d'), os.path.join('X','Y.d'), os.path.join('X','Z.d')]) - def test_MultipleImport(self): + def test_MultipleImport(self) -> None: self.helper('multiple.d', ['A.d', 'B.d', 'C.d', os.path.join('X','Y.d')]) - def test_MultilineImport(self): + def test_MultilineImport(self) -> None: self.helper('multiline.d', ['A.d']) if __name__ == "__main__": diff --git a/SCons/Scanner/DirTests.py b/SCons/Scanner/DirTests.py index 1c46c6c..32355f3 100644 --- a/SCons/Scanner/DirTests.py +++ b/SCons/Scanner/DirTests.py @@ -41,7 +41,7 @@ from SCons.SConsign import current_sconsign_filename # return self.fs.Entry(name) class DummyEnvironment: - def __init__(self, root): + def __init__(self, root) -> None: self.fs = SCons.Node.FS.FS(root) def Dir(self, name): return self.fs.Dir(name) @@ -53,7 +53,7 @@ class DummyEnvironment: return factory or self.fs.Entry class DirScannerTestBase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.test = TestCmd.TestCmd(workdir = '') self.test.subdir('dir', ['dir', 'sub']) @@ -79,7 +79,7 @@ class DirScannerTestBase(unittest.TestCase): self.test.write(['dir', 'sub', '{}.pag'.format(sconsign)], "dir/{}.pag\n".format(sconsign)) class DirScannerTestCase(DirScannerTestBase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(self.test.workpath()) s = SCons.Scanner.Dir.DirScanner() @@ -102,7 +102,7 @@ class DirScannerTestCase(DirScannerTestBase): assert sss == expect, "Found {}, expected {}".format(sss, expect) class DirEntryScannerTestCase(DirScannerTestBase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(self.test.workpath()) s = SCons.Scanner.Dir.DirEntryScanner() diff --git a/SCons/Scanner/Fortran.py b/SCons/Scanner/Fortran.py index 9cf5b22..14df5fc 100644 --- a/SCons/Scanner/Fortran.py +++ b/SCons/Scanner/Fortran.py @@ -48,7 +48,7 @@ class F90Scanner(Classic): """ def __init__(self, name, suffixes, path_variable, - use_regex, incl_regex, def_regex, *args, **kwargs): + use_regex, incl_regex, def_regex, *args, **kwargs) -> None: self.cre_use = re.compile(use_regex, re.M) self.cre_incl = re.compile(incl_regex, re.M) @@ -119,7 +119,7 @@ class F90Scanner(Classic): return [pair[1] for pair in sorted(nodes)] -def FortranScan(path_variable="FORTRANPATH"): +def FortranScan(path_variable: str="FORTRANPATH"): """Return a prototype Scanner instance for scanning source files for Fortran USE & INCLUDE statements""" diff --git a/SCons/Scanner/FortranTests.py b/SCons/Scanner/FortranTests.py index 729e91a..d2f6089 100644 --- a/SCons/Scanner/FortranTests.py +++ b/SCons/Scanner/FortranTests.py @@ -202,7 +202,7 @@ test.write(['modules', 'use.mod'], "\n") # define some helpers: class DummyEnvironment: - def __init__(self, listCppPath): + def __init__(self, listCppPath) -> None: self.path = listCppPath self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -214,16 +214,16 @@ class DummyEnvironment: else: raise KeyError("Dummy environment only has FORTRANPATH attribute.") - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self, key): return self.Dictionary()[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.Dictionary()[key] = value - def __delitem__(self, key): + def __delitem__(self, key) -> None: del self.Dictionary()[key] def subst(self, arg, target=None, source=None, conv=None): @@ -249,7 +249,7 @@ class DummyEnvironment: return self.fs.File(filename) -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = list(map(os.path.normpath, list(map(str, deps)))) expect = list(map(os.path.normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -258,7 +258,7 @@ def deps_match(self, deps, headers): # define some tests: class FortranScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', " INCLUDE 'fi.f'\n") env = DummyEnvironment([]) @@ -272,7 +272,7 @@ class FortranScannerTestCase1(unittest.TestCase): class FortranScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', " INCLUDE 'fi.f'\n") env = DummyEnvironment([test.workpath("d1")]) @@ -286,7 +286,7 @@ class FortranScannerTestCase2(unittest.TestCase): class FortranScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -296,7 +296,7 @@ class FortranScannerTestCase3(unittest.TestCase): class FortranScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write(['d1', 'f2.f'], " INCLUDE 'fi.f'\n") env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -308,7 +308,7 @@ class FortranScannerTestCase4(unittest.TestCase): class FortranScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -318,7 +318,7 @@ class FortranScannerTestCase5(unittest.TestCase): class FortranScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f2.f', "\n") env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -330,7 +330,7 @@ class FortranScannerTestCase6(unittest.TestCase): class FortranScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -340,7 +340,7 @@ class FortranScannerTestCase7(unittest.TestCase): class FortranScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f2.f', "\n") env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -352,7 +352,7 @@ class FortranScannerTestCase8(unittest.TestCase): class FortranScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f3.f', "\n") env = DummyEnvironment([]) s = SCons.Scanner.Fortran.FortranScan() @@ -380,7 +380,7 @@ class FortranScannerTestCase9(unittest.TestCase): class FortranScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(["include"]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -397,11 +397,11 @@ class FortranScannerTestCase10(unittest.TestCase): class FortranScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -419,7 +419,7 @@ class FortranScannerTestCase11(unittest.TestCase): class FortranScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) env.fs.chdir(env.Dir('include')) s = SCons.Scanner.Fortran.FortranScan() @@ -432,7 +432,7 @@ class FortranScannerTestCase12(unittest.TestCase): class FortranScannerTestCase13(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -451,7 +451,7 @@ class FortranScannerTestCase13(unittest.TestCase): class FortranScannerTestCase14(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.VariantDir('build1', 'src', 1) @@ -473,7 +473,7 @@ class FortranScannerTestCase14(unittest.TestCase): class FortranScannerTestCase15(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): if arg == "$junk": @@ -492,7 +492,7 @@ class FortranScannerTestCase15(unittest.TestCase): class FortranScannerTestCase16(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', "\n") test.write('f3.f', "\n") diff --git a/SCons/Scanner/IDLTests.py b/SCons/Scanner/IDLTests.py index 28433d1..b70115b 100644 --- a/SCons/Scanner/IDLTests.py +++ b/SCons/Scanner/IDLTests.py @@ -187,7 +187,7 @@ test.write([ 'repository', 'src', 'ddd.idl'], "\n") # define some helpers: class DummyEnvironment: - def __init__(self, listCppPath): + def __init__(self, listCppPath) -> None: self.path = listCppPath self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -207,16 +207,16 @@ class DummyEnvironment: path = [path] return list(map(self.subst, path)) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self,key): return self.Dictionary()[key] - def __setitem__(self,key,value): + def __setitem__(self,key,value) -> None: self.Dictionary()[key] = value - def __delitem__(self,key): + def __delitem__(self,key) -> None: del self.Dictionary()[key] def get_calculator(self): @@ -237,7 +237,7 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -245,7 +245,7 @@ def deps_match(self, deps, headers): # define some tests: class IDLScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -254,7 +254,7 @@ class IDLScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -263,7 +263,7 @@ class IDLScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -272,7 +272,7 @@ class IDLScannerTestCase3(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -281,7 +281,7 @@ class IDLScannerTestCase4(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -306,7 +306,7 @@ class IDLScannerTestCase5(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env1 = DummyEnvironment([test.workpath("d1")]) env2 = DummyEnvironment([test.workpath("d1/d2")]) s = SCons.Scanner.IDL.IDLScan() @@ -320,7 +320,7 @@ class IDLScannerTestCase6(unittest.TestCase): deps_match(self, deps2, headers2) class IDLScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(["include"]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -336,10 +336,10 @@ class IDLScannerTestCase7(unittest.TestCase): deps_match(self, deps2, headers2) class IDLScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -358,7 +358,7 @@ class IDLScannerTestCase8(unittest.TestCase): test.unlink('fa.idl') class IDLScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) env.fs.chdir(env.Dir('include')) s = SCons.Scanner.IDL.IDLScan() @@ -370,7 +370,7 @@ class IDLScannerTestCase9(unittest.TestCase): test.unlink('include/t4.idl') class IDLScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -389,7 +389,7 @@ class IDLScannerTestCase10(unittest.TestCase): os.chdir(test.workpath('')) class IDLScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.VariantDir('build1', 'src', 1) @@ -410,7 +410,7 @@ class IDLScannerTestCase11(unittest.TestCase): os.chdir(test.workpath('')) class IDLScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): if arg == "$blah": diff --git a/SCons/Scanner/Java.py b/SCons/Scanner/Java.py index e6c2db9..4a66c9d 100644 --- a/SCons/Scanner/Java.py +++ b/SCons/Scanner/Java.py @@ -52,7 +52,7 @@ def _subst_paths(env, paths) -> list: return paths -def _collect_classes(classlist, dirname, files): +def _collect_classes(classlist, dirname, files) -> None: for fname in files: if fname.endswith(".class"): classlist.append(os.path.join(str(dirname), fname)) diff --git a/SCons/Scanner/JavaTests.py b/SCons/Scanner/JavaTests.py index faa0c49..cf4ca83 100644 --- a/SCons/Scanner/JavaTests.py +++ b/SCons/Scanner/JavaTests.py @@ -54,7 +54,7 @@ for fname in subfiles: test.write(fname.split('/'), "\n") class DummyEnvironment(collections.UserDict): - def __init__(self,**kw): + def __init__(self,**kw) -> None: collections.UserDict.__init__(self) self.data.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -73,7 +73,7 @@ class DummyEnvironment(collections.UserDict): path = [path] return list(map(self.subst, path)) - def has_key(self, key): + def has_key(self, key) -> bool: return key in self.Dictionary() def get_calculator(self): @@ -93,13 +93,13 @@ class DummyEnvironment(collections.UserDict): class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def rexists(self): + def rexists(self) -> int: return 1 - def __str__(self): + def __str__(self) -> str: return self.name @@ -109,14 +109,14 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = sorted(map(my_normpath, list(map(str, deps)))) expect = sorted(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) class JavaScannerEmptyClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=path) s = SCons.Scanner.Java.JavaScanner() @@ -126,7 +126,7 @@ class JavaScannerEmptyClasspath(unittest.TestCase): class JavaScannerClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('classpath.jar')]) s = SCons.Scanner.Java.JavaScanner() @@ -136,7 +136,7 @@ class JavaScannerClasspath(unittest.TestCase): class JavaScannerWildcardClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('*')]) s = SCons.Scanner.Java.JavaScanner() @@ -146,7 +146,7 @@ class JavaScannerWildcardClasspath(unittest.TestCase): class JavaScannerDirClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath()]) s = SCons.Scanner.Java.JavaScanner() @@ -156,7 +156,7 @@ class JavaScannerDirClasspath(unittest.TestCase): class JavaScannerNamedDirClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('com'), test.workpath('java space')], @@ -168,7 +168,7 @@ class JavaScannerNamedDirClasspath(unittest.TestCase): class JavaScannerSearchPathClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVACLASSPATH=os.pathsep.join([test.workpath('com'), test.workpath('java space')]), @@ -180,7 +180,7 @@ class JavaScannerSearchPathClasspath(unittest.TestCase): class JavaScannerEmptyProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=path) s = SCons.Scanner.Java.JavaScanner() @@ -190,7 +190,7 @@ class JavaScannerEmptyProcessorpath(unittest.TestCase): class JavaScannerProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('classpath.jar')]) s = SCons.Scanner.Java.JavaScanner() @@ -200,7 +200,7 @@ class JavaScannerProcessorpath(unittest.TestCase): class JavaScannerWildcardProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('*')]) s = SCons.Scanner.Java.JavaScanner() @@ -210,7 +210,7 @@ class JavaScannerWildcardProcessorpath(unittest.TestCase): class JavaScannerDirProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath()]) s = SCons.Scanner.Java.JavaScanner() @@ -220,7 +220,7 @@ class JavaScannerDirProcessorpath(unittest.TestCase): class JavaScannerNamedDirProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('com'), test.workpath('java space')], @@ -232,7 +232,7 @@ class JavaScannerNamedDirProcessorpath(unittest.TestCase): class JavaScannerSearchPathProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=os.pathsep.join([test.workpath('com'), test.workpath('java space')]), diff --git a/SCons/Scanner/LaTeX.py b/SCons/Scanner/LaTeX.py index 700b7cb..6abe736 100644 --- a/SCons/Scanner/LaTeX.py +++ b/SCons/Scanner/LaTeX.py @@ -78,7 +78,7 @@ class FindENVPathDirs: A class to bind a specific E{*}PATH variable name to a function that will return all of the E{*}path directories. """ - def __init__(self, variable): + def __init__(self, variable) -> None: self.variable = variable def __call__(self, env, dir=None, target=None, source=None, argument=None): @@ -175,7 +175,7 @@ class LaTeX(ScannerBase): 'includefrom', 'subincludefrom', 'inputfrom', 'subinputfrom'] - def __init__(self, name, suffixes, graphics_extensions, *args, **kwargs): + def __init__(self, name, suffixes, graphics_extensions, *args, **kwargs) -> None: regex = r''' \\( include @@ -219,7 +219,7 @@ class LaTeX(ScannerBase): back and uses a dictionary of tuples rather than a single tuple of paths. """ - def __init__(self, dictionary): + def __init__(self, dictionary) -> None: self.dictionary = {} for k,n in dictionary.items(): self.dictionary[k] = (FindPathDirs(n), FindENVPathDirs(n)) @@ -241,7 +241,7 @@ class LaTeX(ScannerBase): Do not scan *.eps, *.pdf, *.jpg, etc. """ - def __init__(self, suffixes): + def __init__(self, suffixes) -> None: self.suffixes = suffixes def __call__(self, node, env): @@ -331,7 +331,7 @@ class LaTeX(ScannerBase): line_continues_a_comment = len(comment) > 0 return '\n'.join(out).rstrip()+'\n' - def scan(self, node, subdir='.'): + def scan(self, node, subdir: str='.'): # Modify the default scan function to allow for the regular # expression to return a comma separated list of file names # as can be the case with the bibliography keyword. diff --git a/SCons/Scanner/LaTeXTests.py b/SCons/Scanner/LaTeXTests.py index 252d8d4..ae3ae66 100644 --- a/SCons/Scanner/LaTeXTests.py +++ b/SCons/Scanner/LaTeXTests.py @@ -81,7 +81,7 @@ test.write('incNO.tex', "\n") # define some helpers: # copied from CTest.py class DummyEnvironment(collections.UserDict): - def __init__(self, **kw): + def __init__(self, **kw) -> None: super().__init__() self.data.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -121,7 +121,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -129,7 +129,7 @@ def deps_match(self, deps, headers): class LaTeXScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -141,7 +141,7 @@ class LaTeXScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class LaTeXScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -150,7 +150,7 @@ class LaTeXScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class LaTeXScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -159,7 +159,7 @@ class LaTeXScannerTestCase3(unittest.TestCase): deps_match(self, deps, files) class LaTeXScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) diff --git a/SCons/Scanner/ProgTests.py b/SCons/Scanner/ProgTests.py index 5aa0571..2798ab6 100644 --- a/SCons/Scanner/ProgTests.py +++ b/SCons/Scanner/ProgTests.py @@ -44,7 +44,7 @@ for h in libs: # define some helpers: class DummyEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {'LIBSUFFIXES' : '.lib'} self._dict.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -57,16 +57,16 @@ class DummyEnvironment: else: return [self._dict[x] for x in args] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self,key): return self.Dictionary()[key] - def __setitem__(self,key,value): + def __setitem__(self,key,value) -> None: self.Dictionary()[key] = value - def __delitem__(self,key): + def __delitem__(self,key) -> None: del self.Dictionary()[key] def subst(self, s, target=None, source=None, conv=None): @@ -87,11 +87,11 @@ class DummyEnvironment: return self.fs.File(test.workpath(filename)) class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def rexists(self): + def rexists(self) -> int: return 1 - def __str__(self): + def __str__(self) -> str: return self.name def deps_match(deps, libs): @@ -102,7 +102,7 @@ def deps_match(deps, libs): # define some tests: class ProgramScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("") ], LIBS=[ 'l1', 'l2', 'l3' ]) s = SCons.Scanner.Prog.ProgramScanner() @@ -135,7 +135,7 @@ class ProgramScannerTestCase1(unittest.TestCase): class ProgramScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=list(map(test.workpath, ["", "d1", "d1/d2" ])), LIBS=[ 'l1', 'l2', 'l3' ]) @@ -145,7 +145,7 @@ class ProgramScannerTestCase2(unittest.TestCase): assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), list(map(str, deps)) class ProgramScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"), test.workpath("d1")], LIBS='l2 l3'.split()) @@ -155,7 +155,7 @@ class ProgramScannerTestCase3(unittest.TestCase): assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), list(map(str, deps)) class ProgramScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, path=test.workpath("d1")): if arg == "$blah": @@ -170,7 +170,7 @@ class ProgramScannerTestCase5(unittest.TestCase): assert deps_match(deps, [ 'd1/l2.lib' ]), list(map(str, deps)) class ProgramScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', 'sub/libbar', 'xyz.other'], LIBPREFIXES=['lib'], @@ -181,7 +181,7 @@ class ProgramScannerTestCase6(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR', '$XYZ'], LIBPREFIXES=['lib'], @@ -194,7 +194,7 @@ class ProgramScannerTestCase7(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: n1 = DummyNode('n1') env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], @@ -217,7 +217,7 @@ class ProgramScannerTestCase8(unittest.TestCase): assert deps == [n1, n2], deps class ProgramScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR'], LIBPREFIXES=['lib'], @@ -229,7 +229,7 @@ class ProgramScannerTestCase9(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR'], LIBPREFIXES=['lib'], diff --git a/SCons/Scanner/PythonTests.py b/SCons/Scanner/PythonTests.py index 1a4f5b4..03e4e10 100644 --- a/SCons/Scanner/PythonTests.py +++ b/SCons/Scanner/PythonTests.py @@ -56,7 +56,7 @@ else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -66,7 +66,7 @@ def deps_match(self, deps, headers): # Copied from LaTeXTests.py. class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -104,7 +104,7 @@ class DummyEnvironment(collections.UserDict): class PythonScannerTestPythonPath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner env['ENV']['PYTHONPATH'] = test.workpath('') @@ -115,7 +115,7 @@ class PythonScannerTestPythonPath(unittest.TestCase): class PythonScannerTestPythonCallablePath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner env['ENV']['PYTHONPATH'] = test.workpath('') @@ -126,7 +126,7 @@ class PythonScannerTestPythonCallablePath(unittest.TestCase): class PythonScannerTestImportSimplePackage(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('imports_simple_package.py') @@ -141,7 +141,7 @@ class PythonScannerTestImportSimplePackage(unittest.TestCase): class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('import_simple_package_module1_as.py') @@ -152,7 +152,7 @@ class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase): class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('import_simple_package_module1.py') @@ -163,7 +163,7 @@ class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_module1.py') @@ -174,7 +174,7 @@ class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_module1_as.py') @@ -186,7 +186,7 @@ class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModulesNoSpace( unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_modules_no_space.py') @@ -199,7 +199,7 @@ class PythonScannerTestFromImportSimplePackageModulesNoSpace( class PythonScannerTestFromImportSimplePackageModulesWithSpace( unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_modules_with_space.py') @@ -211,7 +211,7 @@ class PythonScannerTestFromImportSimplePackageModulesWithSpace( class PythonScannerTestCurdirReferenceScript(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.Dir('curdir_reference').File('script.py') @@ -222,7 +222,7 @@ class PythonScannerTestCurdirReferenceScript(unittest.TestCase): class PythonScannerTestImportsNested3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('imports_nested3.py') @@ -234,7 +234,7 @@ class PythonScannerTestImportsNested3(unittest.TestCase): class PythonScannerTestImportsGrandparentModule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -246,7 +246,7 @@ class PythonScannerTestImportsGrandparentModule(unittest.TestCase): class PythonScannerTestImportsParentModule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -258,7 +258,7 @@ class PythonScannerTestImportsParentModule(unittest.TestCase): class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -270,7 +270,7 @@ class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests the following import statement: `from simple_package.module1 import somefunc` with somefunc.py existing @@ -287,7 +287,7 @@ class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests the following import statement: `from nested1 import module, nested2`. In this test, module is a Python @@ -305,7 +305,7 @@ class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): class PythonScannerTestImportUnknownFiles(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests importing files that are not found. If Python really can't find those files, it will fail. But this is intended to diff --git a/SCons/Scanner/RCTests.py b/SCons/Scanner/RCTests.py index 3655269..120c7f8 100644 --- a/SCons/Scanner/RCTests.py +++ b/SCons/Scanner/RCTests.py @@ -71,7 +71,7 @@ for h in headers: # define some helpers: class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -89,7 +89,7 @@ class DummyEnvironment(collections.UserDict): path = [path] return list(map(self.subst, path)) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.data def get_calculator(self): @@ -110,7 +110,7 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = sorted(map(my_normpath, list(map(str, deps)))) expect = sorted(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -118,7 +118,7 @@ def deps_match(self, deps, headers): # define some tests: class RCScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) @@ -128,7 +128,7 @@ class RCScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class RCScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) @@ -145,7 +145,7 @@ class RCScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class RCScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) diff --git a/SCons/Scanner/ScannerTests.py b/SCons/Scanner/ScannerTests.py index b9cb209..1fbbb62 100644 --- a/SCons/Scanner/ScannerTests.py +++ b/SCons/Scanner/ScannerTests.py @@ -35,7 +35,7 @@ class DummyFS: return DummyNode(name) class DummyEnvironment(collections.UserDict): - def __init__(self, mapping=None, **kwargs): + def __init__(self, mapping=None, **kwargs) -> None: super().__init__(mapping) self.data.update(kwargs) self.fs = DummyFS() @@ -55,31 +55,31 @@ class DummyEnvironment(collections.UserDict): return factory or self.fs.File class DummyNode: - def __init__(self, name, search_result=()): + def __init__(self, name, search_result=()) -> None: self.name = name self.search_result = tuple(search_result) - def rexists(self): + def rexists(self) -> bool: return True - def __str__(self): + def __str__(self) -> str: return self.name def Rfindalldirs(self, pathlist): return self.search_result + pathlist - def __repr__(self): + def __repr__(self) -> str: return self.name def __eq__(self, other): return self.name == other.name - def __repr__(self): + def __repr__(self) -> str: return self.name def __eq__(self, other): return self.name == other.name class FindPathDirsTestCase(unittest.TestCase): - def test_FindPathDirs(self): + def test_FindPathDirs(self) -> None: """Test the FindPathDirs callable class""" env = DummyEnvironment(LIBPATH = [ 'foo' ]) @@ -95,9 +95,9 @@ class FindPathDirsTestCase(unittest.TestCase): class ScannerTestCase(unittest.TestCase): - def test_creation(self): + def test_creation(self) -> None: """Test creation of Scanner objects""" - def func(self): + def func(self) -> None: pass s = ScannerBase(func) assert isinstance(s, ScannerBase), s @@ -120,11 +120,11 @@ class ScannerTestCase(unittest.TestCase): class ScannerBaseTestCase(unittest.TestCase): class skey_node: - def __init__(self, key): + def __init__(self, key) -> None: self.key = key def scanner_key(self): return self.key - def rexists(self): + def rexists(self) -> int: return 1 def func(self, filename, env, target, *args): @@ -137,7 +137,7 @@ class ScannerBaseTestCase(unittest.TestCase): return self.deps - def test(self, scanner, env, filename, deps, *args): + def test(self, scanner, env, filename, deps, *args) -> None: self.deps = deps path = scanner.path(env) scanned = scanner(filename, env, path) @@ -154,7 +154,7 @@ class ScannerBaseTestCase(unittest.TestCase): else: self.assertFalse(hasattr(self, "arg"), "an argument was given when it shouldn't have been") - def test___call__dict(self): + def test___call__dict(self) -> None: """Test calling ScannerBase objects with a dictionary""" called = [] def s1func(node, env, path, called=called): @@ -177,9 +177,9 @@ class ScannerBaseTestCase(unittest.TestCase): selector(ny, env, []) assert called == ['s2func', ny], called - def test_path(self): + def test_path(self) -> None: """Test the ScannerBase path() method""" - def pf(env, cwd, target, source, argument=None): + def pf(env, cwd, target, source, argument=None) -> str: return "pf: %s %s %s %s %s" % \ (env.VARIABLE, cwd, target[0], source[0], argument) @@ -196,7 +196,7 @@ class ScannerBaseTestCase(unittest.TestCase): p = s.path(env, 'here', [target], [source]) assert p == "pf: v1 here target source xyz", p - def test_positional(self): + def test_positional(self) -> None: """Test the ScannerBase class using positional arguments""" s = ScannerBase(self.func, "Pos") env = DummyEnvironment() @@ -207,7 +207,7 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i1" self.test(s, env, DummyNode('i1.cpp'), ['i1.h', 'i1.hpp']) - def test_keywords(self): + def test_keywords(self) -> None: """Test the ScannerBase class using keyword arguments""" s = ScannerBase(function = self.func, name = "Key") env = DummyEnvironment() @@ -219,7 +219,7 @@ class ScannerBaseTestCase(unittest.TestCase): self.test(s, env, DummyNode('i2.cpp'), ['i2.h', 'i2.hpp']) - def test_pos_opt(self): + def test_pos_opt(self) -> None: """Test the ScannerBase class using both position and optional arguments""" arg = "this is the argument" s = ScannerBase(self.func, "PosArg", arg) @@ -231,7 +231,7 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i3" self.test(s, env, DummyNode('i3.cpp'), ['i3.h', 'i3.hpp'], arg) - def test_key_opt(self): + def test_key_opt(self) -> None: """Test the ScannerBase class using both keyword and optional arguments""" arg = "this is another argument" s = ScannerBase(function = self.func, name = "KeyArg", argument = arg) @@ -243,12 +243,12 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i4" self.test(s, env, DummyNode('i4.cpp'), ['i4.h', 'i4.hpp'], arg) - def test___cmp__(self): + def test___cmp__(self) -> None: """Test the ScannerBase class __cmp__() method""" s = ScannerBase(self.func, "Cmp") assert s is not None - def test_hash(self): + def test_hash(self) -> None: """Test the ScannerBase class __hash__() method""" s = ScannerBase(self.func, "Hash") mapping = {} @@ -258,11 +258,11 @@ class ScannerBaseTestCase(unittest.TestCase): self.assertTrue(h == i, "hash Scanner base class expected %s, got %s" % (i, h)) - def test_scan_check(self): + def test_scan_check(self) -> None: """Test the ScannerBase class scan_check() method""" def my_scan(filename, env, target, *args): return [] - def check(node, env, s=self): + def check(node, env, s=self) -> int: s.checked[str(node)] = 1 return 1 env = DummyEnvironment() @@ -273,7 +273,7 @@ class ScannerBaseTestCase(unittest.TestCase): self.assertTrue(self.checked['x'] == 1, "did not call check function") - def test_recursive(self): + def test_recursive(self) -> None: """Test the ScannerBase class recursive flag""" nodes = [1, 2, 3, 4] @@ -295,7 +295,7 @@ class ScannerBaseTestCase(unittest.TestCase): n = s.recurse_nodes(nodes) self.assertTrue(n == [1, 3], "recursive = 1 didn't return all nodes: %s" % n) - def test_get_skeys(self): + def test_get_skeys(self) -> None: """Test the ScannerBase get_skeys() method""" s = ScannerBase(function = self.func) sk = s.get_skeys() @@ -310,7 +310,7 @@ class ScannerBaseTestCase(unittest.TestCase): sk = s.get_skeys(env) self.assertTrue(sk == ['.3', '.4'], "sk was %s, not ['.3', '.4']") - def test_select(self): + def test_select(self) -> None: """Test the ScannerBase select() method""" scanner = ScannerBase(function = self.func) s = scanner.select('.x') @@ -324,7 +324,7 @@ class ScannerBaseTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s is None, s - def test_add_scanner(self): + def test_add_scanner(self) -> None: """Test the ScannerBase add_scanner() method""" selector = ScannerBase({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.z')) @@ -333,7 +333,7 @@ class ScannerBaseTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s == 3, s - def test___str__(self): + def test___str__(self) -> None: """Test the ScannerBase __str__() method""" scanner = ScannerBase(function = self.func) s = str(scanner) @@ -344,20 +344,20 @@ class ScannerBaseTestCase(unittest.TestCase): class SelectorTestCase(unittest.TestCase): class skey_node: - def __init__(self, key): + def __init__(self, key) -> None: self.key = key def scanner_key(self): return self.key - def rexists(self): + def rexists(self) -> int: return 1 - def test___init__(self): + def test___init__(self) -> None: """Test creation of Scanner.Selector object""" s = Selector({}) assert isinstance(s, Selector), s assert s.mapping == {}, s.mapping - def test___call__(self): + def test___call__(self) -> None: """Test calling Scanner.Selector objects""" called = [] def s1func(node, env, path, called=called): @@ -380,7 +380,7 @@ class SelectorTestCase(unittest.TestCase): selector(ny, env, []) assert called == ['s2func', ny], called - def test_select(self): + def test_select(self) -> None: """Test the Scanner.Selector select() method""" selector = Selector({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.x')) @@ -390,7 +390,7 @@ class SelectorTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s is None, s - def test_add_scanner(self): + def test_add_scanner(self) -> None: """Test the Scanner.Selector add_scanner() method""" selector = Selector({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.z')) @@ -400,31 +400,31 @@ class SelectorTestCase(unittest.TestCase): assert s == 3, s class CurrentTestCase(unittest.TestCase): - def test_class(self): + def test_class(self) -> None: """Test the Scanner.Current class""" class MyNode: - def __init__(self): + def __init__(self) -> None: self.called_has_builder = None self.called_is_up_to_date = None self.func_called = None - def rexists(self): + def rexists(self) -> int: return 1 class HasNoBuilder(MyNode): def has_builder(self): self.called_has_builder = 1 return None class IsNotCurrent(MyNode): - def has_builder(self): + 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 class IsCurrent(MyNode): - def has_builder(self): + def has_builder(self) -> int: self.called_has_builder = 1 return 1 - def is_up_to_date(self): + def is_up_to_date(self) -> int: self.called_is_up_to_date = 1 return 1 def func(node, env, path): @@ -461,7 +461,7 @@ class ClassicTestCase(unittest.TestCase): return self.deps - def test_find_include(self): + def test_find_include(self) -> None: """Test the Scanner.Classic find_include() method""" env = DummyEnvironment() s = Classic("t", ['.suf'], 'MYPATH', r'^my_inc (\S+)') @@ -480,15 +480,15 @@ class ClassicTestCase(unittest.TestCase): finally: SCons.Node.FS.find_file = save - def test_name(self): + def test_name(self) -> None: """Test setting the Scanner.Classic name""" s = Classic("my_name", ['.s'], 'MYPATH', r'^my_inc (\S+)') assert s.name == "my_name", s.name - def test_scan(self): + def test_scan(self) -> None: """Test the Scanner.Classic scan() method""" class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self._rfile = self self.includes = None @@ -562,7 +562,7 @@ class ClassicTestCase(unittest.TestCase): ret = s.function(n, env, ('foo5',)) assert ret == ['jkl', 'mno'], ret - def test_recursive(self): + def test_recursive(self) -> None: """Test the Scanner.Classic class recursive flag""" nodes = [1, 2, 3, 4] @@ -582,7 +582,7 @@ class ClassicTestCase(unittest.TestCase): class ClassicCPPTestCase(unittest.TestCase): - def test_find_include(self): + def test_find_include(self) -> None: """Test the Scanner.ClassicCPP find_include() method""" env = DummyEnvironment() s = ClassicCPP("Test", [], None, "") diff --git a/SCons/Scanner/__init__.py b/SCons/Scanner/__init__.py index fe44ee0..c8c2732 100644 --- a/SCons/Scanner/__init__.py +++ b/SCons/Scanner/__init__.py @@ -59,7 +59,7 @@ class FindPathDirs: """Class to bind a specific E{*}PATH variable name to a function that will return all of the E{*}path directories. """ - def __init__(self, variable): + def __init__(self, variable) -> None: self.variable = variable def __call__(self, env, dir=None, target=None, source=None, argument=None): @@ -149,7 +149,7 @@ class ScannerBase: def __init__( self, function, - name="NONE", + name: str="NONE", argument=_null, skeys=_null, path_function=None, @@ -159,7 +159,7 @@ class ScannerBase: node_factory=None, scan_check=None, recursive=None, - ): + ) -> None: """Construct a new scanner object given a scanner function.""" # Note: this class could easily work with scanner functions that take # something other than a filename as an argument (e.g. a database @@ -238,10 +238,10 @@ class ScannerBase: def __hash__(self): return id(self) - def __str__(self): + def __str__(self) -> str: return self.name - def add_skey(self, skey): + def add_skey(self, skey) -> None: """Add a skey to the list of skeys""" self.skeys.append(skey) @@ -270,7 +270,7 @@ class ScannerBase: # recurse_nodes = _recurse_no_nodes - def add_scanner(self, skey, scanner): + def add_scanner(self, skey, scanner) -> None: self.function[skey] = scanner self.add_skey(skey) @@ -292,7 +292,7 @@ class Selector(ScannerBase): used by various Tool modules and therefore was likely a template for custom modules that may be out there.) """ - def __init__(self, mapping, *args, **kwargs): + def __init__(self, mapping, *args, **kwargs) -> None: super().__init__(None, *args, **kwargs) self.mapping = mapping self.skeys = list(mapping.keys()) @@ -306,7 +306,7 @@ class Selector(ScannerBase): except KeyError: return None - def add_scanner(self, skey, scanner): + def add_scanner(self, skey, scanner) -> None: self.mapping[skey] = scanner self.add_skey(skey) @@ -318,7 +318,7 @@ class Current(ScannerBase): either locally or in a repository). """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: def current_check(node, env): return not node.has_builder() or node.is_up_to_date() @@ -337,7 +337,7 @@ class Classic(Current): name of the include file in group 0. """ - def __init__(self, name, suffixes, path_variable, regex, *args, **kwargs): + def __init__(self, name, suffixes, path_variable, regex, *args, **kwargs) -> None: self.cre = re.compile(regex, re.M) def _scan(node, _, path=(), self=self): diff --git a/SCons/Script/Interactive.py b/SCons/Script/Interactive.py index d694740..8fd3aa0 100644 --- a/SCons/Script/Interactive.py +++ b/SCons/Script/Interactive.py @@ -112,7 +112,7 @@ version Prints SCons version information. 'sh' : 'shell', } - def __init__(self, **kw): + def __init__(self, **kw) -> None: cmd.Cmd.__init__(self) for key, val in kw.items(): setattr(self, key, val) @@ -122,7 +122,7 @@ version Prints SCons version information. else: self.shell_variable = 'SHELL' - def default(self, argv): + def default(self, argv) -> None: print("*** Unknown command: %s" % argv[0]) def onecmd(self, line): @@ -148,7 +148,7 @@ version Prints SCons version information. return self.default(argv) return func(argv) - def do_build(self, argv): + def do_build(self, argv) -> None: """\ build [TARGETS] Build the specified TARGETS and their dependencies. 'b' is a synonym. @@ -213,11 +213,11 @@ version Prints SCons version information. seen_nodes = {} def get_unseen_children(node, parent, seen_nodes=seen_nodes): - def is_unseen(node, seen_nodes=seen_nodes): + def is_unseen(node, seen_nodes=seen_nodes) -> bool: return node not in seen_nodes return [child for child in node.children(scan=1) if is_unseen(child)] - def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes): + def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes) -> None: seen_nodes[node] = 1 # If this file is in a VariantDir and has a @@ -272,11 +272,11 @@ version Prints SCons version information. """ return self.do_build(['build', '--clean'] + argv[1:]) - def do_EOF(self, argv): + def do_EOF(self, argv) -> None: print() self.do_exit(argv) - def _do_one_help(self, arg): + def _do_one_help(self, arg) -> None: try: # If help_() exists, then call it. func = getattr(self, 'help_' + arg) @@ -312,13 +312,13 @@ version Prints SCons version information. lines = list(map(strip_spaces, lines)) return '\n'.join(lines) - def do_exit(self, argv): + def do_exit(self, argv) -> None: """\ exit Exit SCons interactive mode. """ sys.exit(0) - def do_help(self, argv): + def do_help(self, argv) -> None: """\ help [COMMAND] Prints help for the specified COMMAND. 'h' and '?' are synonyms. @@ -335,7 +335,7 @@ version Prints SCons version information. sys.stdout.write(doc + '\n') sys.stdout.flush() - def do_shell(self, argv): + def do_shell(self, argv) -> None: """\ shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' are synonyms. @@ -355,13 +355,13 @@ version Prints SCons version information. else: p.wait() - def do_version(self, argv): + def do_version(self, argv) -> None: """\ version Prints SCons version information. """ sys.stdout.write(self.parser.version + '\n') -def interact(fs, parser, options, targets, target_top): +def interact(fs, parser, options, targets, target_top) -> None: c = SConsInteractiveCmd(prompt = 'scons>>> ', fs = fs, parser = parser, diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4228fa..05e070f 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -82,7 +82,7 @@ num_jobs = None delayed_warnings = [] -def revert_io(): +def revert_io() -> None: # 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. @@ -103,7 +103,7 @@ class Progressor: count = 0 target_string = '$TARGET' - def __init__(self, obj, interval=1, file=None, overwrite=False): + def __init__(self, obj, interval: int=1, file=None, overwrite: bool=False) -> None: if file is None: file = sys.stdout @@ -121,12 +121,12 @@ class Progressor: else: self.func = self.string - def write(self, s): + def write(self, s) -> None: self.file.write(s) self.file.flush() self.prev = s - def erase_previous(self): + def erase_previous(self) -> None: if self.prev: length = len(self.prev) if self.prev[-1] in ('\n', '\r'): @@ -134,16 +134,16 @@ class Progressor: self.write(' ' * length + '\r') self.prev = '' - def spinner(self, node): + def spinner(self, node) -> None: self.write(self.obj[self.count % len(self.obj)]) - def string(self, node): + def string(self, node) -> None: self.write(self.obj) - def replace_string(self, node): + def replace_string(self, node) -> None: self.write(self.obj.replace(self.target_string, str(node))) - def __call__(self, node): + def __call__(self, node) -> None: self.count = self.count + 1 if (self.count % self.interval) == 0: if self.overwrite: @@ -152,7 +152,7 @@ class Progressor: ProgressObject = SCons.Util.Null() -def Progress(*args, **kw): +def Progress(*args, **kw) -> None: global ProgressObject ProgressObject = Progressor(*args, **kw) @@ -170,7 +170,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): """An SCons build task.""" progress = ProgressObject - def display(self, message): + def display(self, message) -> None: display('scons: ' + message) def prepare(self): @@ -179,14 +179,14 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): self.progress(target) return SCons.Taskmaster.OutOfDateTask.prepare(self) - def needs_execute(self): + def needs_execute(self) -> bool: if SCons.Taskmaster.OutOfDateTask.needs_execute(self): return True if self.top and self.targets[0].has_builder(): display("scons: `%s' is up to date." % str(self.node)) return False - def execute(self): + def execute(self) -> None: if print_time: start_time = time.time() global first_command_start @@ -213,7 +213,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): % (str(self.node), (finish_time - start_time)) ) - def do_failed(self, status=2): + def do_failed(self, status: int=2) -> None: _BuildFailures.append(self.exception[1]) global exit_status global this_build_status @@ -253,7 +253,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): else: SCons.Taskmaster.OutOfDateTask.executed(self) - def failed(self): + def failed(self) -> None: # Handle the failure of a build task. The primary purpose here # is to display the various types of Errors and Exceptions # appropriately. @@ -309,7 +309,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): self.exc_clear() - def postprocess(self): + def postprocess(self) -> None: if self.top: t = self.targets[0] for tp in self.options.tree_printers: @@ -321,7 +321,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): print(tree) SCons.Taskmaster.OutOfDateTask.postprocess(self) - def make_ready(self): + def make_ready(self) -> None: """Make a task ready for execution""" SCons.Taskmaster.OutOfDateTask.make_ready(self) if self.out_of_date and self.options.debug_explain: @@ -332,7 +332,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): class CleanTask(SCons.Taskmaster.AlwaysTask): """An SCons clean task.""" - def fs_delete(self, path, pathstr, remove=True): + def fs_delete(self, path, pathstr, remove: bool=True): try: if os.path.lexists(path): if os.path.isfile(path) or os.path.islink(path): @@ -366,20 +366,20 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): result = [t for t in self.targets if not t.noclean] return result - def _clean_targets(self, remove=True): + def _clean_targets(self, remove: bool=True) -> None: target = self.targets[0] if target in SCons.Environment.CleanTargets: files = SCons.Environment.CleanTargets[target] for f in files: self.fs_delete(f.get_abspath(), str(f), remove) - def show(self): + def show(self) -> None: for t in self._get_files_to_clean(): if not t.isdir(): display("Removed " + str(t)) self._clean_targets(remove=False) - def remove(self): + def remove(self) -> None: for t in self._get_files_to_clean(): try: removed = t.remove() @@ -408,15 +408,15 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # anything really needs to be done. make_ready = SCons.Taskmaster.Task.make_ready_all - def prepare(self): + def prepare(self) -> None: pass class QuestionTask(SCons.Taskmaster.AlwaysTask): """An SCons task for the -q (question) option.""" - def prepare(self): + def prepare(self) -> None: pass - def execute(self): + def execute(self) -> None: if self.targets[0].get_state() != SCons.Node.up_to_date or \ (self.top and not self.targets[0].exists()): global exit_status @@ -425,12 +425,12 @@ class QuestionTask(SCons.Taskmaster.AlwaysTask): this_build_status = 1 self.tm.stop() - def executed(self): + def executed(self) -> None: pass class TreePrinter: - def __init__(self, derived=False, prune=False, status=False, sLineDraw=False): + def __init__(self, derived: bool=False, prune: bool=False, status: bool=False, sLineDraw: bool=False) -> None: self.derived = derived self.prune = prune self.status = status @@ -440,7 +440,7 @@ class TreePrinter: def get_derived_children(self, node): children = node.all_children(None) return [x for x in children if x.has_builder()] - def display(self, t): + def display(self, t) -> None: if self.derived: func = self.get_derived_children else: @@ -475,7 +475,7 @@ class FakeOptionParser: def __getattr__(self, attr): return None values = FakeOptionValues() - def add_local_option(self, *args, **kw): + def add_local_option(self, *args, **kw) -> None: pass OptionsParser = FakeOptionParser() @@ -493,7 +493,7 @@ def SetOption(name, value): return OptionsParser.values.set_option(name, value) -def ValidateOptions(throw_exception=False) -> None: +def ValidateOptions(throw_exception: bool=False) -> None: """Validate options passed to SCons on the command line. If you call this after you set all your command line options with AddOption(), @@ -512,27 +512,27 @@ def ValidateOptions(throw_exception=False) -> None: OptionsParser.preserve_unknown_options = False OptionsParser.parse_args(OptionsParser.largs, OptionsParser.values) -def PrintHelp(file=None): +def PrintHelp(file=None) -> None: OptionsParser.print_help(file=file) class Stats: - def __init__(self): + def __init__(self) -> None: self.stats = [] self.labels = [] self.append = self.do_nothing self.print_stats = self.do_nothing - def enable(self, outfp): + def enable(self, outfp) -> None: self.outfp = outfp self.append = self.do_append self.print_stats = self.do_print - def do_nothing(self, *args, **kw): + def do_nothing(self, *args, **kw) -> None: pass class CountStats(Stats): - def do_append(self, label): + def do_append(self, label) -> None: self.labels.append(label) self.stats.append(SCons.Debug.fetchLoggedInstances()) - def do_print(self): + def do_print(self) -> None: stats_table = {} for s in self.stats: for n in [t[0] for t in s]: @@ -559,10 +559,10 @@ class CountStats(Stats): count_stats = CountStats() class MemStats(Stats): - def do_append(self, label): + def do_append(self, label) -> None: self.labels.append(label) self.stats.append(SCons.Debug.memory()) - def do_print(self): + def do_print(self) -> None: fmt = 'Memory %-32s %12d\n' for label, stats in zip(self.labels, self.stats): self.outfp.write(fmt % (label, stats)) @@ -571,7 +571,7 @@ memory_stats = MemStats() # utility functions -def _scons_syntax_error(e): +def _scons_syntax_error(e) -> None: """Handle syntax errors. Print out a message and show where the error occurred. """ @@ -599,7 +599,7 @@ def find_deepest_user_frame(tb): return frame return tb[0] -def _scons_user_error(e): +def _scons_user_error(e) -> None: """Handle user errors. Print out a message and a description of the error, along with the line number and routine where it occured. The file and line number will be the deepest stack frame that is @@ -614,7 +614,7 @@ def _scons_user_error(e): sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) sys.exit(2) -def _scons_user_warning(e): +def _scons_user_warning(e) -> None: """Handle user warnings. Print out a message and a description of the warning, along with the line number and routine where it occured. The file and line number will be the deepest stack frame that is @@ -625,7 +625,7 @@ def _scons_user_warning(e): sys.stderr.write("\nscons: warning: %s\n" % e) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) -def _scons_internal_warning(e): +def _scons_internal_warning(e) -> None: """Slightly different from _scons_user_warning in that we use the *current call stack* rather than sys.exc_info() to get our stack trace. This is used by the warnings framework to print warnings.""" @@ -633,7 +633,7 @@ def _scons_internal_warning(e): sys.stderr.write("\nscons: warning: %s\n" % e.args[0]) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) -def _scons_internal_error(): +def _scons_internal_error() -> None: """Handle all errors but user errors. Print out a message telling the user what to do in this case and print a normal trace. """ @@ -641,7 +641,7 @@ def _scons_internal_error(): traceback.print_exc() sys.exit(2) -def _SConstruct_exists(dirname='', repositories=[], filelist=None): +def _SConstruct_exists(dirname: str='', repositories=[], filelist=None): """This function checks that an SConstruct file exists in a directory. If so, it returns the path of the file. By default, it checks the current directory. @@ -658,7 +658,7 @@ def _SConstruct_exists(dirname='', repositories=[], filelist=None): return sfile return None -def _set_debug_values(options): +def _set_debug_values(options) -> None: global print_memoizer, print_objects, print_stacktrace, print_time, print_action_timestamps debug_values = options.debug @@ -798,7 +798,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): raise -def _load_all_site_scons_dirs(topdir, verbose=False): +def _load_all_site_scons_dirs(topdir, verbose: bool=False) -> None: """Load all of the predefined site_scons dir. Order is significant; we load them in order from most generic (machine-wide) to most specific (topdir). @@ -841,7 +841,7 @@ def _load_all_site_scons_dirs(topdir, verbose=False): print("Loading site dir ", d) _load_site_scons_dir(d) -def test_load_all_site_scons_dirs(d): +def test_load_all_site_scons_dirs(d) -> None: _load_all_site_scons_dirs(d, True) def version_string(label, module): @@ -858,7 +858,7 @@ def version_string(label, module): module.__developer__, module.__buildsys__) -def path_string(label, module): +def path_string(label, module) -> str: path = module.__path__ return "\t%s path: %s\n"%(label,path) @@ -1327,7 +1327,7 @@ def _build_targets(fs, options, targets, target_top): options=options, closing_message=closing_message, failure_message=failure_message - ): + ) -> None: if jobs.were_interrupted(): if not options.no_progress and not options.silent: sys.stderr.write("scons: Build interrupted.\n") @@ -1353,7 +1353,7 @@ def _build_targets(fs, options, targets, target_top): return nodes -def _exec_main(parser, values): +def _exec_main(parser, values) -> None: sconsflags = os.environ.get('SCONSFLAGS', '') all_args = sconsflags.split() + sys.argv[1:] @@ -1374,7 +1374,7 @@ def _exec_main(parser, values): _main(parser) -def main(): +def main() -> None: global OptionsParser global exit_status global first_command_start diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index 8391d62..fda7445 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -98,7 +98,7 @@ class SConsValues(optparse.Values): in the set_option() method. """ - def __init__(self, defaults): + def __init__(self, defaults) -> None: self.__defaults__ = defaults self.__SConscript_settings__ = {} @@ -300,11 +300,11 @@ class SConsBadOptionError(optparse.BadOptionError): """ - def __init__(self, opt_str, parser=None): + def __init__(self, opt_str, parser=None) -> None: self.opt_str = opt_str self.parser = parser - def __str__(self): + def __str__(self) -> str: return _("no such option: %s") % self.opt_str @@ -396,7 +396,7 @@ class SConsOptionParser(optparse.OptionParser): option.process(opt, value, values, self) - def reparse_local_options(self): + def reparse_local_options(self) -> None: """ Re-parse the leftover command-line options. Parse options stored in `self.largs`, so that any value @@ -491,7 +491,7 @@ class SConsOptionParser(optparse.OptionParser): class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): - def format_usage(self, usage): + def format_usage(self, usage) -> str: """ Formats the usage message. """ return "usage: %s\n" % usage @@ -610,7 +610,7 @@ def Parser(version): op.version = version # options ignored for compatibility - def opt_ignore(option, opt, value, parser): + def opt_ignore(option, opt, value, parser) -> None: sys.stderr.write("Warning: ignoring %s option\n" % opt) op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w", @@ -822,7 +822,7 @@ def Parser(version): action="help", help="Print this message and exit") - def warn_md5_chunksize_deprecated(option, opt, value, parser): + def warn_md5_chunksize_deprecated(option, opt, value, parser) -> None: if opt == '--md5-chunksize': SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "Parameter %s is deprecated. Use " @@ -865,7 +865,7 @@ def Parser(version): action="store_true", help="Cache implicit dependencies") - def opt_implicit_deps(option, opt, value, parser): + def opt_implicit_deps(option, opt, value, parser) -> None: setattr(parser.values, 'implicit_cache', True) setattr(parser.values, option.dest, True) @@ -1002,7 +1002,7 @@ def Parser(version): help="Search up directory tree for SConstruct, " "build Default() targets from local SConscript") - def opt_version(option, opt, value, parser): + def opt_version(option, opt, value, parser) -> None: sys.stdout.write(parser.version + '\n') sys.exit(0) @@ -1010,7 +1010,7 @@ def Parser(version): action="callback", callback=opt_version, help="Print the SCons version number and exit") - def opt_warn(option, opt, value, parser, tree_options=tree_options): + def opt_warn(option, opt, value, parser, tree_options=tree_options) -> None: if SCons.Util.is_String(value): value = value.split(',') parser.values.warn.extend(value) @@ -1033,7 +1033,7 @@ def Parser(version): # we don't want to change. These all get a "the -X option is not # yet implemented" message and don't show up in the help output. - def opt_not_yet(option, opt, value, parser): + def opt_not_yet(option, opt, value, parser) -> None: msg = "Warning: the %s option is not yet implemented\n" % opt sys.stderr.write(msg) diff --git a/SCons/Script/SConscript.py b/SCons/Script/SConscript.py index b72f30e..c0b556c 100644 --- a/SCons/Script/SConscript.py +++ b/SCons/Script/SConscript.py @@ -104,7 +104,7 @@ def compute_exports(exports): class Frame: """A frame on the SConstruct/SConscript call stack""" - def __init__(self, fs, exports, sconscript): + def __init__(self, fs, exports, sconscript) -> None: self.globals = BuildDefaultGlobals() self.retval = None self.prev_dir = fs.getcwd() @@ -332,7 +332,7 @@ def _SConscript(fs, *files, **kw): else: return tuple(results) -def SConscript_exception(file=sys.stderr): +def SConscript_exception(file=sys.stderr) -> None: """Print an exception stack trace just for the SConscript file(s). This will show users who have Python errors where the problem is, without cluttering the output with all of the internal calls leading @@ -481,11 +481,11 @@ class SConsEnvironment(SCons.Environment.Base): kw['_depth'] = kw.get('_depth', 0) + 1 return SCons.Environment.Base.Configure(self, *args, **kw) - def Default(self, *targets): + def Default(self, *targets) -> None: SCons.Script._Set_Default_Targets(self, targets) @staticmethod - def EnsureSConsVersion(major, minor, revision=0): + def EnsureSConsVersion(major, minor, revision: int=0) -> None: """Exit abnormally if the SCons version is not late enough.""" # split string to avoid replacement during build process if SCons.__version__ == '__' + 'VERSION__': @@ -503,7 +503,7 @@ class SConsEnvironment(SCons.Environment.Base): sys.exit(2) @staticmethod - def EnsurePythonVersion(major, minor): + def EnsurePythonVersion(major, minor) -> None: """Exit abnormally if the Python version is not late enough.""" if sys.version_info < (major, minor): v = sys.version.split()[0] @@ -511,10 +511,10 @@ class SConsEnvironment(SCons.Environment.Base): sys.exit(2) @staticmethod - def Exit(value=0): + def Exit(value: int=0) -> None: sys.exit(value) - def Export(self, *vars, **kw): + def Export(self, *vars, **kw) -> None: for var in vars: global_exports.update(compute_exports(self.Split(var))) global_exports.update(kw) @@ -529,7 +529,7 @@ class SConsEnvironment(SCons.Environment.Base): return SCons.Script.Main.GetOption(name) - def Help(self, text, append=False): + def Help(self, text, append: bool=False) -> None: text = self.subst(text, raw=1) SCons.Script.HelpFunction(text, append=append) @@ -602,7 +602,7 @@ class SConsEnvironment(SCons.Environment.Base): global sconscript_chdir sconscript_chdir = flag - def SetOption(self, name, value): + def SetOption(self, name, value) -> None: name = self.subst(name) SCons.Script.Main.SetOption(name, value) @@ -650,7 +650,7 @@ class DefaultEnvironmentCall: thereby prevent expansion of construction variables (since from the user's point of view this was called as a global function, with no associated construction environment).""" - def __init__(self, method_name, subst=0): + def __init__(self, method_name, subst: int=0) -> None: self.method_name = method_name if subst: self.factory = SCons.Defaults.DefaultEnvironment @@ -674,7 +674,7 @@ def BuildDefaultGlobals(): import SCons.Script d = SCons.Script.__dict__ - def not_a_module(m, d=d, mtype=type(SCons.Script)): + def not_a_module(m, d=d, mtype=type(SCons.Script)) -> bool: return not isinstance(d[m], mtype) for m in filter(not_a_module, dir(SCons.Script)): GlobalDict[m] = d[m] diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index 6cfea1b..c8666c4 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -175,11 +175,11 @@ DefaultEnvironment = SCons.Defaults.DefaultEnvironment # Other variables we provide. class TargetList(collections.UserList): - def _do_nothing(self, *args, **kw): + def _do_nothing(self, *args, **kw) -> None: pass - def _add_Default(self, list): + def _add_Default(self, list) -> None: self.extend(list) - def _clear(self): + def _clear(self) -> None: del self[:] ARGUMENTS = {} @@ -199,13 +199,13 @@ DEFAULT_TARGETS = [] # own targets to BUILD_TARGETS. _build_plus_default = TargetList() -def _Add_Arguments(alist): +def _Add_Arguments(alist) -> None: for arg in alist: a, b = arg.split('=', 1) ARGUMENTS[a] = b ARGLIST.append((a, b)) -def _Add_Targets(tlist): +def _Add_Targets(tlist) -> None: if tlist: COMMAND_LINE_TARGETS.extend(tlist) BUILD_TARGETS.extend(tlist) @@ -225,7 +225,7 @@ def _Set_Default_Targets_Has_Not_Been_Called(d, fs): _Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called -def _Set_Default_Targets(env, tlist): +def _Set_Default_Targets(env, tlist) -> None: global DEFAULT_TARGETS global _Get_Default_Targets _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called @@ -250,7 +250,7 @@ def _Set_Default_Targets(env, tlist): # help_text = None -def HelpFunction(text, append=False): +def HelpFunction(text, append: bool=False) -> None: global help_text if help_text is None: if append: @@ -271,7 +271,7 @@ sconscript_reading = 0 _no_missing_sconscript = False _warn_missing_sconscript_deprecated = True -def set_missing_sconscript_error(flag=1): +def set_missing_sconscript_error(flag: int=1): """Set behavior on missing file in SConscript() call. Returns: diff --git a/SCons/Subst.py b/SCons/Subst.py index 645639b..8e6d22e 100644 --- a/SCons/Subst.py +++ b/SCons/Subst.py @@ -40,7 +40,7 @@ _strconv = [ AllowableExceptions = (IndexError, NameError) -def SetAllowableExceptions(*excepts): +def SetAllowableExceptions(*excepts) -> None: global AllowableExceptions AllowableExceptions = [_f for _f in excepts if _f] @@ -59,10 +59,10 @@ class Literal: around a string, then it will be interpreted as literal. When passed to the command interpreter, all special characters will be escaped.""" - def __init__(self, lstr): + def __init__(self, lstr) -> None: self.lstr = lstr - def __str__(self): + def __str__(self) -> str: return self.lstr def escape(self, escape_func): @@ -71,7 +71,7 @@ class Literal: def for_signature(self): return self.lstr - def is_literal(self): + def is_literal(self) -> int: return 1 def __eq__(self, other): @@ -79,7 +79,7 @@ class Literal: return False return self.lstr == other.lstr - def __neq__(self, other): + def __neq__(self, other) -> bool: return not self.__eq__(other) def __hash__(self): @@ -94,7 +94,7 @@ class SpecialAttrWrapper: such that we can return some canonical string during signature calculation to avoid unnecessary rebuilds.""" - def __init__(self, lstr, for_signature=None): + def __init__(self, lstr, for_signature=None) -> None: """The for_signature parameter, if supplied, will be the canonical string we return from for_signature(). Else we will simply return lstr.""" @@ -104,7 +104,7 @@ class SpecialAttrWrapper: else: self.forsig = lstr - def __str__(self): + def __str__(self) -> str: return self.lstr def escape(self, escape_func): @@ -113,7 +113,7 @@ class SpecialAttrWrapper: def for_signature(self): return self.forsig - def is_literal(self): + def is_literal(self) -> int: return 1 def quote_spaces(arg): @@ -131,7 +131,7 @@ class CmdStringHolder(collections.UserString): particular platform, it will return the contained string with the proper escape sequences inserted. """ - def __init__(self, cmd, literal=None): + def __init__(self, cmd, literal=None) -> None: super().__init__(cmd) self.literal = literal @@ -180,7 +180,7 @@ class NLWrapper: cleaner conceptually... """ - def __init__(self, list, func): + def __init__(self, list, func) -> None: self.list = list self.func = func def _return_nodelist(self): @@ -209,7 +209,7 @@ class Targets_or_Sources(collections.UserList): a list during variable expansion. We're not really using any collections.UserList methods in practice. """ - def __init__(self, nl): + def __init__(self, nl) -> None: self.nl = nl def __getattr__(self, attr): nl = self.nl._create_nodelist() @@ -217,10 +217,10 @@ class Targets_or_Sources(collections.UserList): def __getitem__(self, i): nl = self.nl._create_nodelist() return nl[i] - def __str__(self): + def __str__(self) -> str: nl = self.nl._create_nodelist() return str(nl) - def __repr__(self): + def __repr__(self) -> str: nl = self.nl._create_nodelist() return repr(nl) @@ -230,7 +230,7 @@ class Target_or_Source: to access an individual proxy Node, calling the NLWrapper to create a proxy on demand. """ - def __init__(self, nl): + def __init__(self, nl) -> None: self.nl = nl def __getattr__(self, attr): nl = self.nl._create_nodelist() @@ -241,20 +241,20 @@ class Target_or_Source: # pass through, so raise AttributeError for everything. raise AttributeError("NodeList has no attribute: %s" % attr) return getattr(nl0, attr) - def __str__(self): + def __str__(self) -> str: nl = self.nl._create_nodelist() if nl: return str(nl[0]) return '' - def __repr__(self): + def __repr__(self) -> str: nl = self.nl._create_nodelist() if nl: return repr(nl[0]) return '' class NullNodeList(SCons.Util.NullSeq): - def __call__(self, *args, **kwargs): return '' - def __str__(self): return '' + def __call__(self, *args, **kwargs) -> str: return '' + def __str__(self) -> str: return '' NullNodesList = NullNodeList() @@ -335,7 +335,7 @@ class StringSubber: """ - def __init__(self, env, mode, conv, gvars): + def __init__(self, env, mode, conv, gvars) -> None: self.env = env self.mode = mode self.conv = conv @@ -489,7 +489,7 @@ class ListSubber(collections.UserList): and the rest of the object takes care of doing the right thing internally. """ - def __init__(self, env, mode, conv, gvars): + def __init__(self, env, mode, conv, gvars) -> None: super().__init__([]) self.env = env self.mode = mode @@ -503,7 +503,7 @@ class ListSubber(collections.UserList): self.in_strip = None self.next_line() - def expanded(self, s): + def expanded(self, s) -> bool: """Determines if the string s requires further expansion. Due to the implementation of ListSubber expand will call @@ -620,7 +620,7 @@ class ListSubber(collections.UserList): else: self.append(s) - def substitute(self, args, lvars, within_list): + def substitute(self, args, lvars, within_list) -> None: """Substitute expansions in an argument or list of arguments. This serves as a wrapper for splitting up a string into @@ -643,23 +643,23 @@ class ListSubber(collections.UserList): else: self.expand(args, lvars, within_list) - def next_line(self): + def next_line(self) -> None: """Arrange for the next word to start a new line. This is like starting a new word, except that we have to append another line to the result.""" collections.UserList.append(self, []) self.next_word() - def this_word(self): + def this_word(self) -> None: """Arrange for the next word to append to the end of the current last word in the result.""" self.append = self.add_to_current_word - def next_word(self): + def next_word(self) -> None: """Arrange for the next word to start a new word.""" self.append = self.add_new_word - def add_to_current_word(self, x): + def add_to_current_word(self, x) -> None: """Append the string x to the end of the current last word in the result. If that is not possible, then just add it as a new word. Make sure the entire concatenated string @@ -707,7 +707,7 @@ class ListSubber(collections.UserList): y = CmdStringHolder(y, None) self[-1][-1] = y - def add_new_word(self, x): + def add_new_word(self, x) -> None: if not self.in_strip or self.mode != SUBST_SIG: literal = self.literal(x) x = self.conv(x) @@ -724,12 +724,12 @@ class ListSubber(collections.UserList): else: return l() - def open_strip(self, x): + def open_strip(self, x) -> None: """Handle the "open strip" $( token.""" self.add_strip(x) self.in_strip = 1 - def close_strip(self, x): + def close_strip(self, x) -> None: """Handle the "close strip" $) token.""" self.add_strip(x) self.in_strip = None @@ -805,7 +805,7 @@ _separate_args = re.compile(r'(%s|\s+|[^\s$]+|\$)' % _dollar_exps_str) _space_sep = re.compile(r'[\t ]+(?![^{]*})') -def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None, overrides=False): +def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None, overrides: bool=False): """Expand a string or list containing construction variable substitutions. @@ -887,7 +887,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ return result -def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None,overrides=False): +def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None,overrides: bool=False): """Substitute construction variables in a string (or list or other object) and separate the arguments into a command list. diff --git a/SCons/SubstTests.py b/SCons/SubstTests.py index 16bd3c7..dead458 100644 --- a/SCons/SubstTests.py +++ b/SCons/SubstTests.py @@ -36,11 +36,11 @@ from SCons.Subst import (Literal, SUBST_CMD, SUBST_RAW, SUBST_SIG, SpecialAttrWr class DummyNode: """Simple node work-alike.""" - def __init__(self, name): + def __init__(self, name) -> None: self.name = os.path.normpath(name) - def __str__(self): + def __str__(self) -> str: return self.name - def is_literal(self): + def is_literal(self) -> int: return 1 def rfile(self): return self @@ -48,7 +48,7 @@ class DummyNode: return self class DummyEnv: - def __init__(self, dict={}): + def __init__(self, dict={}) -> None: self.dict = dict def Dictionary(self, key = None): @@ -68,13 +68,13 @@ class DummyEnv: dict["SOURCES"] = 'ssig' return dict -def cs(target=None, source=None, env=None, for_signature=None): +def cs(target=None, source=None, env=None, for_signature=None) -> str: return 'cs' def cl(target=None, source=None, env=None, for_signature=None): return ['cl'] -def CmdGen1(target, source, env, for_signature): +def CmdGen1(target, source, env, for_signature) -> str: # Nifty trick...since Environment references are interpolated, # instantiate an instance of a callable class with this one, # which will then get evaluated. @@ -83,7 +83,7 @@ def CmdGen1(target, source, env, for_signature): return "${CMDGEN2('foo', %d)}" % for_signature class CmdGen2: - def __init__(self, mystr, forsig): + def __init__(self, mystr, forsig) -> None: self.mystr = mystr self.expect_for_signature = forsig @@ -94,14 +94,14 @@ class CmdGen2: return [ self.mystr, env.Dictionary('BAR') ] -def CallableWithDefault(target, source, env, for_signature, other_value="default"): +def CallableWithDefault(target, source, env, for_signature, other_value: str="default") -> str: assert str(target) == 't', target assert str(source) == 's', source return "CallableWithDefault: %s"%other_value PartialCallable = partial(CallableWithDefault, other_value="partial") -def CallableWithNoDefault(target, source, env, for_signature, other_value): +def CallableWithNoDefault(target, source, env, for_signature, other_value) -> str: assert str(target) == 't', target assert str(source) == 's', source return "CallableWithNoDefault: %s"%other_value @@ -120,7 +120,7 @@ else: class SubstTestCase(unittest.TestCase): class MyNode(DummyNode): """Simple node work-alike with some extra stuff for testing.""" - def __init__(self, name): + def __init__(self, name) -> None: super().__init__(name) class Attribute: pass @@ -132,19 +132,19 @@ class SubstTestCase(unittest.TestCase): foo = 1 class TestLiteral: - def __init__(self, literal): + def __init__(self, literal) -> None: self.literal = literal - def __str__(self): + def __str__(self) -> str: return self.literal - def is_literal(self): + def is_literal(self) -> int: return 1 class TestCallable: - def __init__(self, value): + def __init__(self, value) -> None: self.value = value - def __call__(self): + def __call__(self) -> None: pass - def __str__(self): + def __str__(self) -> str: return self.value # only use of this is currently commented out below @@ -253,7 +253,7 @@ class SubstTestCase(unittest.TestCase): 'DEFS' : [ ('Q1', '"q1"'), ('Q2', '"$AAA"') ], } - def basic_comparisons(self, function, convert): + def basic_comparisons(self, function, convert) -> None: env = DummyEnv(self.loc) cases = self.basic_cases[:] kwargs = {'target' : self.target, 'source' : self.source, @@ -476,7 +476,7 @@ class scons_subst_TestCase(SubstTestCase): ["|", "|", "c", "1"], ] - def test_subst_env(self): + def test_subst_env(self) -> None: """Test scons_subst(): expansion dictionary""" # The expansion dictionary no longer comes from the construction # environment automatically. @@ -484,7 +484,7 @@ class scons_subst_TestCase(SubstTestCase): s = scons_subst('$AAA', env) assert s == '', s - def test_subst_SUBST_modes(self): + def test_subst_SUBST_modes(self) -> None: """Test scons_subst(): SUBST_* modes""" env = DummyEnv(self.loc) subst_cases = self.subst_cases[:] @@ -512,7 +512,7 @@ class scons_subst_TestCase(SubstTestCase): del subst_cases[:4] assert failed == 0, "%d subst() mode cases failed" % failed - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test scons_subst(): target= and source= arguments""" env = DummyEnv(self.loc) t1 = self.MyNode('t1') @@ -534,7 +534,7 @@ class scons_subst_TestCase(SubstTestCase): result = scons_subst("$TARGETS $SOURCE", env, target=[], source=[]) assert result == " ", result - def test_subst_callable_expansion(self): + def test_subst_callable_expansion(self) -> None: """Test scons_subst(): expanding a callable""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -543,7 +543,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test foo bar with spaces.out s t", newcom - def test_subst_callable_with_default_expansion(self): + def test_subst_callable_with_default_expansion(self) -> None: """Test scons_subst(): expanding a callable with a default value arg""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -552,7 +552,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test CallableWithDefault: default s t", newcom - def test_subst_partial_callable_with_default_expansion(self): + def test_subst_partial_callable_with_default_expansion(self) -> None: """Test scons_subst(): expanding a functools.partial callable which sets the default value in the callable""" env = DummyEnv(self.loc) @@ -562,7 +562,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test CallableWithDefault: partial s t", newcom - def test_subst_partial_callable_with_no_default_expansion(self): + def test_subst_partial_callable_with_no_default_expansion(self) -> None: """Test scons_subst(): expanding a functools.partial callable which sets the value for extraneous function argument""" env = DummyEnv(self.loc) @@ -640,7 +640,7 @@ class scons_subst_TestCase(SubstTestCase): raise AssertionError("did not catch expected UserError") try: - def func(a, b, c): + def func(a, b, c) -> None: pass scons_subst("${func(1)}", env, gvars={'func':func}) except SCons.Errors.UserError as e: @@ -654,7 +654,7 @@ class scons_subst_TestCase(SubstTestCase): else: raise AssertionError("did not catch expected UserError") - def test_subst_raw_function(self): + def test_subst_raw_function(self) -> None: """Test scons_subst(): fetch function with SUBST_RAW plus conv""" # Test that the combination of SUBST_RAW plus a pass-through # conversion routine allows us to fetch a function through the @@ -682,7 +682,7 @@ class scons_subst_TestCase(SubstTestCase): node = scons_subst("$NODE", env, mode=SUBST_SIG, conv=s, gvars=gvars) assert node is n1, node - def test_subst_overriding_gvars(self): + def test_subst_overriding_gvars(self) -> None: """Test scons_subst(): supplying an overriding gvars dictionary""" env = DummyEnv({'XXX' : 'xxx'}) result = scons_subst('$XXX', env, gvars=env.Dictionary()) @@ -691,7 +691,7 @@ class scons_subst_TestCase(SubstTestCase): assert result == 'yyy', result class CLVar_TestCase(unittest.TestCase): - def test_CLVar(self): + def test_CLVar(self) -> None: """Test scons_subst() and scons_subst_list() with CLVar objects""" loc = {} @@ -714,7 +714,7 @@ class CLVar_TestCase(unittest.TestCase): assert cmd_list[0][4] == "test", cmd_list[0][4] - def test_subst_overriding_lvars_overrides(self): + def test_subst_overriding_lvars_overrides(self) -> None: """Test that optional passed arg overrides overrides gvars, and existing lvars.""" env=DummyEnv({'XXX' : 'xxx'}) result = scons_subst('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyz'}) @@ -931,7 +931,7 @@ class scons_subst_list_TestCase(SubstTestCase): [["|", "|", "c", "1"]], ] - def test_subst_env(self): + def test_subst_env(self) -> None: """Test scons_subst_list(): expansion dictionary""" # The expansion dictionary no longer comes from the construction # environment automatically. @@ -939,7 +939,7 @@ class scons_subst_list_TestCase(SubstTestCase): s = scons_subst_list('$AAA', env) assert s == [[]], s - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test scons_subst_list(): target= and source= arguments""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -966,7 +966,7 @@ class scons_subst_list_TestCase(SubstTestCase): gvars=gvars) assert cmd_list == [['testing', 'foo', 'bar with spaces.out', 't', 's']], cmd_list - def test_subst_escape(self): + def test_subst_escape(self) -> None: """Test scons_subst_list(): escape functionality""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -1009,7 +1009,7 @@ class scons_subst_list_TestCase(SubstTestCase): c = cmd_list[0][2].escape(escape_func) assert c == 't"', c - def test_subst_SUBST_modes(self): + def test_subst_SUBST_modes(self) -> None: """Test scons_subst_list(): SUBST_* modes""" env = DummyEnv(self.loc) subst_list_cases = self.subst_list_cases[:] @@ -1073,7 +1073,7 @@ class scons_subst_list_TestCase(SubstTestCase): else: raise AssertionError("did not catch expected SyntaxError") - def test_subst_raw_function(self): + def test_subst_raw_function(self) -> None: """Test scons_subst_list(): fetch function with SUBST_RAW plus conv""" # Test that the combination of SUBST_RAW plus a pass-through # conversion routine allows us to fetch a function through the @@ -1086,7 +1086,7 @@ class scons_subst_list_TestCase(SubstTestCase): r = scons_subst_list("$CALLABLE2", env, mode=SUBST_RAW, gvars=gvars) assert r == [['callable-2']], repr(r) - def test_subst_list_overriding_gvars(self): + def test_subst_list_overriding_gvars(self) -> None: """Test scons_subst_list(): overriding conv()""" env = DummyEnv() def s(obj): @@ -1102,7 +1102,7 @@ class scons_subst_list_TestCase(SubstTestCase): node = scons_subst_list("$NODE", env, mode=SUBST_SIG, conv=s, gvars=gvars) assert node == [[n1]], node - def test_subst_list_overriding_gvars2(self): + def test_subst_list_overriding_gvars2(self) -> None: """Test scons_subst_list(): supplying an overriding gvars dictionary""" env = DummyEnv({'XXX' : 'xxx'}) result = scons_subst_list('$XXX', env, gvars=env.Dictionary()) @@ -1110,7 +1110,7 @@ class scons_subst_list_TestCase(SubstTestCase): result = scons_subst_list('$XXX', env, gvars={'XXX' : 'yyy'}) assert result == [['yyy']], result - def test_subst_list_overriding_lvars_overrides(self): + def test_subst_list_overriding_lvars_overrides(self) -> None: """Test that optional passed arg overrides overrides gvars, and existing lvars.""" env = DummyEnv({'XXX':'xxx'}) result = scons_subst_list('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyy'}) @@ -1168,7 +1168,7 @@ class scons_subst_once_TestCase(unittest.TestCase): ['x', 'x $RECURSE y', 'y'], ] - def test_subst_once(self): + def test_subst_once(self) -> None: """Test the scons_subst_once() function""" env = DummyEnv(self.loc) cases = self.basic_cases[:] @@ -1185,7 +1185,7 @@ class scons_subst_once_TestCase(unittest.TestCase): assert failed == 0, "%d subst() cases failed" % failed class quote_spaces_TestCase(unittest.TestCase): - def test_quote_spaces(self): + def test_quote_spaces(self) -> None: """Test the quote_spaces() method...""" q = quote_spaces('x') assert q == 'x', q @@ -1197,30 +1197,30 @@ class quote_spaces_TestCase(unittest.TestCase): assert q == '"x\tx"', q class Node: - def __init__(self, name, children=[]): + def __init__(self, name, children=[]) -> None: self.children = children self.name = name - def __str__(self): + def __str__(self) -> str: return self.name - def exists(self): + def exists(self) -> int: return 1 - def rexists(self): + def rexists(self) -> int: return 1 - def has_builder(self): + def has_builder(self) -> int: return 1 - def has_explicit_builder(self): + def has_explicit_builder(self) -> int: return 1 - def side_effect(self): + def side_effect(self) -> int: return 1 - def precious(self): + def precious(self) -> int: return 1 - def always_build(self): + def always_build(self) -> int: return 1 - def current(self): + def current(self) -> int: return 1 class LiteralTestCase(unittest.TestCase): - def test_Literal(self): + def test_Literal(self) -> None: """Test the Literal() function.""" input_list = [ '$FOO', Literal('$BAR') ] gvars = { 'FOO' : 'BAZ', 'BAR' : 'BLAT' } @@ -1232,13 +1232,13 @@ class LiteralTestCase(unittest.TestCase): cmd_list = escape_list(cmd_list[0], escape_func) assert cmd_list == ['BAZ', '**$BAR**'], cmd_list - def test_LiteralEqualsTest(self): + def test_LiteralEqualsTest(self) -> None: """Test that Literals compare for equality properly""" assert Literal('a literal') == Literal('a literal') assert Literal('a literal') != Literal('b literal') class SpecialAttrWrapperTestCase(unittest.TestCase): - def test_SpecialAttrWrapper(self): + def test_SpecialAttrWrapper(self) -> None: """Test the SpecialAttrWrapper() function.""" input_list = [ '$FOO', SpecialAttrWrapper('$BAR', 'BLEH') ] gvars = { 'FOO' : 'BAZ', 'BAR' : 'BLAT' } @@ -1255,7 +1255,7 @@ class SpecialAttrWrapperTestCase(unittest.TestCase): assert cmd_list == ['BAZ', '**BLEH**'], cmd_list class subst_dict_TestCase(unittest.TestCase): - def test_subst_dict(self): + def test_subst_dict(self) -> None: """Test substituting dictionary values in an Action """ t = DummyNode('t') @@ -1280,9 +1280,9 @@ class subst_dict_TestCase(unittest.TestCase): class V: # Fake Value node with no rfile() method. - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return 'v-'+self.name def get_subst_proxy(self): return self diff --git a/SCons/Taskmaster/Job.py b/SCons/Taskmaster/Job.py index a63b529..572464b 100644 --- a/SCons/Taskmaster/Job.py +++ b/SCons/Taskmaster/Job.py @@ -55,10 +55,10 @@ default_stack_size = 256 interrupt_msg = 'Build interrupted.' class InterruptState: - def __init__(self): + def __init__(self) -> None: self.interrupted = False - def set(self): + def set(self) -> None: self.interrupted = True def __call__(self): @@ -70,7 +70,7 @@ class Jobs: methods for starting, stopping, and waiting on all N jobs. """ - def __init__(self, num, taskmaster): + def __init__(self, num, taskmaster) -> None: """ Create 'num' jobs using the given taskmaster. @@ -109,7 +109,7 @@ class Jobs: self.job = Serial(taskmaster) self.num_jobs = 1 - def run(self, postfunc=lambda: None): + def run(self, postfunc=lambda: None) -> None: """Run the jobs. postfunc() will be invoked after the jobs has run. It will be @@ -129,7 +129,7 @@ class Jobs: """Returns whether the jobs were interrupted by a signal.""" return self.job.interrupted() - def _setup_sig_handler(self): + def _setup_sig_handler(self) -> None: """Setup an interrupt handler so that SCons can shutdown cleanly in various conditions: @@ -150,7 +150,7 @@ class Jobs: SCons forks before executing another process. In that case, we want the child to exit immediately. """ - def handler(signum, stack, self=self, parentpid=os.getpid()): + def handler(signum, stack, self=self, parentpid=os.getpid()) -> None: if os.getpid() == parentpid: self.job.taskmaster.stop() self.job.interrupted.set() @@ -169,7 +169,7 @@ class Jobs: "Will not be able to reinstate and so will return to default handler." SCons.Warnings.warn(SCons.Warnings.SConsWarning, msg) - def _reset_sig_handler(self): + def _reset_sig_handler(self) -> None: """Restore the signal handlers to their previous state (before the call to _setup_sig_handler().""" sigint_to_use = self.old_sigint if self.old_sigint is not None else signal.SIG_DFL @@ -191,7 +191,7 @@ class Serial: This class is not thread safe. """ - def __init__(self, taskmaster): + def __init__(self, taskmaster) -> None: """Create a new serial job given a taskmaster. The taskmaster's next_task() method should return the next task @@ -253,7 +253,7 @@ else: dequeues the task, executes it, and posts a tuple including the task and a boolean indicating whether the task executed successfully. """ - def __init__(self, requestQueue, resultsQueue, interrupted): + def __init__(self, requestQueue, resultsQueue, interrupted) -> None: super().__init__() self.daemon = True self.requestQueue = requestQueue @@ -287,7 +287,7 @@ else: class ThreadPool: """This class is responsible for spawning and managing worker threads.""" - def __init__(self, num, stack_size, interrupted): + def __init__(self, num, stack_size, interrupted) -> None: """Create the request and reply queues, and 'num' worker threads. One must specify the stack size of the worker threads. The @@ -318,7 +318,7 @@ else: if 'prev_size' in locals(): threading.stack_size(prev_size) - def put(self, task): + def put(self, task) -> None: """Put task into request queue.""" self.requestQueue.put(task) @@ -326,10 +326,10 @@ else: """Remove and return a result tuple from the results queue.""" return self.resultsQueue.get() - def preparation_failed(self, task): + def preparation_failed(self, task) -> None: self.resultsQueue.put((task, False)) - def cleanup(self): + def cleanup(self) -> None: """ Shuts down the thread pool, giving each worker thread a chance to shut down gracefully. @@ -365,7 +365,7 @@ else: This class is thread safe. """ - def __init__(self, taskmaster, num, stack_size): + def __init__(self, taskmaster, num, stack_size) -> None: """Create a new parallel job given a taskmaster. The taskmaster's next_task() method should return the next @@ -459,16 +459,16 @@ else: COMPLETED = 3 class Worker(threading.Thread): - def __init__(self, owner): + def __init__(self, owner) -> None: super().__init__() self.daemon = True self.owner = owner self.start() - def run(self): + def run(self) -> None: self.owner._work() - def __init__(self, taskmaster, num, stack_size): + def __init__(self, taskmaster, num, stack_size) -> None: self.taskmaster = taskmaster self.num_workers = num self.stack_size = stack_size @@ -507,21 +507,21 @@ else: jl.addHandler(self.taskmaster.trace.log_handler) return jl - def trace_message(self, message): + def trace_message(self, message) -> None: # This grabs the name of the function which calls trace_message() method_name = sys._getframe(1).f_code.co_name + "():" thread_id=threading.get_ident() self.trace.debug('%s.%s [Thread:%s] %s' % (type(self).__name__, method_name, thread_id, message)) # print('%-15s %s' % (method_name, message)) - def start(self): + def start(self) -> None: self._start_workers() for worker in self.workers: worker.join() self.workers = [] self.taskmaster.cleanup() - def _start_workers(self): + def _start_workers(self) -> None: prev_size = self._adjust_stack_size() for _ in range(self.num_workers): self.workers.append(NewParallel.Worker(self)) @@ -544,7 +544,7 @@ else: return None - def _restore_stack_size(self, prev_size): + def _restore_stack_size(self, prev_size) -> None: if prev_size is not None: threading.stack_size(prev_size) diff --git a/SCons/Taskmaster/JobTests.py b/SCons/Taskmaster/JobTests.py index 9e7b080..3faa97d 100644 --- a/SCons/Taskmaster/JobTests.py +++ b/SCons/Taskmaster/JobTests.py @@ -63,37 +63,37 @@ num_tasks = num_jobs*5 class DummyLock: """fake lock class to use if threads are not supported""" - def acquire(self): + def acquire(self) -> None: pass - def release(self): + def release(self) -> None: pass class NoThreadsException(Exception): """raised by the ParallelTestCase if threads are not supported""" - def __str__(self): + def __str__(self) -> str: return "the interpreter doesn't support threads" class Task: """A dummy task class for testing purposes.""" - def __init__(self, i, taskmaster): + def __init__(self, i, taskmaster) -> None: self.i = i self.taskmaster = taskmaster self.was_executed = 0 self.was_prepared = 0 - def prepare(self): + def prepare(self) -> None: self.was_prepared = 1 - def _do_something(self): + def _do_something(self) -> None: pass - def needs_execute(self): + def needs_execute(self) -> bool: return True - def execute(self): + def execute(self) -> None: self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") @@ -119,7 +119,7 @@ class Task: self.taskmaster.end_list.append(self.i) self.taskmaster.guard.release() - def executed(self): + def executed(self) -> None: self.taskmaster.num_executed = self.taskmaster.num_executed + 1 self.taskmaster.test_case.assertTrue(self.was_prepared, @@ -129,20 +129,20 @@ class Task: self.taskmaster.test_case.assertTrue(isinstance(self, Task), "the task wasn't really a Task instance") - def failed(self): + def failed(self) -> None: self.taskmaster.num_failed = self.taskmaster.num_failed + 1 self.taskmaster.stop = 1 self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") - def postprocess(self): + def postprocess(self) -> None: self.taskmaster.num_postprocessed = self.taskmaster.num_postprocessed + 1 - def exception_set(self): + def exception_set(self) -> None: pass class RandomTask(Task): - def _do_something(self): + def _do_something(self) -> None: # do something that will take some random amount of time: for i in range(random.randrange(0, 100 + num_sines, 1)): x = math.sin(i) @@ -151,20 +151,20 @@ class RandomTask(Task): class ExceptionTask: """A dummy task class for testing purposes.""" - def __init__(self, i, taskmaster): + def __init__(self, i, taskmaster) -> None: self.taskmaster = taskmaster self.was_prepared = 0 - def prepare(self): + def prepare(self) -> None: self.was_prepared = 1 - def needs_execute(self): + def needs_execute(self) -> bool: return True def execute(self): raise Exception - def executed(self): + def executed(self) -> None: self.taskmaster.num_executed = self.taskmaster.num_executed + 1 self.taskmaster.test_case.assertTrue(self.was_prepared, @@ -174,22 +174,22 @@ class ExceptionTask: self.taskmaster.test_case.assertTrue(self.__class__ is Task, "the task wasn't really a Task instance") - def failed(self): + def failed(self) -> None: self.taskmaster.num_failed = self.taskmaster.num_failed + 1 self.taskmaster.stop = 1 self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") - def postprocess(self): + def postprocess(self) -> None: self.taskmaster.num_postprocessed = self.taskmaster.num_postprocessed + 1 - def exception_set(self): + def exception_set(self) -> None: self.taskmaster.exception_set() class Taskmaster: """A dummy taskmaster class for testing the job classes.""" - def __init__(self, n, test_case, Task): + def __init__(self, n, test_case, Task) -> None: """n is the number of dummy tasks to perform.""" self.test_case = test_case @@ -232,14 +232,14 @@ class Taskmaster: def all_tasks_are_postprocessed(self): return self.num_postprocessed == self.num_tasks - def tasks_were_serial(self): + def tasks_were_serial(self) -> bool: """analyze the task order to see if they were serial""" return not self.found_parallel - def exception_set(self): + def exception_set(self) -> None: pass - def cleanup(self): + def cleanup(self) -> None: pass @@ -292,7 +292,7 @@ class ParallelTestCase(JobTestCase): # tasks complete and get their notifications on the resultsQueue. class SleepTask(Task): - def _do_something(self): + def _do_something(self) -> None: time.sleep(0.01) global SaveThreadPool @@ -329,7 +329,7 @@ class ParallelTestCase(JobTestCase): SCons.Taskmaster.Job.ThreadPool = SaveThreadPool class SerialTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """test a serial job""" taskmaster = Taskmaster(num_tasks, self, RandomTask) @@ -350,7 +350,7 @@ class SerialTestCase(unittest.TestCase): class NoParallelTestCase(JobTestCase): - def runTest(self): + def runTest(self) -> None: """test handling lack of parallel support""" def NoParallel(tm, num, stack_size): raise NameError @@ -377,7 +377,7 @@ class NoParallelTestCase(JobTestCase): class SerialExceptionTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """test a serial job with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) @@ -396,7 +396,7 @@ class SerialExceptionTestCase(unittest.TestCase): class ParallelExceptionTestCase(JobTestCase): - def runTest(self): + def runTest(self) -> None: """test parallel jobs with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) @@ -421,23 +421,23 @@ import SCons.Node import time class DummyNodeInfo: - def update(self, obj): + def update(self, obj) -> None: pass class testnode (SCons.Node.Node): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.executed self.ninfo = DummyNodeInfo() class goodnode (testnode): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.up_to_date self.ninfo = DummyNodeInfo() class slowgoodnode (goodnode): - def prepare(self): + def prepare(self) -> None: # Delay to allow scheduled Jobs to run while the dispatcher # sleeps. Keep this short because it affects the time taken # by this test. @@ -445,7 +445,7 @@ class slowgoodnode (goodnode): goodnode.prepare(self) class badnode (goodnode): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.failed def build(self, **kw): @@ -467,7 +467,7 @@ class badpreparenode (badnode): class _SConsTaskTest(JobTestCase): - def _test_seq(self, num_jobs): + def _test_seq(self, num_jobs) -> None: for node_seq in [ [goodnode], [badnode], @@ -484,7 +484,7 @@ class _SConsTaskTest(JobTestCase): self._do_test(num_jobs, node_seq) - def _do_test(self, num_jobs, node_seq): + def _do_test(self, num_jobs, node_seq) -> None: testnodes = [] for tnum in range(num_tasks): @@ -549,13 +549,13 @@ class _SConsTaskTest(JobTestCase): class SerialTaskTest(_SConsTaskTest): - def runTest(self): + def runTest(self) -> None: """test serial jobs with actual Taskmaster and Task""" self._test_seq(1) class ParallelTaskTest(_SConsTaskTest): - def runTest(self): + def runTest(self) -> None: """test parallel jobs with actual Taskmaster and Task""" self._test_seq(num_jobs) diff --git a/SCons/Taskmaster/TaskmasterTests.py b/SCons/Taskmaster/TaskmasterTests.py index 95150fd..32959fb 100644 --- a/SCons/Taskmaster/TaskmasterTests.py +++ b/SCons/Taskmaster/TaskmasterTests.py @@ -39,7 +39,7 @@ scan_called = 0 class Node: - def __init__(self, name, kids=[], scans=[]): + def __init__(self, name, kids=[], scans=[]) -> None: self.name = name self.kids = kids self.scans = scans @@ -72,7 +72,7 @@ class Node: def disambiguate(self): return self - def push_to_cache(self): + def push_to_cache(self) -> None: pass def retrieve_from_cache(self): @@ -81,18 +81,18 @@ class Node: cache_text.append(self.name + " retrieved") return self.cached - def make_ready(self): + def make_ready(self) -> None: pass - def prepare(self): + def prepare(self) -> None: self.prepared = 1 self.get_binfo() - def build(self): + def build(self) -> None: global built_text built_text = self.name + " built" - def remove(self): + def remove(self) -> None: pass # The following four methods new_binfo(), del_binfo(), @@ -104,7 +104,7 @@ class Node: binfo = "binfo" return binfo - def del_binfo(self): + def del_binfo(self) -> None: """Delete the build info from this node.""" try: delattr(self, 'binfo') @@ -123,13 +123,13 @@ class Node: return binfo - def clear(self): + def clear(self) -> None: # The del_binfo() call here isn't necessary for normal execution, # but is for interactive mode, where we might rebuild the same # target and need to start from scratch. self.del_binfo() - def built(self): + def built(self) -> None: global built_text if not self.cached: built_text = built_text + " really" @@ -141,10 +141,10 @@ class Node: self.clear() - def release_target_info(self): + def release_target_info(self) -> None: pass - def has_builder(self): + def has_builder(self) -> bool: return self.builder is not None def is_derived(self): @@ -153,7 +153,7 @@ class Node: def alter_targets(self): return self.alttargets, None - def visited(self): + def visited(self) -> None: global visited_nodes visited_nodes.append(self.name) @@ -163,7 +163,7 @@ class Node: self.scanned = 1 return self.kids - def scan(self): + def scan(self) -> None: global scan_called scan_called = scan_called + 1 self.kids = self.kids + self.scans @@ -172,7 +172,7 @@ class Node: def scanner_key(self): return self.name - def add_to_waiting_parents(self, node): + def add_to_waiting_parents(self, node) -> int: wp = self.waiting_parents if node in wp: return 0 @@ -182,44 +182,44 @@ class Node: def get_state(self): return self.state - def set_state(self, state): + def set_state(self, state) -> None: self.state = state - def set_bsig(self, bsig): + def set_bsig(self, bsig) -> None: self.bsig = bsig - def set_csig(self, csig): + def set_csig(self, csig) -> None: self.csig = csig - def store_csig(self): + def store_csig(self) -> None: pass - def store_bsig(self): + def store_bsig(self) -> None: pass - def is_pseudo_derived(self): + def is_pseudo_derived(self) -> None: pass def is_up_to_date(self): return self._current_val - def depends_on(self, nodes): + def depends_on(self, nodes) -> int: for node in nodes: if node in self.kids: return 1 return 0 - def __str__(self): + def __str__(self) -> str: return self.name - def postprocess(self): + def postprocess(self) -> None: self.postprocessed = 1 self.waiting_parents = set() def get_executor(self): if not hasattr(self, 'executor'): class Executor: - def prepare(self): + def prepare(self) -> None: pass def get_action_targets(self): @@ -261,7 +261,7 @@ class MyException(Exception): class TaskmasterTestCase(unittest.TestCase): - def test_next_task(self): + def test_next_task(self) -> None: """Test fetching the next task """ global built_text @@ -307,7 +307,7 @@ class TaskmasterTestCase(unittest.TestCase): top_node = n3 class MyTask(SCons.Taskmaster.AlwaysTask): - def execute(self): + def execute(self) -> None: global built_text if self.targets[0].get_state() == SCons.Node.up_to_date: if self.top: @@ -550,14 +550,14 @@ class TaskmasterTestCase(unittest.TestCase): s = n2.get_state() assert s == SCons.Node.executed, s - def test_make_ready_out_of_date(self): + def test_make_ready_out_of_date(self) -> None: """Test the Task.make_ready() method's list of out-of-date Nodes """ ood = [] def TaskGen(tm, targets, top, node, ood=ood): class MyTask(SCons.Taskmaster.AlwaysTask): - def make_ready(self): + def make_ready(self) -> None: SCons.Taskmaster.Task.make_ready(self) self.ood.extend(self.out_of_date) @@ -597,7 +597,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() assert ood == [a5], ood - def test_make_ready_exception(self): + def test_make_ready_exception(self) -> None: """Test handling exceptions from Task.make_ready() """ @@ -612,7 +612,7 @@ class TaskmasterTestCase(unittest.TestCase): assert exc_type == MyException, repr(exc_type) assert str(exc_value) == "from make_ready()", exc_value - def test_needs_execute(self): + def test_needs_execute(self) -> None: """Test that we can't instantiate a Task subclass without needs_execute We should be getting: @@ -627,7 +627,7 @@ class TaskmasterTestCase(unittest.TestCase): with self.assertRaises(TypeError): _ = tm.next_task() - def test_make_ready_all(self): + def test_make_ready_all(self) -> None: """Test the make_ready_all() method""" class MyTask(SCons.Taskmaster.AlwaysTask): @@ -688,7 +688,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() assert t is None - def test_children_errors(self): + def test_children_errors(self) -> None: """Test errors when fetching the children of a node. """ @@ -697,7 +697,7 @@ class TaskmasterTestCase(unittest.TestCase): raise SCons.Errors.StopError("stop!") class ExitNode(Node): - def children(self): + def children(self) -> None: sys.exit(77) n1 = StopNode("n1") @@ -715,7 +715,7 @@ class TaskmasterTestCase(unittest.TestCase): assert exc_value.node == n2, exc_value.node assert exc_value.status == 77, exc_value.status - def test_cycle_detection(self): + def test_cycle_detection(self) -> None: """Test detecting dependency cycles """ n1 = Node("n1") @@ -731,7 +731,7 @@ class TaskmasterTestCase(unittest.TestCase): else: assert 'Did not catch expected UserError' - def test_next_top_level_candidate(self): + def test_next_top_level_candidate(self) -> None: """Test the next_top_level_candidate() method """ n1 = Node("n1") @@ -745,7 +745,7 @@ class TaskmasterTestCase(unittest.TestCase): assert t.targets == [n3], list(map(str, t.targets)) assert t.top == 1, t.top - def test_stop(self): + def test_stop(self) -> None: """Test the stop() method Both default and overridden in a subclass. @@ -769,7 +769,7 @@ class TaskmasterTestCase(unittest.TestCase): assert tm.next_task() is None class MyTM(SCons.Taskmaster.Taskmaster): - def stop(self): + def stop(self) -> None: global built_text built_text = "MyTM.stop()" SCons.Taskmaster.Taskmaster.stop(self) @@ -787,7 +787,7 @@ class TaskmasterTestCase(unittest.TestCase): assert built_text == "MyTM.stop()" assert tm.next_task() is None - def test_executed(self): + def test_executed(self) -> None: """Test when a task has been executed """ global built_text @@ -945,7 +945,7 @@ class TaskmasterTestCase(unittest.TestCase): else: raise AssertionError("did not catch expected exception") - def test_execute(self): + def test_execute(self) -> None: """Test executing a task """ global built_text @@ -1043,7 +1043,7 @@ class TaskmasterTestCase(unittest.TestCase): assert built_text is None, built_text assert cache_text == ["n7 retrieved", "n8 retrieved"], cache_text - def test_cached_execute(self): + def test_cached_execute(self) -> None: """Test executing a task with cached targets """ # In issue #2720 Alexei Klimkin detected that the previous @@ -1087,7 +1087,7 @@ class TaskmasterTestCase(unittest.TestCase): has_binfo = hasattr(n1, 'binfo') assert has_binfo, has_binfo - def test_cached_execute_target_unlink_fails(self): + def test_cached_execute_target_unlink_fails(self) -> None: """Test executing a task with cached targets where unlinking one of the targets fail """ global cache_text @@ -1114,7 +1114,7 @@ class TaskmasterTestCase(unittest.TestCase): _save_warn = SCons.Warnings.warn issued_warnings = [] - def fake_warnings_warn(clz, message): + def fake_warnings_warn(clz, message) -> None: nonlocal issued_warnings issued_warnings.append((clz, message)) SCons.Warnings.warn = fake_warnings_warn @@ -1136,7 +1136,7 @@ class TaskmasterTestCase(unittest.TestCase): self.assertEqual(cache_text, ["n1 retrieved"], msg=cache_text) - def test_exception(self): + def test_exception(self) -> None: """Test generic Taskmaster exception handling """ @@ -1221,7 +1221,7 @@ class TaskmasterTestCase(unittest.TestCase): else: assert 0, "did not catch expected exception" - def test_postprocess(self): + def test_postprocess(self) -> None: """Test postprocessing targets to give them a chance to clean up """ n1 = Node("n1") @@ -1247,7 +1247,7 @@ class TaskmasterTestCase(unittest.TestCase): assert n2.postprocessed assert n3.postprocessed - def test_trace(self): + def test_trace(self) -> None: """Test Taskmaster tracing """ import io diff --git a/SCons/Taskmaster/__init__.py b/SCons/Taskmaster/__init__.py index 7ab864e..7965ca8 100644 --- a/SCons/Taskmaster/__init__.py +++ b/SCons/Taskmaster/__init__.py @@ -81,7 +81,7 @@ class Stats: the Taskmaster records its decision each time it processes the Node. (Ideally, that's just once per Node.) """ - def __init__(self): + def __init__(self) -> None: """ Instantiates a Taskmaster.Stats object, initializing all appropriate counters to zero. @@ -106,7 +106,7 @@ fmt = "%(considered)3d "\ "%(build)3d " -def dump_stats(): +def dump_stats() -> None: for n in sorted(StatsNodes, key=lambda a: str(a)): print((fmt % n.attributes.stats.__dict__) + str(n)) @@ -132,19 +132,19 @@ class Task(ABC): LOGGER = None - def __init__(self, tm, targets, top, node): + def __init__(self, tm, targets, top, node) -> None: self.tm = tm self.targets = targets self.top = top self.node = node self.exc_clear() - def trace_message(self, node, description='node'): + def trace_message(self, node, description: str='node') -> None: # This grabs the name of the function which calls trace_message() method_name=sys._getframe(1).f_code.co_name+"():" Task.LOGGER.debug('%-15s %s %s' % (method_name, description, self.tm.tm_trace_node(node))) - def display(self, message): + def display(self, message) -> None: """ Hook to allow the calling interface to display a message. @@ -157,7 +157,7 @@ class Task(ABC): """ pass - def prepare(self): + def prepare(self) -> None: """ Called just before the task is executed. @@ -260,7 +260,7 @@ class Task(ABC): buildError.exc_info = sys.exc_info() raise buildError - def executed_without_callbacks(self): + def executed_without_callbacks(self) -> None: """ Called when the task has been successfully executed and the Taskmaster instance doesn't want to call @@ -276,7 +276,7 @@ class Task(ABC): side_effect.set_state(NODE_NO_STATE) t.set_state(NODE_EXECUTED) - def executed_with_callbacks(self): + def executed_with_callbacks(self) -> None: """ Called when the task has been successfully executed and the Taskmaster instance wants to call the Node's callback @@ -311,7 +311,7 @@ class Task(ABC): executed = executed_with_callbacks - def failed(self): + def failed(self) -> None: """ Default action when a task fails: stop the build. @@ -321,7 +321,7 @@ class Task(ABC): """ self.fail_stop() - def fail_stop(self): + def fail_stop(self) -> None: """ Explicit stop-the-build failure. @@ -349,7 +349,7 @@ class Task(ABC): self.targets = [self.tm.current_top] self.top = 1 - def fail_continue(self): + def fail_continue(self) -> None: """ Explicit continue-the-build failure. @@ -366,7 +366,7 @@ class Task(ABC): self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED)) - def make_ready_all(self): + def make_ready_all(self) -> None: """ Marks all targets in a task ready for execution. @@ -431,7 +431,7 @@ class Task(ABC): make_ready = make_ready_current - def postprocess(self): + def postprocess(self) -> None: """ Post-processes a task after it's been executed. @@ -511,7 +511,7 @@ class Task(ABC): """ return self.exception - def exc_clear(self): + def exc_clear(self) -> None: """ Clears any recorded exception. @@ -521,7 +521,7 @@ class Task(ABC): self.exception = (None, None, None) self.exception_raise = self._no_exception_to_raise - def exception_set(self, exception=None): + def exception_set(self, exception=None) -> None: """ Records an exception to be raised at the appropriate time. @@ -533,7 +533,7 @@ class Task(ABC): self.exception = exception self.exception_raise = self._exception_raise - def _no_exception_to_raise(self): + def _no_exception_to_raise(self) -> None: pass def _exception_raise(self): @@ -563,7 +563,7 @@ class Task(ABC): class AlwaysTask(Task): - def needs_execute(self): + def needs_execute(self) -> bool: """ Always returns True (indicating this Task should always be executed). @@ -606,7 +606,7 @@ class Taskmaster: The Taskmaster for walking the dependency DAG. """ - def __init__(self, targets=[], tasker=None, order=None, trace=None): + def __init__(self, targets=[], tasker=None, order=None, trace=None) -> None: self.original_top = targets self.top_targets_left = targets[:] self.top_targets_left.reverse() @@ -623,7 +623,7 @@ class Taskmaster: self.trace = False self.configure_trace(trace) - def configure_trace(self, trace=None): + def configure_trace(self, trace=None) -> None: """ This handles the command line option --taskmastertrace= It can be: @@ -726,7 +726,7 @@ class Taskmaster: self.will_not_build(candidates) return None - def _validate_pending_children(self): + def _validate_pending_children(self) -> None: """ Validate the content of the pending_children set. Assert if an internal error is found. @@ -803,7 +803,7 @@ class Taskmaster: for p in n.waiting_parents: assert p.ref_count > 0, (str(n), str(p), p.ref_count) - def tm_trace_node(self, node): + def tm_trace_node(self, node) -> str: return('<%-10s %-3s %s>' % (StateString[node.get_state()], node.ref_count, repr(str(node)))) @@ -1047,7 +1047,7 @@ class Taskmaster: return task - def will_not_build(self, nodes, node_func=lambda n: None): + def will_not_build(self, nodes, node_func=lambda n: None) -> None: """ Perform clean-up about nodes that will never be built. Invokes a user defined function on all of these nodes (including all @@ -1092,7 +1092,7 @@ class Taskmaster: # allow us to use in-place updates self.pending_children = pending_children - def stop(self): + def stop(self) -> None: """ Stops the current build completely. """ diff --git a/SCons/Tool/386asm.py b/SCons/Tool/386asm.py index 51738eb..f19f758 100644 --- a/SCons/Tool/386asm.py +++ b/SCons/Tool/386asm.py @@ -39,7 +39,7 @@ import SCons.Util as_module = __import__('as', globals(), locals(), [], 1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" as_module.generate(env) diff --git a/SCons/Tool/DCommon.py b/SCons/Tool/DCommon.py index 128e561..a4f976d 100644 --- a/SCons/Tool/DCommon.py +++ b/SCons/Tool/DCommon.py @@ -32,7 +32,7 @@ Coded by Russel Winder (russel@winder.org.uk) import os.path -def isD(env, source): +def isD(env, source) -> int: if not source: return 0 for s in source: @@ -43,7 +43,7 @@ def isD(env, source): return 0 -def addDPATHToEnv(env, executable): +def addDPATHToEnv(env, executable) -> None: dPath = env.WhereIs(executable) if dPath: phobosDir = dPath[:dPath.rindex(executable)] + '/../src/phobos' diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py index aff0f92..f893a12 100644 --- a/SCons/Tool/FortranCommon.py +++ b/SCons/Tool/FortranCommon.py @@ -30,7 +30,7 @@ from typing import Tuple import SCons.Scanner.Fortran import SCons.Tool import SCons.Util -from SCons.Action import Action +from SCons.Action import Action, ActionBase def isfortran(env, source) -> bool: @@ -115,7 +115,9 @@ def ComputeFortranSuffixes(suffixes, ppsuffixes) -> None: else: suffixes.extend(upper_suffixes) -def CreateDialectActions(dialect) -> Tuple[Action, Action, Action, Action]: +def CreateDialectActions( + dialect: str, +) -> Tuple[ActionBase, ActionBase, ActionBase, ActionBase]: """Create dialect specific actions.""" CompAction = Action(f'${dialect}COM ', cmdstr=f'${dialect}COMSTR') CompPPAction = Action(f'${dialect}PPCOM ', cmdstr=f'${dialect}PPCOMSTR') @@ -124,7 +126,7 @@ def CreateDialectActions(dialect) -> Tuple[Action, Action, Action, Action]: return CompAction, CompPPAction, ShCompAction, ShCompPPAction -def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_mods=False) -> None: +def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_mods: bool=False) -> None: """Add dialect specific construction variables. Args: diff --git a/SCons/Tool/FortranCommonTests.py b/SCons/Tool/FortranCommonTests.py index 56f41c7..a2960d6 100644 --- a/SCons/Tool/FortranCommonTests.py +++ b/SCons/Tool/FortranCommonTests.py @@ -44,21 +44,21 @@ os.chdir(test.workpath('')) class DummyEnvironment: dictionary = None # type: Dict[Any, Any] - def __init__(self, list_cpp_path): + def __init__(self, list_cpp_path) -> None: self.path = list_cpp_path self.fs = SCons.Node.FS.FS(test.workpath('')) self.dictionary = {} - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dictionary def __getitem__(self, key): return self.dictionary[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dictionary[key] = value - def __delitem__(self, key): + def __delitem__(self, key) -> None: del self.dictionary[key] def subst(self, arg, target=None, source=None, conv=None): @@ -85,7 +85,7 @@ class DummyEnvironment: class FortranScannerSubmodulesTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ Check that test_1.f90 and test_2.f90 which have interface specifications Don't generate targets for those modules listed in the interface section diff --git a/SCons/Tool/GettextCommon.py b/SCons/Tool/GettextCommon.py index 058b997..ba9ce31 100644 --- a/SCons/Tool/GettextCommon.py +++ b/SCons/Tool/GettextCommon.py @@ -82,8 +82,8 @@ class _POTargetFactory: default for all produced nodes. """ - def __init__(self, env, nodefault=True, alias=None, precious=True - , noclean=True): + def __init__(self, env, nodefault: bool=True, alias=None, precious: bool=True + , noclean: bool=True) -> None: """ Object constructor. **Arguments** @@ -104,7 +104,7 @@ class _POTargetFactory: self.noclean = noclean self.nodefault = nodefault - def _create_node(self, name, factory, directory=None, create=1): + def _create_node(self, name, factory, directory=None, create: int=1): """ Create node, and set it up to factory settings. """ node = factory(name, directory, create) node.set_noclean(self.noclean) @@ -115,11 +115,11 @@ class _POTargetFactory: self.env.AlwaysBuild(self.env.Alias(self.alias, node)) return node - def Entry(self, name, directory=None, create=1): + def Entry(self, name, directory=None, create: int=1): """ Create `SCons.Node.FS.Entry` """ return self._create_node(name, self.env.fs.Entry, directory, create) - def File(self, name, directory=None, create=1): + def File(self, name, directory=None, create: int=1): """ Create `SCons.Node.FS.File` """ return self._create_node(name, self.env.fs.File, directory, create) @@ -191,7 +191,7 @@ class _POFileBuilder(BuilderBase): # and execute iterativelly (recursion) self._execute(None, source[i]). # After that it calls emitter (which is quite too late). The emitter is # also called in each iteration, what makes things yet worse. - def __init__(self, env, **kw): + def __init__(self, env, **kw) -> None: if 'suffix' not in kw: kw['suffix'] = '$POSUFFIX' if 'src_suffix' not in kw: @@ -300,7 +300,7 @@ class RPaths: # seems be enough for our purposes (don't need TARGET variable and # SCons.Defaults.Variable_Caller stuff). - def __init__(self, env): + def __init__(self, env) -> None: """ Initialize `RPaths` callable object. **Arguments**: diff --git a/SCons/Tool/JavaCommon.py b/SCons/Tool/JavaCommon.py index adec1d3..96000d0 100644 --- a/SCons/Tool/JavaCommon.py +++ b/SCons/Tool/JavaCommon.py @@ -100,7 +100,7 @@ if java_parsing: """The initial state for parsing a Java file for classes, interfaces, and anonymous inner classes.""" - def __init__(self, version=default_java_version): + def __init__(self, version=default_java_version) -> None: if version not in ( '1.1', '1.2', @@ -136,7 +136,7 @@ if java_parsing: self.anonStacksStack = [[0]] self.package = None - def trace(self): + def trace(self) -> None: pass def __getClassState(self): @@ -175,10 +175,10 @@ if java_parsing: def _getAnonStack(self): return self.anonStacksStack[-1] - def openBracket(self): + def openBracket(self) -> None: self.brackets = self.brackets + 1 - def closeBracket(self): + def closeBracket(self) -> None: self.brackets = self.brackets - 1 if len(self.stackBrackets) and \ self.brackets == self.stackBrackets[-1]: @@ -223,7 +223,7 @@ if java_parsing: return self.__getSkipState() return self - def addAnonClass(self): + def addAnonClass(self) -> None: """Add an anonymous inner class""" if self.version in ('1.1', '1.2', '1.3', '1.4'): clazz = self.listClasses[0] @@ -257,7 +257,7 @@ if java_parsing: self.nextAnon = self.nextAnon + 1 self._getAnonStack().append(0) - def setPackage(self, package): + def setPackage(self, package) -> None: self.package = package @@ -267,7 +267,7 @@ if java_parsing: within the confines of a scope. """ - def __init__(self, old_state): + def __init__(self, old_state) -> None: self.outer_state = old_state.outer_state self.old_state = old_state self.brackets = 0 @@ -296,10 +296,10 @@ if java_parsing: self.skipState = ret return ret - def openBracket(self): + def openBracket(self) -> None: self.brackets = self.brackets + 1 - def closeBracket(self): + def closeBracket(self) -> None: self.brackets = self.brackets - 1 def parseToken(self, token): @@ -332,7 +332,7 @@ if java_parsing: class AnonClassState: """A state that looks for anonymous inner classes.""" - def __init__(self, old_state): + def __init__(self, old_state) -> None: # outer_state is always an instance of OuterState self.outer_state = old_state.outer_state self.old_state = old_state @@ -373,7 +373,7 @@ if java_parsing: """A state that will skip a specified number of tokens before reverting to the previous state.""" - def __init__(self, tokens_to_skip, old_state): + def __init__(self, tokens_to_skip, old_state) -> None: self.tokens_to_skip = tokens_to_skip self.old_state = old_state @@ -387,7 +387,7 @@ if java_parsing: class ClassState: """A state we go into when we hit a class or interface keyword.""" - def __init__(self, outer_state): + def __init__(self, outer_state) -> None: # outer_state is always an instance of OuterState self.outer_state = outer_state @@ -419,7 +419,7 @@ if java_parsing: """A state that will ignore all tokens until it gets to a specified token.""" - def __init__(self, ignore_until, old_state): + def __init__(self, ignore_until, old_state) -> None: self.ignore_until = ignore_until self.old_state = old_state @@ -433,7 +433,7 @@ if java_parsing: """The state we enter when we encounter the package keyword. We assume the next token will be the package name.""" - def __init__(self, outer_state): + def __init__(self, outer_state) -> None: # outer_state is always an instance of OuterState self.outer_state = outer_state diff --git a/SCons/Tool/JavaCommonTests.py b/SCons/Tool/JavaCommonTests.py index 75e75ef..fa462b6 100644 --- a/SCons/Tool/JavaCommonTests.py +++ b/SCons/Tool/JavaCommonTests.py @@ -34,14 +34,14 @@ import TestSCons # the parser to spit out trace messages of the tokens it sees and the # attendant transitions. -def trace(token, newstate): +def trace(token, newstate) -> None: from SCons.Debug import Trace statename = newstate.__class__.__name__ Trace('token = %s, state = %s\n' % (repr(token), statename)) class parse_javaTestCase(unittest.TestCase): - def test_bare_bones(self): + def test_bare_bones(self) -> None: """Test a bare-bones class""" input = """\ @@ -65,7 +65,7 @@ public class Foo assert classes == ['Foo'], classes - def test_file_parser(self): + def test_file_parser(self) -> None: """Test the file parser""" input = """\ package com.sub.bar; @@ -90,7 +90,7 @@ public class Foo assert classes == ['Foo'], classes - def test_dollar_sign(self): + def test_dollar_sign(self) -> None: """Test class names with $ in them""" input = """\ @@ -104,7 +104,7 @@ public class BadDep { - def test_inner_classes(self): + def test_inner_classes(self) -> None: """Test parsing various forms of inner classes""" input = """\ @@ -227,7 +227,7 @@ class Private { - def test_comments(self): + def test_comments(self) -> None: """Test a class with comments""" input = """\ @@ -272,7 +272,7 @@ public class Example1 extends UnicastRemoteObject implements Hello { assert classes == ['Example1'], classes - def test_arrays(self): + def test_arrays(self) -> None: """Test arrays of class instances""" input = """\ @@ -292,7 +292,7 @@ public class Test { - def test_backslash(self): + def test_backslash(self) -> None: """Test backslash handling""" input = """\ @@ -310,7 +310,7 @@ public class MyTabs assert classes == ['MyTabs$MyInternal', 'MyTabs'], classes - def test_enum(self): + def test_enum(self) -> None: """Test the Java 1.5 enum keyword""" input = """\ @@ -323,7 +323,7 @@ public enum a {} assert classes == ['a'], classes - def test_anon_classes(self): + def test_anon_classes(self) -> None: """Test anonymous classes""" input = """\ @@ -347,7 +347,7 @@ public abstract class TestClass assert classes == ['TestClass$1', 'TestClass$2', 'TestClass'], classes - def test_closing_bracket(self): + def test_closing_bracket(self) -> None: """Test finding a closing bracket instead of an anonymous class""" input = """\ @@ -365,7 +365,7 @@ class Foo { } assert classes == ['TestSCons', 'Foo'], classes - def test_dot_class_attributes(self): + def test_dot_class_attributes(self) -> None: """Test handling ".class" attributes""" input = """\ @@ -398,7 +398,7 @@ public class A { assert pkg_dir is None, pkg_dir assert classes == ['A$B', 'A'], classes - def test_anonymous_classes_with_parentheses(self): + def test_anonymous_classes_with_parentheses(self) -> None: """Test finding anonymous classes marked by parentheses""" input = """\ @@ -432,7 +432,7 @@ public class Foo { - def test_nested_anonymous_inner_classes(self): + def test_nested_anonymous_inner_classes(self) -> None: """Test finding nested anonymous inner classes""" input = """\ @@ -481,7 +481,7 @@ public class NestedExample expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ] assert expect == classes, (expect, classes) - def test_lambda_after_new(self): + def test_lambda_after_new(self) -> None: """Test lamdas after new""" input = """\ @@ -518,7 +518,7 @@ public class LamdaExample expect = [ 'LamdaExample' ] assert expect == classes, (expect, classes) - def test_private_inner_class_instantiation(self): + def test_private_inner_class_instantiation(self) -> None: """Test anonymous inner class generated by private instantiation""" input = """\ @@ -551,7 +551,7 @@ class test pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') assert expect == classes, (expect, classes) - def test_floating_point_numbers(self): + def test_floating_point_numbers(self) -> None: """Test floating-point numbers in the input stream""" input = """ // Broken.java @@ -592,7 +592,7 @@ class Broken assert expect == classes, (expect, classes) - def test_genercis(self): + def test_genercis(self) -> None: """Test that generics don't interfere with detecting anonymous classes""" input = """\ @@ -624,7 +624,7 @@ public class Foo assert expect == classes, (expect, classes) - def test_in_function_class_declaration(self): + def test_in_function_class_declaration(self) -> None: """ Test that implementing a class in a function call doesn't confuse SCons. """ @@ -667,7 +667,7 @@ public class AnonDemo { pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8') assert expect == classes, (expect, classes) - def test_jdk_globs(self): + def test_jdk_globs(self) -> None: """ Verify that the java path globs work with specific examples. :return: diff --git a/SCons/Tool/MSCommon/MSVC/ConfigTests.py b/SCons/Tool/MSCommon/MSVC/ConfigTests.py index 89db6cd..cbd811e 100644 --- a/SCons/Tool/MSCommon/MSVC/ConfigTests.py +++ b/SCons/Tool/MSCommon/MSVC/ConfigTests.py @@ -44,7 +44,7 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: vc._VCVER = cls._VCVER class Config: @@ -58,13 +58,13 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_VERSION_INTERNAL = cls.MSVC_VERSION_INTERNAL class ConfigTests(unittest.TestCase): - def test_vcver(self): + def test_vcver(self) -> None: # all vc._VCVER in Config.MSVC_VERSION_SUFFIX _VCVER = Patch.vc._VCVER.enable_copy() _VCVER.append('99.9') @@ -72,7 +72,7 @@ class ConfigTests(unittest.TestCase): Config.verify() Patch.vc._VCVER.restore() - def test_msvc_version_internal(self): + def test_msvc_version_internal(self) -> None: # all vc._VCVER numstr in Config.MSVC_VERSION_INTERNAL MSVC_VERSION_INTERNAL = Patch.Config.MSVC_VERSION_INTERNAL.enable_copy() del MSVC_VERSION_INTERNAL['14.3'] @@ -80,7 +80,7 @@ class ConfigTests(unittest.TestCase): Config.verify() Patch.Config.MSVC_VERSION_INTERNAL.restore() - def test_verify(self): + def test_verify(self) -> None: Config.verify() diff --git a/SCons/Tool/MSCommon/MSVC/Dispatcher.py b/SCons/Tool/MSCommon/MSVC/Dispatcher.py index 42b5287..31233a9 100644 --- a/SCons/Tool/MSCommon/MSVC/Dispatcher.py +++ b/SCons/Tool/MSCommon/MSVC/Dispatcher.py @@ -53,16 +53,16 @@ from ..common import ( _refs = [] -def register_modulename(modname): +def register_modulename(modname) -> None: module = sys.modules[modname] _refs.append(module) -def register_class(ref): +def register_class(ref) -> None: _refs.append(ref) -def reset(): +def reset() -> None: debug('') for ref in _refs: for method in ['reset', '_reset']: @@ -73,7 +73,7 @@ def reset(): func() -def verify(): +def verify() -> None: debug('') for ref in _refs: for method in ['verify', '_verify']: diff --git a/SCons/Tool/MSCommon/MSVC/DispatcherTests.py b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py index d6af8d4..61ea3f1 100644 --- a/SCons/Tool/MSCommon/MSVC/DispatcherTests.py +++ b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py @@ -46,37 +46,37 @@ verify = None class StaticMethods: @staticmethod - def _reset(): + def _reset() -> None: Data.reset_count += 1 @staticmethod - def reset(): + def reset() -> None: Data.reset_count += 1 @staticmethod - def _verify(): + def _verify() -> None: Data.verify_count += 1 @staticmethod - def verify(): + def verify() -> None: Data.verify_count += 1 class ClassMethods: @classmethod - def _reset(cls): + def _reset(cls) -> None: Data.reset_count += 1 @classmethod - def reset(cls): + def reset(cls) -> None: Data.reset_count += 1 @classmethod - def _verify(cls): + def _verify(cls) -> None: Data.verify_count += 1 @classmethod - def verify(cls): + def verify(cls) -> None: Data.verify_count += 1 @@ -94,22 +94,22 @@ MSVC.Dispatcher.register_class(NotCallable) class DispatcherTests(unittest.TestCase): - def test_dispatcher_reset(self): + def test_dispatcher_reset(self) -> None: MSVC.Dispatcher.reset() self.assertTrue(Data.reset_count == 4, "MSVC.Dispatcher.reset() count failed") Data.reset_count = 0 - def test_dispatcher_verify(self): + def test_dispatcher_verify(self) -> None: MSVC.Dispatcher.verify() self.assertTrue(Data.verify_count == 4, "MSVC.Dispatcher.verify() count failed") Data.verify_count = 0 - def test_msvc_reset(self): + def test_msvc_reset(self) -> None: MSVC._reset() self.assertTrue(Data.reset_count == 4, "MSVC._reset() count failed") Data.reset_count = 0 - def test_msvc_verify(self): + def test_msvc_verify(self) -> None: MSVC._verify() self.assertTrue(Data.verify_count == 4, "MSVC._verify() count failed") Data.verify_count = 0 diff --git a/SCons/Tool/MSCommon/MSVC/PolicyTests.py b/SCons/Tool/MSCommon/MSVC/PolicyTests.py index 013fd47..a312d11 100644 --- a/SCons/Tool/MSCommon/MSVC/PolicyTests.py +++ b/SCons/Tool/MSCommon/MSVC/PolicyTests.py @@ -43,22 +43,22 @@ from SCons.Tool.MSCommon.MSVC.Warnings import ( class PolicyTests(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.warnstack = [] - def push_warning_as_exception(self, warning_class): + def push_warning_as_exception(self, warning_class) -> None: SCons.Warnings.enableWarningClass(warning_class) prev_state = SCons.Warnings.warningAsException() self.warnstack.append((warning_class, prev_state)) - def pop_warning_as_exception(self): + def pop_warning_as_exception(self) -> None: warning_class, prev_state = self.warnstack.pop() SCons.Warnings.warningAsException(prev_state) SCons.Warnings.suppressWarningClass(warning_class) # msvc_set_notfound_policy, msvc_get_notfound_policy, and MSVC_NOTFOUND_POLICY - def test_notfound_func_valid_symbols(self): + def test_notfound_func_valid_symbols(self) -> None: def_policy = Policy.msvc_get_notfound_policy() last_policy = def_policy for notfound_def in Policy.MSVC_NOTFOUND_DEFINITION_LIST: @@ -75,21 +75,21 @@ class PolicyTests(unittest.TestCase): last_policy = cur_get_policy Policy.msvc_set_notfound_policy(def_policy) - def test_notfound_func_invalid_symbol(self): + def test_notfound_func_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_set_notfound_policy('Undefined') - def test_notfound_handler_invalid_symbol(self): + def test_notfound_handler_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': 'Undefined'}, '') - def test_notfound_handler_ignore(self): + def test_notfound_handler_ignore(self) -> None: def_policy = Policy.msvc_set_notfound_policy('Ignore') Policy.msvc_notfound_handler(None, '') Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': None}, '') Policy.msvc_set_notfound_policy(def_policy) - def test_notfound_handler_warning(self): + def test_notfound_handler_warning(self) -> None: # treat warning as exception for testing self.push_warning_as_exception(SCons.Warnings.VisualCMissingWarning) def_policy = Policy.msvc_set_notfound_policy('Warning') @@ -101,7 +101,7 @@ class PolicyTests(unittest.TestCase): Policy.msvc_set_notfound_policy(def_policy) self.pop_warning_as_exception() - def test_notfound_handler_error(self): + def test_notfound_handler_error(self) -> None: def_policy = Policy.msvc_set_notfound_policy('Error') with self.assertRaises(MSVCVersionNotFound): Policy.msvc_notfound_handler(None, '') @@ -112,7 +112,7 @@ class PolicyTests(unittest.TestCase): # msvc_set_scripterror_policy, msvc_get_scripterror_policy, and MSVC_SCRIPTERROR_POLICY - def test_scripterror_func_valid_symbols(self): + def test_scripterror_func_valid_symbols(self) -> None: def_policy = Policy.msvc_get_scripterror_policy() last_policy = def_policy for scripterror_def in Policy.MSVC_SCRIPTERROR_DEFINITION_LIST: @@ -129,21 +129,21 @@ class PolicyTests(unittest.TestCase): last_policy = cur_get_policy Policy.msvc_set_scripterror_policy(def_policy) - def test_scripterror_func_invalid_symbol(self): + def test_scripterror_func_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_set_scripterror_policy('Undefined') - def test_scripterror_handler_invalid_symbol(self): + def test_scripterror_handler_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': 'Undefined'}, '') - def test_scripterror_handler_ignore(self): + def test_scripterror_handler_ignore(self) -> None: def_policy = Policy.msvc_set_scripterror_policy('Ignore') Policy.msvc_scripterror_handler(None, '') Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': None}, '') Policy.msvc_set_scripterror_policy(def_policy) - def test_scripterror_handler_warning(self): + def test_scripterror_handler_warning(self) -> None: # treat warning as exception for testing self.push_warning_as_exception(MSVCScriptExecutionWarning) def_policy = Policy.msvc_set_scripterror_policy('Warning') @@ -155,7 +155,7 @@ class PolicyTests(unittest.TestCase): Policy.msvc_set_scripterror_policy(def_policy) self.pop_warning_as_exception() - def test_scripterror_handler_error(self): + def test_scripterror_handler_error(self) -> None: def_policy = Policy.msvc_set_scripterror_policy('Error') with self.assertRaises(MSVCScriptExecutionError): Policy.msvc_scripterror_handler(None, '') diff --git a/SCons/Tool/MSCommon/MSVC/Registry.py b/SCons/Tool/MSCommon/MSVC/Registry.py index 9519e15..eee20cc 100644 --- a/SCons/Tool/MSCommon/MSVC/Registry.py +++ b/SCons/Tool/MSCommon/MSVC/Registry.py @@ -46,7 +46,7 @@ Dispatcher.register_modulename(__name__) # A null-terminated string that contains unexpanded references to environment variables. REG_EXPAND_SZ = 2 -def read_value(hkey, subkey_valname, expand=True): +def read_value(hkey, subkey_valname, expand: bool=True): try: rval_t = RegGetValue(hkey, subkey_valname) except OSError: @@ -58,7 +58,7 @@ def read_value(hkey, subkey_valname, expand=True): debug('hkey=%s, subkey=%s, rval=%s', repr(hkey), repr(subkey_valname), repr(rval)) return rval -def registry_query_path(key, val, suffix, expand=True): +def registry_query_path(key, val, suffix, expand: bool=True): extval = val + '\\' + suffix if suffix else val qpath = read_value(key, extval, expand=expand) if qpath and os.path.exists(qpath): @@ -74,7 +74,7 @@ REG_SOFTWARE_MICROSOFT = [ (HKEY_CURRENT_USER, r'Software\Microsoft'), ] -def microsoft_query_paths(suffix, usrval=None, expand=True): +def microsoft_query_paths(suffix, usrval=None, expand: bool=True): paths = [] records = [] for key, val in REG_SOFTWARE_MICROSOFT: @@ -87,7 +87,7 @@ def microsoft_query_paths(suffix, usrval=None, expand=True): records.append((qpath, key, val, extval, usrval)) return records -def microsoft_query_keys(suffix, usrval=None, expand=True): +def microsoft_query_keys(suffix, usrval=None, expand: bool=True): records = [] for key, val in REG_SOFTWARE_MICROSOFT: extval = val + '\\' + suffix if suffix else val diff --git a/SCons/Tool/MSCommon/MSVC/RegistryTests.py b/SCons/Tool/MSCommon/MSVC/RegistryTests.py index aff3b3f..9c9ef89 100644 --- a/SCons/Tool/MSCommon/MSVC/RegistryTests.py +++ b/SCons/Tool/MSCommon/MSVC/RegistryTests.py @@ -37,7 +37,7 @@ class RegistryTests(unittest.TestCase): _sdk_versions = None @classmethod - def setUpClass(cls): + def setUpClass(cls) -> None: cls._sdk_versions = [] sdk_seen = set() for vs_def in Config.VISUALSTUDIO_DEFINITION_LIST: @@ -49,24 +49,24 @@ class RegistryTests(unittest.TestCase): sdk_seen.add(sdk_version) cls._sdk_versions.append(sdk_version) - def setUp(self): + def setUp(self) -> None: self.sdk_versions = self.__class__._sdk_versions - def test_sdk_query_paths(self): + def test_sdk_query_paths(self) -> None: for sdk_version in self.sdk_versions: _ = Registry.sdk_query_paths(sdk_version) - def test_vstudio_sxs_vc7(self): + def test_vstudio_sxs_vc7(self) -> None: suffix = Registry.vstudio_sxs_vc7('14.0') _ = Registry.microsoft_query_paths(suffix) - def test_microsoft_query_keys(self): + def test_microsoft_query_keys(self) -> None: val = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' for suffix in ['Temp', 'Tmp']: _ = Registry.registry_query_path(Registry.HKEY_LOCAL_MACHINE, val, suffix, expand=True) _ = Registry.registry_query_path(Registry.HKEY_LOCAL_MACHINE, val, suffix, expand=False) - def test_registry_query_path(self): + def test_registry_query_path(self) -> None: # need a better test for when VS2015 is no longer installed for component_reg in ('enterprise', 'professional', 'community'): suffix = Registry.devdiv_vs_servicing_component('14.0', component_reg) @@ -74,7 +74,7 @@ class RegistryTests(unittest.TestCase): if not rval: continue - def test_windows_kit_query_paths(self): + def test_windows_kit_query_paths(self) -> None: for sdk_version in self.sdk_versions: _ = Registry.windows_kit_query_paths(sdk_version) diff --git a/SCons/Tool/MSCommon/MSVC/ScriptArguments.py b/SCons/Tool/MSCommon/MSVC/ScriptArguments.py index 57dbf9d..a5ceb33 100644 --- a/SCons/Tool/MSCommon/MSVC/ScriptArguments.py +++ b/SCons/Tool/MSCommon/MSVC/ScriptArguments.py @@ -107,12 +107,12 @@ _MSVC_FORCE_DEFAULT_TOOLSET = False # Force default arguments _MSVC_FORCE_DEFAULT_ARGUMENTS = False -def _msvc_force_default_sdk(force=True): +def _msvc_force_default_sdk(force: bool=True) -> None: global _MSVC_FORCE_DEFAULT_SDK _MSVC_FORCE_DEFAULT_SDK = force debug('_MSVC_FORCE_DEFAULT_SDK=%s', repr(force)) -def _msvc_force_default_toolset(force=True): +def _msvc_force_default_toolset(force: bool=True) -> None: global _MSVC_FORCE_DEFAULT_TOOLSET _MSVC_FORCE_DEFAULT_TOOLSET = force debug('_MSVC_FORCE_DEFAULT_TOOLSET=%s', repr(force)) @@ -227,7 +227,7 @@ def _msvc_script_argument_uwp(env, msvc, arglist): return uwp_arg -def _user_script_argument_uwp(env, uwp, user_argstr): +def _user_script_argument_uwp(env, uwp, user_argstr) -> bool: matches = [m for m in re_vcvars_uwp.finditer(user_argstr)] if not matches: @@ -331,7 +331,7 @@ def _msvc_script_argument_sdk(env, msvc, toolset, platform_def, arglist): return sdk_version -def _msvc_script_default_sdk(env, msvc, platform_def, arglist, force_sdk=False): +def _msvc_script_default_sdk(env, msvc, platform_def, arglist, force_sdk: bool=False): if msvc.vs_def.vc_buildtools_def.vc_version_numeric < VS2015.vc_buildtools_def.vc_version_numeric: return None @@ -390,7 +390,7 @@ def _msvc_have140_toolset(): return _toolset_have140_cache -def _reset_have140_cache(): +def _reset_have140_cache() -> None: global _toolset_have140_cache debug('reset: cache') _toolset_have140_cache = None @@ -520,7 +520,7 @@ def _msvc_read_toolset_default(msvc, vc_dir): _toolset_version_cache = {} _toolset_default_cache = {} -def _reset_toolset_cache(): +def _reset_toolset_cache() -> None: global _toolset_version_cache global _toolset_default_cache debug('reset: toolset cache') @@ -686,7 +686,7 @@ def _msvc_script_argument_toolset(env, msvc, vc_dir, arglist): return toolset_vcvars -def _msvc_script_default_toolset(env, msvc, vc_dir, arglist, force_toolset=False): +def _msvc_script_default_toolset(env, msvc, vc_dir, arglist, force_toolset: bool=False): if msvc.vs_def.vc_buildtools_def.vc_version_numeric < VS2017.vc_buildtools_def.vc_version_numeric: return None @@ -853,7 +853,7 @@ def _msvc_script_argument_user(env, msvc, arglist): return script_args -def _msvc_process_construction_variables(env): +def _msvc_process_construction_variables(env) -> bool: for cache_variable in [ _MSVC_FORCE_DEFAULT_TOOLSET, @@ -982,7 +982,7 @@ def _msvc_toolset_internal(msvc_version, toolset_version, vc_dir): return toolset_vcvars -def _msvc_toolset_versions_internal(msvc_version, vc_dir, full=True, sxs=False): +def _msvc_toolset_versions_internal(msvc_version, vc_dir, full: bool=True, sxs: bool=False): msvc = _msvc_version(msvc_version) @@ -1020,12 +1020,12 @@ def _msvc_toolset_versions_spectre_internal(msvc_version, vc_dir): return spectre_toolset_versions -def reset(): +def reset() -> None: debug('') _reset_have140_cache() _reset_toolset_cache() -def verify(): +def verify() -> None: debug('') _verify_re_sdk_dispatch_map() diff --git a/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py b/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py index 4413256..670576b 100644 --- a/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py +++ b/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py @@ -147,13 +147,13 @@ class Data: ) @classmethod - def msvc_sdk_version_list_components(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_version_list_components(cls, msvc_version, msvc_uwp_app: bool=False): comps_dict = cls.SDK_VERSIONS_COMPS_DICT.get(msvc_version, {}) comps_list = comps_dict.get(msvc_uwp_app, []) return comps_list @classmethod - def msvc_sdk_version(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_version(cls, msvc_version, msvc_uwp_app: bool=False): comps_dict = cls.SDK_VERSIONS_COMPS_DICT.get(msvc_version, {}) comps_list = comps_dict.get(msvc_uwp_app, []) if not comps_list: @@ -163,7 +163,7 @@ class Data: return sdk_version @classmethod - def msvc_sdk_notfound_version(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_notfound_version(cls, msvc_version, msvc_uwp_app: bool=False): notfound_dict = cls.SDK_VERSIONS_NOTFOUND_DICT.get(msvc_version, {}) notfound_list = notfound_dict.get(msvc_uwp_app, []) if not notfound_list: @@ -201,19 +201,19 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_SDK_VERSIONS = cls.MSVC_SDK_VERSIONS class ScriptArgumentsTests(unittest.TestCase): - def test_verify(self): + def test_verify(self) -> None: MSVC_SDK_VERSIONS = Patch.Config.MSVC_SDK_VERSIONS.enable_copy() MSVC_SDK_VERSIONS.add('99.0') with self.assertRaises(MSVCInternalError): ScriptArguments.verify() Patch.Config.MSVC_SDK_VERSIONS.restore() - def test_msvc_script_arguments_defaults(self): + def test_msvc_script_arguments_defaults(self) -> None: func = ScriptArguments.msvc_script_arguments env = Environment() # disable forcing sdk and toolset versions as arguments @@ -244,7 +244,7 @@ class ScriptArgumentsTests(unittest.TestCase): # restore forcing sdk and toolset versions as arguments ScriptArguments.msvc_force_default_arguments(force=force) - def test_msvc_toolset_versions_internal(self): + def test_msvc_toolset_versions_internal(self) -> None: func = ScriptArguments._msvc_toolset_versions_internal for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: for full in (True, False): @@ -267,7 +267,7 @@ class ScriptArgumentsTests(unittest.TestCase): func.__name__, repr(version_def.msvc_version), repr(vc_dir), repr(full), repr(sxs) )) - def test_msvc_toolset_internal(self): + def test_msvc_toolset_internal(self) -> None: if not Data.HAVE_MSVC: return func = ScriptArguments._msvc_toolset_internal @@ -278,7 +278,7 @@ class ScriptArgumentsTests(unittest.TestCase): for toolset_version in toolset_versions: _ = func(version_def.msvc_version, toolset_version, vc_dir) - def run_msvc_script_args_none(self): + def run_msvc_script_args_none(self) -> None: func = ScriptArguments.msvc_script_arguments for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: for kwargs in [ @@ -291,7 +291,7 @@ class ScriptArgumentsTests(unittest.TestCase): env = Environment(**kwargs) _ = func(env, version_def.msvc_version, vc_dir, '') - def run_msvc_script_args(self): + def run_msvc_script_args(self) -> None: func = ScriptArguments.msvc_script_arguments for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: if version_def.msvc_vernum >= 14.1: @@ -565,7 +565,7 @@ class ScriptArgumentsTests(unittest.TestCase): with self.assertRaises(MSVCArgumentError): _ = func(env, version_def.msvc_version, vc_dir, '') - def test_msvc_script_args_none(self): + def test_msvc_script_args_none(self) -> None: force = ScriptArguments.msvc_force_default_arguments(force=False) self.run_msvc_script_args_none() if Data.HAVE_MSVC: @@ -573,14 +573,14 @@ class ScriptArgumentsTests(unittest.TestCase): self.run_msvc_script_args_none() ScriptArguments.msvc_force_default_arguments(force=force) - def test_msvc_script_args(self): + def test_msvc_script_args(self) -> None: force = ScriptArguments.msvc_force_default_arguments(force=False) self.run_msvc_script_args() ScriptArguments.msvc_force_default_arguments(force=True) self.run_msvc_script_args() ScriptArguments.msvc_force_default_arguments(force=force) - def test_reset(self): + def test_reset(self) -> None: ScriptArguments.reset() self.assertTrue(ScriptArguments._toolset_have140_cache is None, "ScriptArguments._toolset_have140_cache was not reset") self.assertFalse(ScriptArguments._toolset_version_cache, "ScriptArguments._toolset_version_cache was not reset") diff --git a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py index e1c05bc..34e60ab 100644 --- a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py +++ b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py @@ -54,7 +54,7 @@ class _Data: need_init = True @classmethod - def reset(cls): + def reset(cls) -> None: debug('msvc default:init') cls.n_setup = 0 # number of calls to msvc_setup_env_once cls.default_ismsvc = False # is msvc the default compiler @@ -65,7 +65,7 @@ class _Data: cls.msvc_nodefault = False # is there a default version of msvc cls.need_init = True # reset initialization indicator -def _initialize(env, msvc_exists_func): +def _initialize(env, msvc_exists_func) -> None: if _Data.need_init: _Data.reset() _Data.need_init = False @@ -88,7 +88,7 @@ def register_tool(env, tool, msvc_exists_func): _Data.msvc_tools.add(tool) debug('msvc default:tool=%s, msvc_tools=%s', tool, _Data.msvc_tools) -def register_setup(env, msvc_exists_func): +def register_setup(env, msvc_exists_func) -> None: if _Data.need_init: _initialize(env, msvc_exists_func) _Data.n_setup += 1 @@ -106,7 +106,7 @@ def register_setup(env, msvc_exists_func): _Data.n_setup, _Data.msvc_installed, _Data.default_ismsvc ) -def set_nodefault(): +def set_nodefault() -> None: # default msvc version, msvc not installed _Data.msvc_nodefault = True debug('msvc default:msvc_nodefault=%s', _Data.msvc_nodefault) @@ -227,7 +227,7 @@ def register_iserror(env, tool, msvc_exists_func): # return tool list in order presented return tools_found_list -def reset(): +def reset() -> None: debug('') _Data.reset() diff --git a/SCons/Tool/MSCommon/MSVC/UtilTests.py b/SCons/Tool/MSCommon/MSVC/UtilTests.py index 5e14d50..36e08f5 100644 --- a/SCons/Tool/MSCommon/MSVC/UtilTests.py +++ b/SCons/Tool/MSCommon/MSVC/UtilTests.py @@ -39,7 +39,7 @@ class Data: class UtilTests(unittest.TestCase): - def test_listdir_dirs(self): + def test_listdir_dirs(self) -> None: func = Util.listdir_dirs for dirname, expect in [ (None, False), ('', False), ('doesnotexist.xyz.abc', False), @@ -50,7 +50,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(dirname), 'list is empty' if expect else 'list is not empty' )) - def test_process_path(self): + def test_process_path(self) -> None: func = Util.process_path for p, expect in [ (None, True), ('', True), @@ -61,7 +61,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(p), repr(rval) )) - def test_get_version_prefix(self): + def test_get_version_prefix(self) -> None: func = Util.get_version_prefix for version, expect in [ (None, ''), ('', ''), @@ -76,7 +76,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(version), repr(prefix), repr(expect) )) - def test_get_msvc_version_prefix(self): + def test_get_msvc_version_prefix(self) -> None: func = Util.get_msvc_version_prefix for version, expect in [ (None, ''), ('', ''), @@ -91,7 +91,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(version), repr(prefix), repr(expect) )) - def test_is_toolset_full(self): + def test_is_toolset_full(self) -> None: func = Util.is_toolset_full for toolset, expect in [ (None, False), ('', False), @@ -103,7 +103,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_is_toolset_140(self): + def test_is_toolset_140(self) -> None: func = Util.is_toolset_140 for toolset, expect in [ (None, False), ('', False), @@ -115,7 +115,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_is_toolset_sxs(self): + def test_is_toolset_sxs(self) -> None: func = Util.is_toolset_sxs for toolset, expect in [ (None, False), ('', False), @@ -127,7 +127,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_msvc_version_components(self): + def test_msvc_version_components(self) -> None: func = Util.msvc_version_components for vcver, expect in [ (None, False), ('', False), ('ABC', False), ('14', False), ('14.1.', False), ('14.16', False), @@ -145,7 +145,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(vcver) )) - def test_msvc_extended_version_components(self): + def test_msvc_extended_version_components(self) -> None: func = Util.msvc_extended_version_components # normal code paths for vcver, expect in [ @@ -184,7 +184,7 @@ class UtilTests(unittest.TestCase): )) Util.re_extended_version = save_re - def test_msvc_sdk_version_components(self): + def test_msvc_sdk_version_components(self) -> None: func = Util.msvc_sdk_version_components for vcver, expect in [ (None, False), ('', False), ('ABC', False), ('14', False), ('14.1.', False), ('14.16', False), diff --git a/SCons/Tool/MSCommon/MSVC/WinSDK.py b/SCons/Tool/MSCommon/MSVC/WinSDK.py index 6d18d07..a5a48c4 100644 --- a/SCons/Tool/MSCommon/MSVC/WinSDK.py +++ b/SCons/Tool/MSCommon/MSVC/WinSDK.py @@ -154,7 +154,7 @@ def _sdk_81_layout(version): _sdk_map_cache = {} _sdk_cache = {} -def _reset_sdk_cache(): +def _reset_sdk_cache() -> None: global _sdk_map_cache global _sdk_cache debug('') @@ -220,7 +220,7 @@ def _sdk_map(version_list): _sdk_cache[key] = sdk_map return sdk_map -def get_msvc_platform(is_uwp=False): +def get_msvc_platform(is_uwp: bool=False): platform_def = _UWP if is_uwp else _DESKTOP return platform_def @@ -230,7 +230,7 @@ def get_sdk_version_list(vs_def, platform_def): sdk_list = sdk_map.get(platform_def.vc_platform, []) return sdk_list -def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app=False): +def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app: bool=False): debug('msvc_version=%s, msvc_uwp_app=%s', repr(msvc_version), repr(msvc_uwp_app)) sdk_versions = [] @@ -254,11 +254,11 @@ def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app=False): return sdk_versions -def reset(): +def reset() -> None: debug('') _reset_sdk_cache() -def verify(): +def verify() -> None: debug('') _verify_sdk_dispatch_map() diff --git a/SCons/Tool/MSCommon/MSVC/WinSDKTests.py b/SCons/Tool/MSCommon/MSVC/WinSDKTests.py index 2a40e9a..10e68f3 100644 --- a/SCons/Tool/MSCommon/MSVC/WinSDKTests.py +++ b/SCons/Tool/MSCommon/MSVC/WinSDKTests.py @@ -47,7 +47,7 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_SDK_VERSIONS = cls.MSVC_SDK_VERSIONS class Registry: @@ -69,54 +69,54 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Registry.sdk_query_paths = cls.sdk_query_paths class WinSDKTests(unittest.TestCase): @classmethod - def setUpClass(cls): + def setUpClass(cls) -> None: Patch.Registry.sdk_query_paths.enable_duplicate() @classmethod - def tearDownClass(cls): + def tearDownClass(cls) -> None: Patch.Registry.sdk_query_paths.restore() - def test_verify(self): + def test_verify(self) -> None: MSVC_SDK_VERSIONS = Patch.Config.MSVC_SDK_VERSIONS.enable_copy() MSVC_SDK_VERSIONS.add('99.0') with self.assertRaises(MSVCInternalError): WinSDK.verify() Patch.Config.MSVC_SDK_VERSIONS.restore() - def _run_reset(self): + def _run_reset(self) -> None: WinSDK.reset() self.assertFalse(WinSDK._sdk_map_cache, "WinSDK._sdk_map_cache was not reset") self.assertFalse(WinSDK._sdk_cache, "WinSDK._sdk_cache was not reset") - def _run_get_msvc_sdk_version_list(self): + def _run_get_msvc_sdk_version_list(self) -> None: for vcver in Config.MSVC_VERSION_SUFFIX.keys(): for msvc_uwp_app in (True, False): _ = WinSDK.get_msvc_sdk_version_list(vcver, msvc_uwp_app=msvc_uwp_app) - def _run_version_list_sdk_map(self): + def _run_version_list_sdk_map(self) -> None: for vcver in Config.MSVC_VERSION_SUFFIX.keys(): vs_def = Config.MSVC_VERSION_SUFFIX.get(vcver) if not vs_def.vc_sdk_versions: continue _ = WinSDK._version_list_sdk_map(vs_def.vc_sdk_versions) - def test_version_list_sdk_map(self): + def test_version_list_sdk_map(self) -> None: self._run_version_list_sdk_map() self._run_version_list_sdk_map() self.assertTrue(WinSDK._sdk_map_cache, "WinSDK._sdk_map_cache is empty") - def test_get_msvc_sdk_version_list(self): + def test_get_msvc_sdk_version_list(self) -> None: self._run_get_msvc_sdk_version_list() self._run_get_msvc_sdk_version_list() self.assertTrue(WinSDK._sdk_cache, "WinSDK._sdk_cache is empty") - def test_get_msvc_sdk_version_list_empty(self): + def test_get_msvc_sdk_version_list_empty(self) -> None: func = WinSDK.get_msvc_sdk_version_list for vcver in [None, '', '99', '99.9']: sdk_versions = func(vcver) @@ -124,7 +124,7 @@ class WinSDKTests(unittest.TestCase): func.__name__, repr(vcver) )) - def test_reset(self): + def test_reset(self) -> None: self._run_reset() if __name__ == "__main__": diff --git a/SCons/Tool/MSCommon/MSVC/__init__.py b/SCons/Tool/MSCommon/MSVC/__init__.py index 849c82d..766894d 100644 --- a/SCons/Tool/MSCommon/MSVC/__init__.py +++ b/SCons/Tool/MSCommon/MSVC/__init__.py @@ -47,9 +47,9 @@ from . import ScriptArguments # noqa: F401 from . import Dispatcher as _Dispatcher -def _reset(): +def _reset() -> None: _Dispatcher.reset() -def _verify(): +def _verify() -> None: _Dispatcher.verify() diff --git a/SCons/Tool/MSCommon/arch.py b/SCons/Tool/MSCommon/arch.py index 6648bb6..e526873 100644 --- a/SCons/Tool/MSCommon/arch.py +++ b/SCons/Tool/MSCommon/arch.py @@ -30,7 +30,7 @@ class ArchDefinition: """ A class for defining architecture-specific settings and logic. """ - def __init__(self, arch, synonyms=[]): + def __init__(self, arch, synonyms=[]) -> None: self.arch = arch self.synonyms = synonyms diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py index ad4c827..185ccdf 100644 --- a/SCons/Tool/MSCommon/common.py +++ b/SCons/Tool/MSCommon/common.py @@ -68,7 +68,7 @@ if LOGFILE: class _Debug_Filter(logging.Filter): # custom filter for module relative filename - def filter(self, record): + def filter(self, record) -> bool: relfilename = get_relative_filename(record.pathname, modulelist) relfilename = relfilename.replace('\\', '/') record.relfilename = relfilename @@ -138,7 +138,7 @@ def read_script_env_cache(): return envcache -def write_script_env_cache(cache): +def write_script_env_cache(cache) -> None: """ write out cache of msvc env vars if requested """ if CONFIG_CACHE: try: @@ -209,7 +209,7 @@ def has_reg(value): # Functions for fetching environment variable settings from batch files. -def normalize_env(env, keys, force=False): +def normalize_env(env, keys, force: bool=False): """Given a dictionary representing a shell environment, add the variables from os.environ needed for the processing of .bat files; the keys are controlled by the keys argument. @@ -369,7 +369,7 @@ def parse_output(output, keep=KEEPLIST): for i in keep: rdk[i] = re.compile('%s=(.*)' % i, re.I) - def add_env(rmatch, key, dkeep=dkeep): + def add_env(rmatch, key, dkeep=dkeep) -> None: path_list = rmatch.group(1).split(os.pathsep) for path in path_list: # Do not add empty paths (when a var ends with ;) diff --git a/SCons/Tool/MSCommon/sdk.py b/SCons/Tool/MSCommon/sdk.py index aa94f4d..fd0892c 100644 --- a/SCons/Tool/MSCommon/sdk.py +++ b/SCons/Tool/MSCommon/sdk.py @@ -59,7 +59,7 @@ class SDKDefinition: """ An abstract base class for trying to find installed SDK directories. """ - def __init__(self, version, **kw): + def __init__(self, version, **kw) -> None: self.version = version self.__dict__.update(kw) @@ -130,7 +130,7 @@ class WindowsSDK(SDKDefinition): A subclass for trying to find installed Windows SDK directories. """ HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder' - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.hkey_data = self.version @@ -139,7 +139,7 @@ class PlatformSDK(SDKDefinition): A subclass for trying to find installed Platform SDK directories. """ HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir' - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.hkey_data = self.uuid @@ -306,7 +306,7 @@ def get_installed_sdks(): SDKEnvironmentUpdates = {} -def set_sdk_by_directory(env, sdk_dir): +def set_sdk_by_directory(env, sdk_dir) -> None: global SDKEnvironmentUpdates debug('set_sdk_by_directory: Using dir:%s', sdk_dir) try: diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 7871940..1dc6b8d 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -455,7 +455,7 @@ def get_native_host_platform(): return _native_host_platform -def get_host_target(env, msvc_version, all_host_targets=False): +def get_host_target(env, msvc_version, all_host_targets: bool=False): vernum = float(get_msvc_version_numeric(msvc_version)) @@ -823,7 +823,7 @@ __INSTALLED_VCS_RUN = None _VC_TOOLS_VERSION_FILE_PATH = ['Auxiliary', 'Build', 'Microsoft.VCToolsVersion.default.txt'] _VC_TOOLS_VERSION_FILE = os.sep.join(_VC_TOOLS_VERSION_FILE_PATH) -def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version): +def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version) -> bool: """Return status of finding a cl.exe to use. Locates cl in the vc_dir depending on TARGET_ARCH, HOST_ARCH and the @@ -963,7 +963,7 @@ def get_installed_vcs(env=None): __INSTALLED_VCS_RUN = installed_versions return __INSTALLED_VCS_RUN -def reset_installed_vcs(): +def reset_installed_vcs() -> None: """Make it try again to find VC. This is just for the tests.""" global __INSTALLED_VCS_RUN __INSTALLED_VCS_RUN = None @@ -1099,7 +1099,7 @@ def get_default_version(env): return msvc_version -def msvc_setup_env_once(env, tool=None): +def msvc_setup_env_once(env, tool=None) -> None: try: has_run = env["MSVC_SETUP_RUN"] except KeyError: @@ -1340,7 +1340,7 @@ def msvc_setup_env_tool(env=None, version=None, tool=None): rval = True return rval -def msvc_sdk_versions(version=None, msvc_uwp_app=False): +def msvc_sdk_versions(version=None, msvc_uwp_app: bool=False): debug('version=%s, msvc_uwp_app=%s', repr(version), repr(msvc_uwp_app)) rval = [] @@ -1360,7 +1360,7 @@ def msvc_sdk_versions(version=None, msvc_uwp_app=False): rval = MSVC.WinSDK.get_msvc_sdk_version_list(version, msvc_uwp_app) return rval -def msvc_toolset_versions(msvc_version=None, full=True, sxs=False): +def msvc_toolset_versions(msvc_version=None, full: bool=True, sxs: bool=False): debug('msvc_version=%s, full=%s, sxs=%s', repr(msvc_version), repr(full), repr(sxs)) env = None @@ -1410,7 +1410,7 @@ def msvc_toolset_versions_spectre(msvc_version=None): rval = MSVC.ScriptArguments._msvc_toolset_versions_spectre_internal(msvc_version, vc_dir) return rval -def msvc_query_version_toolset(version=None, prefer_newest=True): +def msvc_query_version_toolset(version=None, prefer_newest: bool=True): """ Returns an msvc version and a toolset version given a version specification. diff --git a/SCons/Tool/MSCommon/vcTests.py b/SCons/Tool/MSCommon/vcTests.py index 3e37def..c4cf2af 100644 --- a/SCons/Tool/MSCommon/vcTests.py +++ b/SCons/Tool/MSCommon/vcTests.py @@ -47,12 +47,12 @@ MS_TOOLS_VERSION = '1.1.1' class VswhereTestCase(unittest.TestCase): @staticmethod - def _createVSWhere(path): + def _createVSWhere(path) -> None: os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, 'w') as f: f.write("Created:%s" % f) - def testDefaults(self): + def testDefaults(self) -> None: """ Verify that msvc_find_vswhere() find's files in the specified paths """ @@ -75,7 +75,7 @@ class VswhereTestCase(unittest.TestCase): class MSVcTestCase(unittest.TestCase): @staticmethod - def _createDummyCl(path, add_bin=True): + def _createDummyCl(path, add_bin: bool=True) -> None: """ Creates a dummy cl.exe in the correct directory. It will create all missing parent directories as well @@ -101,7 +101,7 @@ class MSVcTestCase(unittest.TestCase): ct.write('created') - def runTest(self): + def runTest(self) -> None: """ Check that all proper HOST_PLATFORM and TARGET_PLATFORM are handled. Verify that improper HOST_PLATFORM and/or TARGET_PLATFORM are properly handled. @@ -307,13 +307,13 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: MSCommon.vc.msvc_default_version = cls.msvc_default_version class MsvcSdkVersionsTests(unittest.TestCase): """Test msvc_sdk_versions""" - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) for msvc_uwp_app in (True, False): @@ -323,14 +323,14 @@ class MsvcSdkVersionsTests(unittest.TestCase): else: self.assertFalse(sdk_list, "SDK list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) for msvc_uwp_app in (True, False): @@ -340,7 +340,7 @@ class MsvcSdkVersionsTests(unittest.TestCase): else: self.assertFalse(sdk_list, "SDK list is not empty for msvc version {}".format(repr(symbol))) - def test_valid_vcver_toolsets(self): + def test_valid_vcver_toolsets(self) -> None: for symbol in MSCommon.vc._VCVER: toolset_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=True, sxs=True) if toolset_list is None: @@ -354,13 +354,13 @@ class MsvcSdkVersionsTests(unittest.TestCase): ) self.assertTrue(sdk_list, "SDK list is empty for msvc toolset version {}".format(repr(toolset))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['6.0Exp', '14.3Exp', '99', '14.1Bug']: for msvc_uwp_app in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_sdk_versions(version=symbol, msvc_uwp_app=msvc_uwp_app) - def test_invalid_vcver_toolsets(self): + def test_invalid_vcver_toolsets(self) -> None: for symbol in ['14.31.123456', '14.31.1.1']: for msvc_uwp_app in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): @@ -369,7 +369,7 @@ class MsvcSdkVersionsTests(unittest.TestCase): class MsvcToolsetVersionsTests(unittest.TestCase): """Test msvc_toolset_versions""" - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) toolset_none_list = MSCommon.vc.msvc_toolset_versions(msvc_version=None, full=False, sxs=False) @@ -386,14 +386,14 @@ class MsvcToolsetVersionsTests(unittest.TestCase): self.assertFalse(toolset_all_list, "Toolset all list is not empty for msvc version {}".format(repr(None))) self.assertFalse(toolset_none_list, "Toolset none list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) toolset_none_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=False, sxs=False) @@ -410,14 +410,14 @@ class MsvcToolsetVersionsTests(unittest.TestCase): self.assertFalse(toolset_all_list, "Toolset all list is not empty for msvc version {}".format(repr(symbol))) self.assertFalse(toolset_none_list, "Toolset none list is not empty for msvc version {}".format(repr(symbol))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol) class MsvcToolsetVersionsSpectreTests(unittest.TestCase): - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) spectre_toolset_list = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=None) @@ -427,14 +427,14 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): else: self.assertFalse(spectre_toolset_list, "Toolset spectre list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) spectre_toolset_list = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=symbol) @@ -444,7 +444,7 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): else: self.assertFalse(spectre_toolset_list, "Toolset spectre list is not empty for msvc version {}".format(repr(symbol))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=symbol) @@ -452,7 +452,7 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): class MsvcQueryVersionToolsetTests(unittest.TestCase): """Test msvc_query_toolset_version""" - def run_valid_default_msvc(self, have_msvc): + def run_valid_default_msvc(self, have_msvc) -> None: for prefer_newest in (True, False): msvc_version, msvc_toolset_version = MSCommon.vc.msvc_query_version_toolset( version=None, prefer_newest=prefer_newest @@ -468,14 +468,14 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(None) )) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc(have_msvc=False) Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc(have_msvc=Data.HAVE_MSVC) - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) for prefer_newest in (True, False): @@ -489,7 +489,7 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(symbol) )) - def test_valid_vcver_toolsets(self): + def test_valid_vcver_toolsets(self) -> None: for symbol in MSCommon.vc._VCVER: toolset_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=True, sxs=True) if toolset_list is None: @@ -508,7 +508,7 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(toolset) )) - def test_msvc_query_version_toolset_notfound(self): + def test_msvc_query_version_toolset_notfound(self) -> None: toolset_notfound_dict = Data.msvc_toolset_notfound_dict() for toolset_notfound_list in toolset_notfound_dict.values(): for toolset in toolset_notfound_list[:1]: @@ -516,13 +516,13 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): with self.assertRaises(MSCommon.vc.MSVCToolsetVersionNotFound): _ = MSCommon.vc.msvc_query_version_toolset(version=toolset, prefer_newest=prefer_newest) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: for prefer_newest in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_query_version_toolset(version=symbol, prefer_newest=prefer_newest) - def test_invalid_vcver_toolsets(self): + def test_invalid_vcver_toolsets(self) -> None: for symbol in ['14.16.00000Exp', '14.00.00001', '14.31.123456', '14.31.1.1']: for prefer_newest in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): diff --git a/SCons/Tool/MSCommon/vs.py b/SCons/Tool/MSCommon/vs.py index 08c3cf5..00ccaef 100644 --- a/SCons/Tool/MSCommon/vs.py +++ b/SCons/Tool/MSCommon/vs.py @@ -46,7 +46,7 @@ class VisualStudio: An abstract base class for trying to find installed versions of Visual Studio. """ - def __init__(self, version, **kw): + def __init__(self, version, **kw) -> None: self.version = version kw['vc_version'] = kw.get('vc_version', version) kw['sdk_version'] = kw.get('sdk_version', version) @@ -148,7 +148,7 @@ class VisualStudio: self._cache['supported_arch'] = self.supported_arch return self.supported_arch - def reset(self): + def reset(self) -> None: self._cache = {} # The list of supported Visual Studio versions we know how to detect. @@ -439,7 +439,7 @@ def get_installed_visual_studios(env=None): InstalledVSMap[vs.version] = vs return InstalledVSList -def reset_installed_visual_studios(): +def reset_installed_visual_studios() -> None: global InstalledVSList global InstalledVSMap InstalledVSList = None @@ -564,12 +564,12 @@ def get_default_arch(env): return arch -def merge_default_version(env): +def merge_default_version(env) -> None: version = get_default_version(env) arch = get_default_arch(env) # TODO: refers to versions and arch which aren't defined; called nowhere. Drop? -def msvs_setup_env(env): +def msvs_setup_env(env) -> None: msvs = get_vs_by_version(version) if msvs is None: return diff --git a/SCons/Tool/PharLapCommon.py b/SCons/Tool/PharLapCommon.py index 9ffafa9..e1907ab 100644 --- a/SCons/Tool/PharLapCommon.py +++ b/SCons/Tool/PharLapCommon.py @@ -86,7 +86,7 @@ def getPharLapVersion(): # Default return for Phar Lap 9.1 return 910 -def addPharLapPaths(env): +def addPharLapPaths(env) -> None: """This function adds the path to the Phar Lap binaries, includes, and libraries, if they are not already there.""" ph_path = getPharLapPath() diff --git a/SCons/Tool/ToolTests.py b/SCons/Tool/ToolTests.py index 59d093b..e87a972 100644 --- a/SCons/Tool/ToolTests.py +++ b/SCons/Tool/ToolTests.py @@ -31,19 +31,19 @@ import SCons.Tool class DummyEnvironment: - def __init__(self): + def __init__(self) -> None: self.dict = {} def Detect(self, progs): if not SCons.Util.is_List(progs): progs = [ progs ] return progs[0] - def Append(self, **kw): + def Append(self, **kw) -> None: self.dict.update(kw) def __getitem__(self, key): return self.dict[key] - def __setitem__(self, key, val): + def __setitem__(self, key, val) -> None: self.dict[key] = val - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict def subst(self, string, *args, **kwargs): return string @@ -60,13 +60,13 @@ class DummyEnvironment: if self.PHONY_PATH in paths: return os.path.join(self.PHONY_PATH, key_program) return None - def AppendENVPath(self, pathvar, path): + def AppendENVPath(self, pathvar, path) -> None: # signature matches how called from find_program_path() self['ENV'][pathvar] = self['ENV'][pathvar] + os.pathsep + path class ToolTestCase(unittest.TestCase): - def test_Tool(self): + def test_Tool(self) -> None: """Test the Tool() function""" env = DummyEnvironment() @@ -96,7 +96,7 @@ class ToolTestCase(unittest.TestCase): assert exc_caught, "did not catch expected UserError" - def test_pathfind(self): + def test_pathfind(self) -> None: """Test that find_program_path() alters PATH only if add_path is true""" env = DummyEnvironment() diff --git a/SCons/Tool/__init__.py b/SCons/Tool/__init__.py index 33c1d33..3681235 100644 --- a/SCons/Tool/__init__.py +++ b/SCons/Tool/__init__.py @@ -105,7 +105,7 @@ TOOL_ALIASES = { class Tool: - def __init__(self, name, toolpath=None, **kwargs): + def __init__(self, name, toolpath=None, **kwargs) -> None: if toolpath is None: toolpath = [] @@ -241,7 +241,7 @@ class Tool: msg = "No tool named '{self.name}': {e}" raise SCons.Errors.SConsEnvironmentError(msg) - def __call__(self, env, *args, **kw): + def __call__(self, env, *args, **kw) -> None: if self.init_kw is not None: # Merge call kws into init kws; # but don't bash self.init_kw. @@ -264,7 +264,7 @@ class Tool: self.generate(env, *args, **kw) - def __str__(self): + def __str__(self) -> str: return self.name @@ -324,7 +324,7 @@ def createStaticLibBuilder(env): return static_lib -def createSharedLibBuilder(env, shlib_suffix='$_SHLIBSUFFIX'): +def createSharedLibBuilder(env, shlib_suffix: str='$_SHLIBSUFFIX'): """This is a utility function that creates the SharedLibrary Builder in an Environment if it is not there already. @@ -354,7 +354,7 @@ def createSharedLibBuilder(env, shlib_suffix='$_SHLIBSUFFIX'): return shared_lib -def createLoadableModuleBuilder(env, loadable_module_suffix='$_LDMODULESUFFIX'): +def createLoadableModuleBuilder(env, loadable_module_suffix: str='$_LDMODULESUFFIX'): """This is a utility function that creates the LoadableModule Builder in an Environment if it is not there already. @@ -557,7 +557,7 @@ class ToolInitializerMethod: environment in place of this particular instance. """ - def __init__(self, name, initializer): + def __init__(self, name, initializer) -> None: """ Note: we store the tool name as __name__ so it can be used by the class that attaches this to a construction environment. @@ -608,7 +608,7 @@ class ToolInitializer: that we want to use to delay Tool searches until necessary. """ - def __init__(self, env, tools, names): + def __init__(self, env, tools, names) -> None: if not SCons.Util.is_List(tools): tools = [tools] if not SCons.Util.is_List(names): @@ -622,7 +622,7 @@ class ToolInitializer: self.methods[name] = method env.AddMethod(method) - def remove_methods(self, env): + def remove_methods(self, env) -> None: """ Removes the methods that were added by the tool initialization so we no longer copy and re-bind them when the construction @@ -631,7 +631,7 @@ class ToolInitializer: for method in self.methods.values(): env.RemoveMethod(method) - def apply_tools(self, env): + def apply_tools(self, env) -> None: """ Searches the list of associated Tool modules for one that exists, and applies that to the construction environment. @@ -649,7 +649,7 @@ class ToolInitializer: # the ToolInitializer class. -def Initializers(env): +def Initializers(env) -> None: ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs', '_InternalInstallVersionedLib']) def Install(self, *args, **kw): @@ -824,7 +824,7 @@ def tool_list(platform, env): return [x for x in tools if x] -def find_program_path(env, key_program, default_paths=None, add_path=False) -> Optional[str]: +def find_program_path(env, key_program, default_paths=None, add_path: bool=False) -> Optional[str]: """ Find the location of a tool using various means. diff --git a/SCons/Tool/aixcc.py b/SCons/Tool/aixcc.py index 09365b1..ccde0a8 100644 --- a/SCons/Tool/aixcc.py +++ b/SCons/Tool/aixcc.py @@ -44,7 +44,7 @@ def get_xlc(env): xlc = env.get('CC', 'xlc') return SCons.Platform.aix.get_xlc(env, xlc, packages) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for xlc / Visual Age suite to an Environment.""" path, _cc, version = get_xlc(env) diff --git a/SCons/Tool/aixcxx.py b/SCons/Tool/aixcxx.py index 58d9ecc..7b47899 100644 --- a/SCons/Tool/aixcxx.py +++ b/SCons/Tool/aixcxx.py @@ -47,7 +47,7 @@ def get_xlc(env): xlc = env.get('CXX', 'xlC') return SCons.Platform.aix.get_xlc(env, xlc, packages) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for xlC / Visual Age suite to an Environment.""" path, _cxx, version = get_xlc(env) diff --git a/SCons/Tool/aixf77.py b/SCons/Tool/aixf77.py index 4cef908..33511ee 100644 --- a/SCons/Tool/aixf77.py +++ b/SCons/Tool/aixf77.py @@ -50,7 +50,7 @@ def get_xlf77(env): #return SCons.Platform.aix.get_xlc(env, xlf77, xlf77_r, packages) return (None, xlf77, xlf77_r, None) -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for the Visual Age FORTRAN compiler to an Environment. diff --git a/SCons/Tool/aixlink.py b/SCons/Tool/aixlink.py index dc0de2a..03fc3b0 100644 --- a/SCons/Tool/aixlink.py +++ b/SCons/Tool/aixlink.py @@ -48,7 +48,7 @@ def smart_linkflags(source, target, env, for_signature): return '' -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age linker to an Environment. diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py index b81d2b3..3dc744d 100644 --- a/SCons/Tool/applelink.py +++ b/SCons/Tool/applelink.py @@ -79,7 +79,7 @@ def _applelib_check_valid_version(version_string): return True, "" -def _applelib_currentVersionFromSoVersion(source, target, env, for_signature): +def _applelib_currentVersionFromSoVersion(source, target, env, for_signature) -> str: """ A generator function to create the -Wl,-current_version flag if needed. If env['APPLELINK_NO_CURRENT_VERSION'] contains a true value no flag will be generated @@ -110,7 +110,7 @@ def _applelib_currentVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-current_version,%s" % version_string -def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): +def _applelib_compatVersionFromSoVersion(source, target, env, for_signature) -> str: """ A generator function to create the -Wl,-compatibility_version flag if needed. If env['APPLELINK_NO_COMPATIBILITY_VERSION'] contains a true value no flag will be generated @@ -141,7 +141,7 @@ def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-compatibility_version,%s" % version_string -def _applelib_soname(target, source, env, for_signature): +def _applelib_soname(target, source, env, for_signature) -> str: """ Override default _soname() function from SCons.Tools.linkCommon.SharedLibrary. Apple's file naming for versioned shared libraries puts the version string before @@ -160,7 +160,7 @@ def _applelib_soname(target, source, env, for_signature): return "$SHLIBPREFIX$_get_shlib_stem$_SHLIBSOVERSION${SHLIBSUFFIX}" -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for applelink to an Environment.""" link.generate(env) diff --git a/SCons/Tool/ar.py b/SCons/Tool/ar.py index 2cd15c8..e370927 100644 --- a/SCons/Tool/ar.py +++ b/SCons/Tool/ar.py @@ -38,7 +38,7 @@ import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/asm.py b/SCons/Tool/asm.py index c748251..2c9a915 100644 --- a/SCons/Tool/asm.py +++ b/SCons/Tool/asm.py @@ -46,7 +46,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for as to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/bcc32.py b/SCons/Tool/bcc32.py index 55f871b..5bd14f6 100644 --- a/SCons/Tool/bcc32.py +++ b/SCons/Tool/bcc32.py @@ -44,7 +44,7 @@ def findIt(program, env): env.PrependENVPath('PATH', dir) return borwin -def generate(env): +def generate(env) -> None: findIt('bcc32', env) """Add Builders and construction variables for bcc to an Environment.""" diff --git a/SCons/Tool/cc.py b/SCons/Tool/cc.py index 590ec5f..e9cbe53 100644 --- a/SCons/Tool/cc.py +++ b/SCons/Tool/cc.py @@ -40,7 +40,7 @@ CSuffixes = ['.c', '.m'] if not SCons.Util.case_sensitive_suffixes('.c', '.C'): CSuffixes.append('.C') -def add_common_cc_variables(env): +def add_common_cc_variables(env) -> None: """ Add underlying common "C compiler" variables that are used by multiple tools (specifically, c++). @@ -64,7 +64,7 @@ def add_common_cc_variables(env): compilers = ['cc'] -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for C compilers to an Environment. """ diff --git a/SCons/Tool/clang.py b/SCons/Tool/clang.py index 518b09e..1cef0ad 100644 --- a/SCons/Tool/clang.py +++ b/SCons/Tool/clang.py @@ -44,7 +44,7 @@ from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for clang to an Environment.""" SCons.Tool.cc.generate(env) diff --git a/SCons/Tool/clangxx.py b/SCons/Tool/clangxx.py index 07d8378..5f8202c 100644 --- a/SCons/Tool/clangxx.py +++ b/SCons/Tool/clangxx.py @@ -44,7 +44,7 @@ from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for clang++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/compilation_db.py b/SCons/Tool/compilation_db.py index a4954c1..14c6ef5 100644 --- a/SCons/Tool/compilation_db.py +++ b/SCons/Tool/compilation_db.py @@ -51,12 +51,12 @@ __COMPILATION_DB_ENTRIES = [] # We make no effort to avoid rebuilding the entries. Someday, perhaps we could and even # integrate with the cache, but there doesn't seem to be much call for it. class __CompilationDbNode(SCons.Node.Python.Value): - def __init__(self, value): + def __init__(self, value) -> None: SCons.Node.Python.Value.__init__(self, value) self.Decider(changed_since_last_build_node) -def changed_since_last_build_node(child, target, prev_ni, node): +def changed_since_last_build_node(child, target, prev_ni, node) -> bool: """ Dummy decider to force always building""" return True @@ -111,7 +111,7 @@ class CompDBTEMPFILE(TempFileMunge): return self.cmd -def compilation_db_entry_action(target, source, env, **kw): +def compilation_db_entry_action(target, source, env, **kw) -> None: """ Create a dictionary with evaluated command line, target, source and store that info as an attribute on the target @@ -140,7 +140,7 @@ def compilation_db_entry_action(target, source, env, **kw): target[0].write(entry) -def write_compilation_db(target, source, env): +def write_compilation_db(target, source, env) -> None: entries = [] use_abspath = env['COMPILATIONDB_USE_ABSPATH'] in [True, 1, 'True', 'true'] @@ -197,7 +197,7 @@ def compilation_db_emitter(target, source, env): return target, source -def generate(env, **kwargs): +def generate(env, **kwargs) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) env["COMPILATIONDB_COMSTR"] = kwargs.get( @@ -261,5 +261,5 @@ def generate(env, **kwargs): env['COMPILATIONDB_PATH_FILTER'] = '' -def exists(env): +def exists(env) -> bool: return True diff --git a/SCons/Tool/cvf.py b/SCons/Tool/cvf.py index 47e733e..0dc74ad 100644 --- a/SCons/Tool/cvf.py +++ b/SCons/Tool/cvf.py @@ -33,7 +33,7 @@ from . import fortran compilers = ['f90'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for compaq visual fortran to an Environment.""" fortran.generate(env) diff --git a/SCons/Tool/cxx.py b/SCons/Tool/cxx.py index 128cdc4..bf4bcce 100644 --- a/SCons/Tool/cxx.py +++ b/SCons/Tool/cxx.py @@ -39,7 +39,7 @@ CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm'] if SCons.Util.case_sensitive_suffixes('.c', '.C'): CXXSuffixes.append('.C') -def iscplusplus(source): +def iscplusplus(source) -> int: if not source: # Source might be None for unusual cases like SConf. return 0 @@ -50,7 +50,7 @@ def iscplusplus(source): return 1 return 0 -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age C++ compilers to an Environment. diff --git a/SCons/Tool/cyglink.py b/SCons/Tool/cyglink.py index bb5cd10..0d1eb51 100644 --- a/SCons/Tool/cyglink.py +++ b/SCons/Tool/cyglink.py @@ -134,7 +134,7 @@ def cyglink_ldmodule_version(target, source, env, for_signature): return "." + version -def _implib_pre_flags(target, source, env, for_signature): +def _implib_pre_flags(target, source, env, for_signature) -> str: no_import_lib = env.get('no_import_lib', False) if no_import_lib in ['1', 'True', 'true', True]: return '' @@ -142,7 +142,7 @@ def _implib_pre_flags(target, source, env, for_signature): return '-Wl,--out-implib=${TARGETS[1]} -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' -def _implib_post_flags(target, source, env, for_signature): +def _implib_post_flags(target, source, env, for_signature) -> str: no_import_lib = env.get('no_import_lib', False) if no_import_lib in ['1', 'True', 'true', True]: return '' @@ -150,7 +150,7 @@ def _implib_post_flags(target, source, env, for_signature): return '-Wl,--no-whole-archive' -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for cyglink to an Environment.""" gnulink.generate(env) diff --git a/SCons/Tool/default.py b/SCons/Tool/default.py index a36e9ec..4b386e2 100644 --- a/SCons/Tool/default.py +++ b/SCons/Tool/default.py @@ -35,12 +35,12 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Tool -def generate(env): +def generate(env) -> None: """Add default tools.""" for t in SCons.Tool.tool_list(env['PLATFORM'], env): SCons.Tool.Tool(t)(env) -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/dmd.py b/SCons/Tool/dmd.py index 67ed43e..7b2a249 100644 --- a/SCons/Tool/dmd.py +++ b/SCons/Tool/dmd.py @@ -82,7 +82,7 @@ import SCons.Tool import SCons.Tool.DCommon as DCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/docbook/__init__.py b/SCons/Tool/docbook/__init__.py index 52e2911..53505eb 100644 --- a/SCons/Tool/docbook/__init__.py +++ b/SCons/Tool/docbook/__init__.py @@ -72,7 +72,7 @@ re_refname = re.compile(r"([^<]*)") lmxl_xslt_global_max_depth = 3600 if has_lxml and lmxl_xslt_global_max_depth: - def __lxml_xslt_set_global_max_depth(max_depth): + def __lxml_xslt_set_global_max_depth(max_depth) -> None: from lxml import etree etree.XSLT.set_global_max_depth(max_depth) __lxml_xslt_set_global_max_depth(lmxl_xslt_global_max_depth) @@ -93,7 +93,7 @@ def __extend_targets_sources(target, source): return target, source -def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path): +def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path) -> None: if kw.get('DOCBOOK_XSL','') == '': xsl_style = kw.get('xsl', env.subst(user_xsl_var)) if xsl_style == '': @@ -137,7 +137,7 @@ def __get_xml_text(root): txt += e.data return txt -def __create_output_dir(base_dir): +def __create_output_dir(base_dir) -> None: """ Ensure that the output directory base_dir exists. """ root, tail = os.path.split(base_dir) dir = None @@ -173,7 +173,7 @@ fop_com = {'fop' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -fo $SOURCE -pdf $TARGET', 'xep' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -valid -fo $SOURCE -pdf $TARGET', 'jw' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -f docbook -b pdf $SOURCE -o $TARGET'} -def __detect_cl_tool(env, chainkey, cdict, cpriority=None): +def __detect_cl_tool(env, chainkey, cdict, cpriority=None) -> None: """ Helper function, picks a command line tool from the list and initializes its environment variables. @@ -195,7 +195,7 @@ def __detect_cl_tool(env, chainkey, cdict, cpriority=None): env[chainkey + 'COM'] = cdict[cltool] break -def _detect(env): +def _detect(env) -> None: """ Detect all the command line tools that we might need for creating the requested output formats. @@ -420,7 +420,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): import zipfile import shutil - def build_open_container(target, source, env): + def build_open_container(target, source, env) -> None: """Generate the *.epub file from intermediate outputs Constructs the epub file according to the Open Container Format. This @@ -444,7 +444,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))), zipfile.ZIP_DEFLATED) - def add_resources(target, source, env): + def add_resources(target, source, env) -> None: """Add missing resources to the OEBPS directory Ensure all the resources in the manifest are present in the OEBPS directory. @@ -789,7 +789,7 @@ def DocbookXslt(env, target, source=None, *args, **kw): return result -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for docbook to an Environment.""" env.SetDefault( @@ -839,5 +839,5 @@ def generate(env): env.AddMethod(DocbookXslt, "DocbookXslt") -def exists(env): +def exists(env) -> int: return 1 diff --git a/SCons/Tool/dvi.py b/SCons/Tool/dvi.py index 4067b2a..a395d2b 100644 --- a/SCons/Tool/dvi.py +++ b/SCons/Tool/dvi.py @@ -34,7 +34,7 @@ import SCons.Tool DVIBuilder = None -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['DVI'] except KeyError: @@ -52,7 +52,7 @@ def generate(env): env['BUILDERS']['DVI'] = DVIBuilder -def exists(env): +def exists(env) -> int: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." return 1 diff --git a/SCons/Tool/dvipdf.py b/SCons/Tool/dvipdf.py index e062207..c08bf07 100644 --- a/SCons/Tool/dvipdf.py +++ b/SCons/Tool/dvipdf.py @@ -85,12 +85,12 @@ def PDFEmitter(target, source, env): used to generate the .dvi file we're using as input, and we only care about the .dvi file. """ - def strip_suffixes(n): + def strip_suffixes(n) -> bool: return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log'] source = [src for src in source if strip_suffixes(src)] return (target, source) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for dvipdf to an Environment.""" global PDFAction if PDFAction is None: diff --git a/SCons/Tool/dvips.py b/SCons/Tool/dvips.py index 198bda0..7cf717b 100644 --- a/SCons/Tool/dvips.py +++ b/SCons/Tool/dvips.py @@ -55,7 +55,7 @@ PSAction = None DVIPSAction = None PSBuilder = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for dvips to an Environment.""" global PSAction if PSAction is None: diff --git a/SCons/Tool/f03.py b/SCons/Tool/f03.py index 142c127..7c2f029 100644 --- a/SCons/Tool/f03.py +++ b/SCons/Tool/f03.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env compilers = ['f03'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f03_to_env(env) diff --git a/SCons/Tool/f08.py b/SCons/Tool/f08.py index eb367c5..30c2d72 100644 --- a/SCons/Tool/f08.py +++ b/SCons/Tool/f08.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env compilers = ['f08'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f08_to_env(env) diff --git a/SCons/Tool/f77.py b/SCons/Tool/f77.py index 5ff15ae..c065f6c 100644 --- a/SCons/Tool/f77.py +++ b/SCons/Tool/f77.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['f77'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f77_to_env(env) diff --git a/SCons/Tool/f90.py b/SCons/Tool/f90.py index cbf3947..b3dde59 100644 --- a/SCons/Tool/f90.py +++ b/SCons/Tool/f90.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env compilers = ['f90'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f90_to_env(env) diff --git a/SCons/Tool/f95.py b/SCons/Tool/f95.py index 4830ee0..b707a11 100644 --- a/SCons/Tool/f95.py +++ b/SCons/Tool/f95.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env compilers = ['f95'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f95_to_env(env) diff --git a/SCons/Tool/filesystem.py b/SCons/Tool/filesystem.py index 3b8ee4c..9a977b5 100644 --- a/SCons/Tool/filesystem.py +++ b/SCons/Tool/filesystem.py @@ -48,7 +48,7 @@ def copyto_emitter(target, source, env): return (n_target, source) -def copy_action_func(target, source, env): +def copy_action_func(target, source, env) -> int: assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(map(str, source))) for t, s in zip(target, source): @@ -62,7 +62,7 @@ def copy_action_str(target, source, env): copy_action = SCons.Action.Action( copy_action_func, copy_action_str ) -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['CopyTo'] env['BUILDERS']['CopyAs'] @@ -88,7 +88,7 @@ def generate(env): env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"' -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/fortran.py b/SCons/Tool/fortran.py index d21b930..4463085 100644 --- a/SCons/Tool/fortran.py +++ b/SCons/Tool/fortran.py @@ -33,7 +33,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env compilers = ['f95', 'f90', 'f77'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_fortran_to_env(env) diff --git a/SCons/Tool/g77.py b/SCons/Tool/g77.py index aea419a..8c69d85 100644 --- a/SCons/Tool/g77.py +++ b/SCons/Tool/g77.py @@ -35,7 +35,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['g77', 'f77'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g77 to an Environment.""" add_all_to_env(env) add_f77_to_env(env) diff --git a/SCons/Tool/gas.py b/SCons/Tool/gas.py index d01bd60..04c9a2e 100644 --- a/SCons/Tool/gas.py +++ b/SCons/Tool/gas.py @@ -40,7 +40,7 @@ except: assemblers = ['as', 'gas'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for as to an Environment.""" as_module.generate(env) diff --git a/SCons/Tool/gcc.py b/SCons/Tool/gcc.py index 1a25cb4..d564f9c 100644 --- a/SCons/Tool/gcc.py +++ b/SCons/Tool/gcc.py @@ -40,7 +40,7 @@ import SCons.Util compilers = ['gcc', 'cc'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gcc to an Environment.""" if 'CC' not in env: diff --git a/SCons/Tool/gdc.py b/SCons/Tool/gdc.py index 0728c6f..c77e27a 100644 --- a/SCons/Tool/gdc.py +++ b/SCons/Tool/gdc.py @@ -54,7 +54,7 @@ import SCons.Tool.DCommon as DCommon import SCons.Tool.linkCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index a1407b3..18c7c0e 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -40,7 +40,7 @@ from SCons.Tool.GettextCommon import ( _xgettext_exists, ) -def generate(env, **kw): +def generate(env, **kw) -> None: for t in tool_list(env['PLATFORM'], env): if sys.platform == 'win32': tool = SCons.Tool.find_program_path( diff --git a/SCons/Tool/gfortran.py b/SCons/Tool/gfortran.py index f9c0a45..cb55ad6 100644 --- a/SCons/Tool/gfortran.py +++ b/SCons/Tool/gfortran.py @@ -34,7 +34,7 @@ from SCons.Util import CLVar from . import fortran -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gfortran.""" fortran.generate(env) diff --git a/SCons/Tool/gnulink.py b/SCons/Tool/gnulink.py index e8b668f..159aa97 100644 --- a/SCons/Tool/gnulink.py +++ b/SCons/Tool/gnulink.py @@ -39,7 +39,7 @@ import SCons.Tool from . import link -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gnulink to an Environment.""" link.generate(env) diff --git a/SCons/Tool/gs.py b/SCons/Tool/gs.py index 25359a8..8955bfd 100644 --- a/SCons/Tool/gs.py +++ b/SCons/Tool/gs.py @@ -50,7 +50,7 @@ else: GhostscriptAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Ghostscript to an Environment.""" global GhostscriptAction diff --git a/SCons/Tool/gxx.py b/SCons/Tool/gxx.py index 1272997..e788381 100644 --- a/SCons/Tool/gxx.py +++ b/SCons/Tool/gxx.py @@ -41,7 +41,7 @@ from . import cxx compilers = ['g++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/hpcc.py b/SCons/Tool/hpcc.py index 51d2e38..f893686 100644 --- a/SCons/Tool/hpcc.py +++ b/SCons/Tool/hpcc.py @@ -36,7 +36,7 @@ import SCons.Util from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for aCC & cc to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/hpcxx.py b/SCons/Tool/hpcxx.py index 7113fa2..c02a06f 100644 --- a/SCons/Tool/hpcxx.py +++ b/SCons/Tool/hpcxx.py @@ -60,7 +60,7 @@ for dir in dirs: break -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g++ to an Environment.""" cplusplus.generate(env) diff --git a/SCons/Tool/hplink.py b/SCons/Tool/hplink.py index ba182f1..0d26fa4 100644 --- a/SCons/Tool/hplink.py +++ b/SCons/Tool/hplink.py @@ -51,7 +51,7 @@ for dir in dirs: ccLinker = linker break -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age linker to an Environment. diff --git a/SCons/Tool/icc.py b/SCons/Tool/icc.py index adf24e9..63c7fd0 100644 --- a/SCons/Tool/icc.py +++ b/SCons/Tool/icc.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for the OS/2 to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/ifl.py b/SCons/Tool/ifl.py index 5746950..dac8179 100644 --- a/SCons/Tool/ifl.py +++ b/SCons/Tool/ifl.py @@ -32,7 +32,7 @@ import SCons.Defaults from SCons.Scanner.Fortran import FortranScan from .FortranCommon import add_all_to_env -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ifl to an Environment.""" fscan = FortranScan("FORTRANPATH") SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) diff --git a/SCons/Tool/ifort.py b/SCons/Tool/ifort.py index bf39b7f..9210923 100644 --- a/SCons/Tool/ifort.py +++ b/SCons/Tool/ifort.py @@ -35,7 +35,7 @@ from SCons.Scanner.Fortran import FortranScan from .FortranCommon import add_all_to_env -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ifort to an Environment.""" # ifort supports Fortran 90 and Fortran 95 # Additionally, ifort recognizes more file extensions. diff --git a/SCons/Tool/ilink.py b/SCons/Tool/ilink.py index 4112825..6be62d3 100644 --- a/SCons/Tool/ilink.py +++ b/SCons/Tool/ilink.py @@ -33,7 +33,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ilink to an Environment.""" SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/ilink32.py b/SCons/Tool/ilink32.py index 1452fd5..1bdc6d0 100644 --- a/SCons/Tool/ilink32.py +++ b/SCons/Tool/ilink32.py @@ -33,7 +33,7 @@ import SCons.Tool import SCons.Tool.bcc32 import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Borland ilink to an Environment.""" SCons.Tool.createSharedLibBuilder(env) diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index d6870c3..54fc090 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -50,8 +50,8 @@ class CopytreeError(OSError): pass -def scons_copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False, dirs_exist_ok=False): +def scons_copytree(src, dst, symlinks: bool=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks: bool=False, dirs_exist_ok: bool=False): """Recursively copy a directory tree, SCons version. This is a modified copy of the Python 3.7 shutil.copytree function. @@ -225,7 +225,7 @@ def listShlibLinksToInstall(dest, source, env): install_links.append((install_link, install_linktgt)) return install_links -def installShlibLinks(dest, source, env): +def installShlibLinks(dest, source, env) -> None: """If we are installing a versioned shared library create the required links.""" Verbose = False symlinks = listShlibLinksToInstall(dest, source, env) @@ -337,7 +337,7 @@ class DESTDIR_factory: """ A node factory, where all files will be relative to the dir supplied in the constructor. """ - def __init__(self, env, dir): + def __init__(self, env, dir) -> None: self.env = env self.dir = env.arg2nodes( dir, env.fs.Dir )[0] @@ -429,7 +429,7 @@ def InstallVersionedBuilderWrapper(env, target=None, source=None, dir=None, **kw added = None -def generate(env): +def generate(env) -> None: from SCons.Script import AddOption, GetOption global added @@ -500,7 +500,7 @@ def generate(env): except KeyError: env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index ac6fa60..a7b4802 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -384,7 +384,7 @@ def get_intel_compiler_top(version, abi): return top -def generate(env, version=None, abi=None, topdir=None, verbose=0): +def generate(env, version=None, abi=None, topdir=None, verbose: int=0): r"""Add Builders and construction variables for Intel C/C++ compiler to an Environment. diff --git a/SCons/Tool/ipkg.py b/SCons/Tool/ipkg.py index 8e01dd2..b295c12 100644 --- a/SCons/Tool/ipkg.py +++ b/SCons/Tool/ipkg.py @@ -39,7 +39,7 @@ import os import SCons.Builder -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ipkg to an Environment.""" try: bld = env['BUILDERS']['Ipkg'] diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index ae44ff3..1967294 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -240,7 +240,7 @@ def generate(env) -> None: env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" env['JARSUFFIX'] = '.jar' -def exists(env): +def exists(env) -> bool: # As reported by Jan Nijtmans in issue #2730, the simple # return env.Detect('jar') # doesn't always work during initialization. For now, we diff --git a/SCons/Tool/javac.py b/SCons/Tool/javac.py index 1b33125..6353924 100644 --- a/SCons/Tool/javac.py +++ b/SCons/Tool/javac.py @@ -73,7 +73,7 @@ def emit_java_classes(target, source, env): elif isinstance(entry, SCons.Node.FS.Dir): result = OrderedDict() dirnode = entry.rdir() - def find_java_files(arg, dirpath, filenames): + def find_java_files(arg, dirpath, filenames) -> None: java_files = sorted([n for n in filenames if _my_normcase(n).endswith(js)]) mydir = dirnode.Dir(dirpath) @@ -141,7 +141,7 @@ class pathopt: Callable object for generating javac-style path options from a construction variable (e.g. -classpath, -sourcepath). """ - def __init__(self, opt, var, default=None): + def __init__(self, opt, var, default=None) -> None: self.opt = opt self.var = var self.default = default @@ -198,7 +198,7 @@ def Java(env, target, source, *args, **kw): return result -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for javac to an Environment.""" java_file = SCons.Tool.CreateJavaFileBuilder(env) java_class = SCons.Tool.CreateJavaClassFileBuilder(env) @@ -242,7 +242,7 @@ def generate(env): env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVAPROCESSORPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}" -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/javacTests.py b/SCons/Tool/javacTests.py index 08633d5..46f1af1 100644 --- a/SCons/Tool/javacTests.py +++ b/SCons/Tool/javacTests.py @@ -27,39 +27,39 @@ import unittest import SCons.Tool.javac class DummyNode: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val - def __str__(self): + def __str__(self) -> str: return str(self.val) class pathoptTestCase(unittest.TestCase): - def assert_pathopt(self, expect, path): + def assert_pathopt(self, expect, path) -> None: popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH') env = {'FOOPATH': path} actual = popt(None, None, env, None) self.assertEqual(expect, actual) - def assert_pathopt_default(self, expect, path, default): + def assert_pathopt_default(self, expect, path, default) -> None: popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH', default='DPATH') env = {'FOOPATH': path, 'DPATH': default} actual = popt(None, None, env, None) self.assertEqual(expect, actual) - def test_unset(self): + def test_unset(self) -> None: self.assert_pathopt([], None) self.assert_pathopt([], '') - def test_str(self): + def test_str(self) -> None: self.assert_pathopt(['-foopath', '/foo/bar'], '/foo/bar') - def test_list_str(self): + def test_list_str(self) -> None: self.assert_pathopt(['-foopath', '/foo%s/bar' % os.pathsep], ['/foo', '/bar']) - def test_uses_pathsep(self): + def test_uses_pathsep(self) -> None: save = os.pathsep try: os.pathsep = '!' @@ -68,27 +68,27 @@ class pathoptTestCase(unittest.TestCase): finally: os.pathsep = save - def test_node(self): + def test_node(self) -> None: self.assert_pathopt(['-foopath', '/foo'], DummyNode('/foo')) - def test_list_node(self): + def test_list_node(self) -> None: self.assert_pathopt(['-foopath', os.pathsep.join(['/foo','/bar'])], ['/foo', DummyNode('/bar')]) - def test_default_str(self): + def test_default_str(self) -> None: self.assert_pathopt_default( ['-foopath', os.pathsep.join(['/foo','/bar','/baz'])], ['/foo', '/bar'], '/baz') - def test_default_list(self): + def test_default_list(self) -> None: self.assert_pathopt_default( ['-foopath', os.pathsep.join(['/foo','/bar','/baz'])], ['/foo', '/bar'], ['/baz']) - def test_default_unset(self): + def test_default_unset(self) -> None: self.assert_pathopt_default( ['-foopath', '/foo'], '/foo', @@ -98,7 +98,7 @@ class pathoptTestCase(unittest.TestCase): '/foo', '') - def test_list_within_list(self): + def test_list_within_list(self) -> None: self.assert_pathopt(['-foopath', os.pathsep.join(['/foo','/bar'])], ['/foo', ['/bar']]) diff --git a/SCons/Tool/javah.py b/SCons/Tool/javah.py index c5a7564..4b68815 100644 --- a/SCons/Tool/javah.py +++ b/SCons/Tool/javah.py @@ -109,13 +109,13 @@ def JavaHOutFlagGenerator(target, source, env, for_signature): except AttributeError: return '-o ' + str(t) -def getJavaHClassPath(env,target, source, for_signature): +def getJavaHClassPath(env,target, source, for_signature) -> str: path = "${SOURCE.attributes.java_classdir}" if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']: path = SCons.Util.AppendPath(path, env['JAVACLASSPATH']) return "-classpath %s" % path -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for javah to an Environment.""" java_javah = SCons.Tool.CreateJavaHBuilder(env) java_javah.emitter = emit_java_headers diff --git a/SCons/Tool/latex.py b/SCons/Tool/latex.py index f30356b..ddbcdf9 100644 --- a/SCons/Tool/latex.py +++ b/SCons/Tool/latex.py @@ -50,7 +50,7 @@ def LaTeXAuxFunction(target = None, source= None, env=None): LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for LaTeX to an Environment.""" env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) diff --git a/SCons/Tool/ldc.py b/SCons/Tool/ldc.py index fa02bf8..7583853 100644 --- a/SCons/Tool/ldc.py +++ b/SCons/Tool/ldc.py @@ -58,7 +58,7 @@ import SCons.Tool import SCons.Tool.DCommon as DCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index 3f1a3ad..527f91c 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -95,7 +95,7 @@ def lexEmitter(target, source, env) -> tuple: return target, source -def get_lex_path(env, append_paths=False) -> Optional[str]: +def get_lex_path(env, append_paths: bool=False) -> Optional[str]: """ Returns the path to the lex tool, searching several possible names. diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py index 24d17a3..e879ae8 100644 --- a/SCons/Tool/link.py +++ b/SCons/Tool/link.py @@ -40,7 +40,7 @@ from SCons.Tool.linkCommon.LoadableModule import setup_loadable_module_logic from SCons.Tool.linkCommon.SharedLibrary import setup_shared_lib_logic -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gnulink to an Environment.""" createProgBuilder(env) diff --git a/SCons/Tool/linkCommon/LoadableModule.py b/SCons/Tool/linkCommon/LoadableModule.py index c8124a0..77a06ed 100644 --- a/SCons/Tool/linkCommon/LoadableModule.py +++ b/SCons/Tool/linkCommon/LoadableModule.py @@ -65,7 +65,7 @@ def _ldmodule_soversion(target, source, env, for_signature): return '' -def _ldmodule_soname(target, source, env, for_signature): +def _ldmodule_soname(target, source, env, for_signature) -> str: if 'SONAME' in env: return '$SONAME' else: @@ -82,7 +82,7 @@ def _LDMODULEVERSION(target, source, env, for_signature): else: return "" -def setup_loadable_module_logic(env): +def setup_loadable_module_logic(env) -> None: """ Just the logic for loadable modules diff --git a/SCons/Tool/linkCommon/SharedLibrary.py b/SCons/Tool/linkCommon/SharedLibrary.py index d18aa6b..30170f8 100644 --- a/SCons/Tool/linkCommon/SharedLibrary.py +++ b/SCons/Tool/linkCommon/SharedLibrary.py @@ -100,7 +100,7 @@ def _soversion(target, source, env, for_signature): return "" -def _soname(target, source, env, for_signature): +def _soname(target, source, env, for_signature) -> str: if "SONAME" in env: # Now verify that SOVERSION is not also set as that is not allowed if "SOVERSION" in env: @@ -177,7 +177,7 @@ def _get_shlib_dir(target, source, env, for_signature: bool) -> str: return "" -def setup_shared_lib_logic(env): +def setup_shared_lib_logic(env) -> None: """Initialize an environment for shared library building. Args: diff --git a/SCons/Tool/linkCommon/__init__.py b/SCons/Tool/linkCommon/__init__.py index 5461ad3..b8d7610 100644 --- a/SCons/Tool/linkCommon/__init__.py +++ b/SCons/Tool/linkCommon/__init__.py @@ -45,7 +45,7 @@ def StringizeLibSymlinks(symlinks): return symlinks -def EmitLibSymlinks(env, symlinks, libnode, **kw): +def EmitLibSymlinks(env, symlinks, libnode, **kw) -> None: """Used by emitters to handle (shared/versioned) library symlinks""" Verbose = False @@ -66,7 +66,7 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw): print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list])) -def CreateLibSymlinks(env, symlinks): +def CreateLibSymlinks(env, symlinks) -> int: """Physically creates symlinks. The symlinks argument must be a list in form [ (link, linktarget), ... ], where link and linktarget are SCons nodes. @@ -92,7 +92,7 @@ def CreateLibSymlinks(env, symlinks): return 0 -def LibSymlinksActionFunction(target, source, env): +def LibSymlinksActionFunction(target, source, env) -> int: for tgt in target: symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None) if symlinks: @@ -127,7 +127,7 @@ def _call_env_subst(env, string, *args, **kw): return env.subst(string, *args, **kw2) -def smart_link(source, target, env, for_signature): +def smart_link(source, target, env, for_signature) -> str: import SCons.Tool.cxx import SCons.Tool.FortranCommon diff --git a/SCons/Tool/linkCommon/linkCommmonTests.py b/SCons/Tool/linkCommon/linkCommmonTests.py index e55660d..5326da2 100644 --- a/SCons/Tool/linkCommon/linkCommmonTests.py +++ b/SCons/Tool/linkCommon/linkCommmonTests.py @@ -31,10 +31,10 @@ from SCons.Environment import Environment class SharedLibraryTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: pass - def test_shlib_symlink_emitter(self): + def test_shlib_symlink_emitter(self) -> None: """Test shlib_symlink_emitter() """ env = Environment(tools=['gnulink']) diff --git a/SCons/Tool/linkloc.py b/SCons/Tool/linkloc.py index 6ee5d61..6122d9b 100644 --- a/SCons/Tool/linkloc.py +++ b/SCons/Tool/linkloc.py @@ -61,7 +61,7 @@ def repl_linker_command(m): return m.group(1) + '#' + m.group(2) class LinklocGenerator: - def __init__(self, cmdline): + def __init__(self, cmdline) -> None: self.cmdline = cmdline def __call__(self, env, target, source, for_signature): @@ -75,7 +75,7 @@ class LinklocGenerator: else: return "${TEMPFILE('" + self.cmdline + "')}" -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createSharedLibBuilder(env) SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/m4.py b/SCons/Tool/m4.py index 8506784..341d93d 100644 --- a/SCons/Tool/m4.py +++ b/SCons/Tool/m4.py @@ -37,7 +37,7 @@ import SCons.Action import SCons.Builder import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for m4 to an Environment.""" M4Action = SCons.Action.Action('$M4COM', '$M4COMSTR') bld = SCons.Builder.Builder(action = M4Action, src_suffix = '.m4') diff --git a/SCons/Tool/masm.py b/SCons/Tool/masm.py index b9d88cd..f8fae20 100644 --- a/SCons/Tool/masm.py +++ b/SCons/Tool/masm.py @@ -44,7 +44,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for masm to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index c25ce69..0c640f5 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -73,7 +73,7 @@ midl_builder = SCons.Builder.Builder(action=midl_action, source_scanner=idl_scanner) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for midl to an Environment.""" env['MIDL'] = 'MIDL.EXE' diff --git a/SCons/Tool/mingw.py b/SCons/Tool/mingw.py index 8e7ac2d..07f15b7 100644 --- a/SCons/Tool/mingw.py +++ b/SCons/Tool/mingw.py @@ -142,7 +142,7 @@ def get_mingw_paths(): _mingw_all_paths = mingw_base_paths + find_version_specific_mingw_paths() return _mingw_all_paths -def generate(env): +def generate(env) -> None: # Check for reasoanble mingw default paths mingw_paths = get_mingw_paths() diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index a15c1dc..334e058 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -86,7 +86,7 @@ def _create_mo_file_builder(env, **kw): return _MOFileBuilder(**kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate `msgfmt` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index 9635f57..19aaccb 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -79,7 +79,7 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **kw): source = [domain] # NOTE: Suffix shall be appended automatically return env._POInitBuilder(target, source, **kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate the `msginit` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 69508eb..292e75d 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -77,7 +77,7 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): return env._POUpdateBuilder(target, source, **kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate the `msgmerge` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/mslib.py b/SCons/Tool/mslib.py index be4088b..6e15a80 100644 --- a/SCons/Tool/mslib.py +++ b/SCons/Tool/mslib.py @@ -45,7 +45,7 @@ from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once tool_name = 'mslib' -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for lib to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py index 2a90e17..1e5b71a 100644 --- a/SCons/Tool/mslink.py +++ b/SCons/Tool/mslink.py @@ -256,7 +256,7 @@ compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckA exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows", "$LINKCOMSTR")}', '$LINKCOMSTR') compositeLinkAction = exeLinkAction + embedManifestExeCheckAction -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createSharedLibBuilder(env, shlib_suffix='$SHLIBSUFFIX') SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/mssdk.py b/SCons/Tool/mssdk.py index b94f105..0151eff 100644 --- a/SCons/Tool/mssdk.py +++ b/SCons/Tool/mssdk.py @@ -36,7 +36,7 @@ selection method. from .MSCommon import mssdk_exists, \ mssdk_setup_env -def generate(env): +def generate(env) -> None: """Add construction variables for an MS SDK to an Environment.""" mssdk_setup_env(env) diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py index 191d2cc..33a67d0 100644 --- a/SCons/Tool/msvc.py +++ b/SCons/Tool/msvc.py @@ -60,7 +60,7 @@ def validate_vars(env): if not SCons.Util.is_String(env['PCHSTOP']): raise SCons.Errors.UserError("The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']) -def msvc_set_PCHPDBFLAGS(env): +def msvc_set_PCHPDBFLAGS(env) -> None: """ Set appropriate PCHPDBFLAGS for the MSVC version being used. """ @@ -229,7 +229,7 @@ ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR", -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for MSVC++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 86df1ef..51e2970 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -207,7 +207,7 @@ class _UserGenerator: usrdebg = None usrconf = None createfile = False - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: # DebugSettings should be a list of debug dictionary sorted in the same order # as the target list and variants if 'variant' not in env: @@ -249,12 +249,12 @@ class _UserGenerator: trg[key] = str(src[key]) self.configs[var].debug = trg - def UserHeader(self): + def UserHeader(self) -> None: encoding = self.env.subst('$MSVSENCODING') versionstr = self.versionstr self.usrfile.write(self.usrhead % locals()) - def UserProject(self): + def UserProject(self) -> None: pass def Build(self): @@ -317,14 +317,14 @@ V9DebugSettings = { class _GenerateV7User(_UserGenerator): """Generates a Project file for MSVS .NET""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: if self.version_num >= 9.0: self.usrhead = V9UserHeader self.usrconf = V9UserConfiguration self.usrdebg = V9DebugSettings super().__init__(dspfile, source, env) - def UserProject(self): + def UserProject(self) -> None: confkeys = sorted(self.configs.keys()) for kind in confkeys: variant = self.configs[kind].variant @@ -379,7 +379,7 @@ V10DebugSettings = { class _GenerateV10User(_UserGenerator): """Generates a Project'user file for MSVS 2010 or later""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: version_num, suite = msvs_parse_version(env['MSVS_VERSION']) if version_num >= 14.3: # Visual Studio 2022 is considered to be version 17. @@ -399,7 +399,7 @@ class _GenerateV10User(_UserGenerator): self.usrdebg = V10DebugSettings super().__init__(dspfile, source, env) - def UserProject(self): + def UserProject(self) -> None: confkeys = sorted(self.configs.keys()) for kind in confkeys: variant = self.configs[kind].variant @@ -422,7 +422,7 @@ class _DSPGenerator: 'resources', 'misc'] - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: self.dspfile = str(dspfile) try: get_abspath = dspfile.get_abspath @@ -585,7 +585,7 @@ class _DSPGenerator: for n in sourcenames: self.sources[n].sort(key=lambda a: a.lower()) - def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, cppdefines, cpppaths, cppflags, dspfile=dspfile, env=env): + def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, cppdefines, cpppaths, cppflags, dspfile=dspfile, env=env) -> None: config = Config() config.buildtarget = buildtarget config.outdir = outdir @@ -617,7 +617,7 @@ class _DSPGenerator: if not (p.platform in seen or seen.add(p.platform))] - def Build(self): + def Build(self) -> None: pass V6DSPHeader = """\ @@ -645,7 +645,7 @@ CFG=%(name)s - Win32 %(confkey)s class _GenerateV6DSP(_DSPGenerator): """Generates a Project file for MSVS 6.0""" - def PrintHeader(self): + def PrintHeader(self) -> None: # pick a default config confkeys = sorted(self.configs.keys()) @@ -659,7 +659,7 @@ class _GenerateV6DSP(_DSPGenerator): self.file.write('!MESSAGE\n\n') - def PrintProject(self): + def PrintProject(self) -> None: name = self.name self.file.write('# Begin Project\n' '# PROP AllowPerConfigDependencies 0\n' @@ -728,7 +728,7 @@ class _GenerateV6DSP(_DSPGenerator): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '\n') - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp|c|cxx|l|y|def|odl|idl|hpj|bat', 'Header Files': 'h|hpp|hxx|hm|inl', 'Local Headers': 'h|hpp|hxx|hm|inl', @@ -882,7 +882,7 @@ V8DSPConfiguration = """\ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): """Generates a Project file for MSVS .NET""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: _DSPGenerator.__init__(self, dspfile, source, env) self.version = env['MSVS_VERSION'] self.version_num, self.suite = msvs_parse_version(self.version) @@ -905,7 +905,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): _GenerateV7User.__init__(self, dspfile, source, env) - def PrintHeader(self): + def PrintHeader(self) -> None: env = self.env versionstr = self.versionstr name = self.name @@ -948,7 +948,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.file.write('\t\n' '\t\n') - def PrintProject(self): + def PrintProject(self) -> None: self.file.write('\t\n') confkeys = sorted(self.configs.keys()) @@ -1005,7 +1005,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '-->\n') - def printSources(self, hierarchy, commonprefix): + def printSources(self, hierarchy, commonprefix) -> None: sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) # First folders, then files @@ -1027,7 +1027,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): '\t\t\t\tRelativePath="%s">\n' '\t\t\t\n' % file) - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', 'Header Files': 'h;hpp;hxx;hm;inl', 'Local Headers': 'h;hpp;hxx;hm;inl', @@ -1192,7 +1192,7 @@ V15DSPHeader = """\ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): """Generates a Project file for MSVS 2010""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: _DSPGenerator.__init__(self, dspfile, source, env) self.dspheader = V10DSPHeader self.dspconfiguration = V10DSPProjectConfiguration @@ -1200,7 +1200,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): _GenerateV10User.__init__(self, dspfile, source, env) - def PrintHeader(self): + def PrintHeader(self) -> None: env = self.env name = self.name versionstr = self.versionstr @@ -1340,7 +1340,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '-->\n') - def printFilters(self, hierarchy, name): + def printFilters(self, hierarchy, name) -> None: sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) for key, value in sorteditems: @@ -1351,7 +1351,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\n' % (filter_name, _generateGUID(self.dspabs, filter_name))) self.printFilters(value, filter_name) - def printSources(self, hierarchy, kind, commonprefix, filter_name): + def printSources(self, hierarchy, kind, commonprefix, filter_name) -> None: keywords = {'Source Files': 'ClCompile', 'Header Files': 'ClInclude', 'Local Headers': 'ClInclude', @@ -1377,7 +1377,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\t%s\n' '\t\t\n' % (keywords[kind], file, filter_name, keywords[kind])) - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', 'Header Files': 'h;hpp;hxx;hm;inl', 'Local Headers': 'h;hpp;hxx;hm;inl', @@ -1443,7 +1443,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): #'\t\t\n' '\t\n' % str(self.sconscript)) - def Parse(self): + def Parse(self) -> None: # DEBUG # print("_GenerateV10DSP.Parse()") pass @@ -1462,7 +1462,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): class _DSWGenerator: """ Base class for DSW generators """ - def __init__(self, dswfile, source, env): + def __init__(self, dswfile, source, env) -> None: self.dswfile = os.path.normpath(str(dswfile)) self.dsw_folder_path = os.path.dirname(os.path.abspath(self.dswfile)) self.env = env @@ -1483,12 +1483,12 @@ class _DSWGenerator: self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0]) self.name = self.env.subst(self.name) - def Build(self): + def Build(self) -> None: pass class _GenerateV7DSW(_DSWGenerator): """Generates a Solution file for MSVS .NET""" - def __init__(self, dswfile, source, env): + def __init__(self, dswfile, source, env) -> None: super().__init__(dswfile, source, env) self.file = None @@ -1520,7 +1520,7 @@ class _GenerateV7DSW(_DSWGenerator): if self.nokeep == 0 and os.path.exists(self.dswfile): self.Parse() - def AddConfig(self, variant, dswfile=dswfile): + def AddConfig(self, variant, dswfile=dswfile) -> None: config = Config() match = re.match(r'(.*)\|(.*)', variant) @@ -1548,7 +1548,7 @@ class _GenerateV7DSW(_DSWGenerator): self.platforms = [p.platform for p in self.configs.values() if not (p.platform in seen or seen.add(p.platform))] - def GenerateProjectFilesInfo(self): + def GenerateProjectFilesInfo(self) -> None: for dspfile in self.dspfiles: dsp_folder_path, name = os.path.split(dspfile) dsp_folder_path = os.path.abspath(dsp_folder_path) @@ -1601,7 +1601,7 @@ class _GenerateV7DSW(_DSWGenerator): self.configs.update(data) - def PrintSolution(self): + def PrintSolution(self) -> None: """Writes a solution file""" self.file.write('Microsoft Visual Studio Solution File, Format Version %s\n' % self.versionstr) if self.version_num >= 14.3: @@ -1769,7 +1769,7 @@ Package=<3> class _GenerateV6DSW(_DSWGenerator): """Generates a Workspace file for MSVS 6.0""" - def PrintWorkspace(self): + def PrintWorkspace(self) -> None: """ writes a DSW file """ name = self.name dspfile = os.path.relpath(self.dspfiles[0], self.dsw_folder_path) @@ -1785,7 +1785,7 @@ class _GenerateV6DSW(_DSWGenerator): self.file.close() -def GenerateDSP(dspfile, source, env): +def GenerateDSP(dspfile, source, env) -> None: """Generates a Project file based on the version of MSVS that is being used""" version_num = 6.0 @@ -1801,7 +1801,7 @@ def GenerateDSP(dspfile, source, env): g = _GenerateV6DSP(dspfile, source, env) g.Build() -def GenerateDSW(dswfile, source, env): +def GenerateDSW(dswfile, source, env) -> None: """Generates a Solution/Workspace file based on the version of MSVS that is being used""" version_num = 6.0 @@ -1861,7 +1861,7 @@ def GenerateProject(target, source, env): GenerateDSW(dswfile, source, env) -def GenerateSolution(target, source, env): +def GenerateSolution(target, source, env) -> None: GenerateDSW(target[0], source, env) def projectEmitter(target, source, env): @@ -2039,7 +2039,7 @@ solutionBuilder = SCons.Builder.Builder(action = '$MSVSSOLUTIONCOM', default_MSVS_SConscript = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Microsoft Visual Studio project files to an Environment.""" try: diff --git a/SCons/Tool/msvsTests.py b/SCons/Tool/msvsTests.py index c4d2e98..9c369d1 100644 --- a/SCons/Tool/msvsTests.py +++ b/SCons/Tool/msvsTests.py @@ -391,7 +391,7 @@ regdata_cv = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion] regdata_none = [] class DummyEnv: - def __init__(self, dict=None): + def __init__(self, dict=None) -> None: self.fs = SCons.Node.FS.FS() if dict: self.dict = dict @@ -403,13 +403,13 @@ class DummyEnv: return self.dict return self.dict[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dict[key] = value def __getitem__(self, key): return self.dict[key] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict def get(self, name, value=None): @@ -424,14 +424,14 @@ class DummyEnv: class RegKey: """key class for storing an 'open' registry key""" - def __init__(self,key): + def __init__(self,key) -> None: self.key = key # Warning: this is NOT case-insensitive, unlike the Windows registry. # So e.g. HKLM\Software is NOT the same key as HKLM\SOFTWARE. class RegNode: """node in the dummy registry""" - def __init__(self,name): + def __init__(self,name) -> None: self.valdict = {} self.keydict = {} self.keyarray = [] @@ -444,7 +444,7 @@ class RegNode: else: raise SCons.Util.RegError - def addValue(self,name,val): + def addValue(self,name,val) -> None: self.valdict[name] = val self.valarray.append(name) @@ -456,7 +456,7 @@ class RegNode: raise SCons.Util.RegError return rv - def key(self,key,sep = '\\'): + def key(self,key,sep: str = '\\'): if key.find(sep) != -1: keyname, subkeys = key.split(sep,1) else: @@ -471,7 +471,7 @@ class RegNode: except KeyError: raise SCons.Util.RegError - def addKey(self,name,sep = '\\'): + def addKey(self,name,sep: str = '\\'): if name.find(sep) != -1: keyname, subkeys = name.split(sep, 1) else: @@ -491,10 +491,10 @@ class RegNode: def keyindex(self,index): return self.keydict[self.keyarray[index]] - def __str__(self): + def __str__(self) -> str: return self._doStr() - def _doStr(self, indent = ''): + def _doStr(self, indent: str = ''): rv = "" for value in self.valarray: rv = rv + '%s"%s" = "%s"\n' % (indent, value, self.valdict[value]) @@ -506,7 +506,7 @@ class RegNode: class DummyRegistry: """registry class for storing fake registry attributes""" - def __init__(self,data): + def __init__(self,data) -> None: """parse input data into the fake registry""" self.root = RegNode('REGISTRY') self.root.addKey('HKEY_LOCAL_MACHINE') @@ -516,7 +516,7 @@ class DummyRegistry: self.parse(data) - def parse(self, data): + def parse(self, data) -> None: parents = [None, None] parents[0] = self.root keymatch = re.compile(r'^\[(.*)\]$') @@ -577,7 +577,7 @@ def DummyQueryValue(key, value): # print "Query Value",key.name+"\\"+value,"=>",rv return rv -def DummyExists(path): +def DummyExists(path) -> int: return 1 def DummyVsWhere(msvc_version, env): @@ -587,7 +587,7 @@ def DummyVsWhere(msvc_version, env): class msvsTestCase(unittest.TestCase): """This test case is run several times with different defaults. See its subclasses below.""" - def setUp(self): + def setUp(self) -> None: debug("THIS TYPE :%s"%self) global registry registry = self.registry @@ -599,7 +599,7 @@ class msvsTestCase(unittest.TestCase): os.chdir(self.test.workpath("")) self.fs = SCons.Node.FS.FS() - def test_get_default_version(self): + def test_get_default_version(self) -> None: """Test retrieval of the default visual studio version""" debug("Testing for default version %s"%self.default_version) @@ -632,18 +632,18 @@ class msvsTestCase(unittest.TestCase): assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION'] assert v3 == override, v3 - def _TODO_test_merge_default_version(self): + def _TODO_test_merge_default_version(self) -> None: """Test the merge_default_version() function""" pass - def test_query_versions(self): + def test_query_versions(self) -> None: """Test retrieval of the list of visual studio versions""" v1 = query_versions() 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): + def test_config_generation(self) -> None: """Test _DSPGenerator.__init__(...)""" if not self.highest_version : return diff --git a/SCons/Tool/mwcc.py b/SCons/Tool/mwcc.py index 8f1201a..22b610a 100644 --- a/SCons/Tool/mwcc.py +++ b/SCons/Tool/mwcc.py @@ -37,7 +37,7 @@ import os.path import SCons.Util -def set_vars(env): +def set_vars(env) -> int: """Set MWCW_VERSION, MWCW_VERSIONS, and some codewarrior environment vars MWCW_VERSIONS is set to a list of objects representing installed versions @@ -120,7 +120,7 @@ def find_versions(): class MWVersion: - def __init__(self, version, path, platform): + def __init__(self, version, path, platform) -> None: self.version = version self.path = path self.platform = platform @@ -144,7 +144,7 @@ class MWVersion: self.includes = [msl, support] self.libs = [msl, support] - def __str__(self): + def __str__(self) -> str: return self.version @@ -152,7 +152,7 @@ CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for the mwcc to an Environment.""" import SCons.Defaults import SCons.Tool diff --git a/SCons/Tool/mwld.py b/SCons/Tool/mwld.py index 2067660..9824c01 100644 --- a/SCons/Tool/mwld.py +++ b/SCons/Tool/mwld.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Tool -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for lib to an Environment.""" SCons.Tool.createStaticLibBuilder(env) SCons.Tool.createSharedLibBuilder(env) diff --git a/SCons/Tool/nasm.py b/SCons/Tool/nasm.py index ff0bc61..253ad1c 100644 --- a/SCons/Tool/nasm.py +++ b/SCons/Tool/nasm.py @@ -44,7 +44,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for nasm to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/ninja/Methods.py b/SCons/Tool/ninja/Methods.py index c0afab8..7259475 100644 --- a/SCons/Tool/ninja/Methods.py +++ b/SCons/Tool/ninja/Methods.py @@ -33,17 +33,17 @@ from SCons.Tool.ninja.Utils import get_targets_sources, get_dependencies, get_or get_rule, get_path, generate_command, get_command_env, get_comstr -def register_custom_handler(env, name, handler): +def register_custom_handler(env, name, handler) -> None: """Register a custom handler for SCons function actions.""" env[NINJA_CUSTOM_HANDLERS][name] = handler -def register_custom_rule_mapping(env, pre_subst_string, rule): +def register_custom_rule_mapping(env, pre_subst_string, rule) -> None: """Register a function to call for a given rule.""" SCons.Tool.ninja.Globals.__NINJA_RULE_MAPPING[pre_subst_string] = rule -def register_custom_rule(env, rule, command, description="", deps=None, pool=None, use_depfile=False, use_response_file=False, response_file_content="$rspc"): +def register_custom_rule(env, rule, command, description: str="", deps=None, pool=None, use_depfile: bool=False, use_response_file: bool=False, response_file_content: str="$rspc") -> None: """Allows specification of Ninja rules from inside SCons files.""" rule_obj = { "command": command, @@ -66,12 +66,12 @@ def register_custom_rule(env, rule, command, description="", deps=None, pool=Non env[NINJA_RULES][rule] = rule_obj -def register_custom_pool(env, pool, size): +def register_custom_pool(env, pool, size) -> None: """Allows the creation of custom Ninja pools""" env[NINJA_POOLS][pool] = size -def set_build_node_callback(env, node, callback): +def set_build_node_callback(env, node, callback) -> None: if not node.is_conftest(): node.attributes.ninja_build_callback = callback @@ -215,7 +215,7 @@ def get_command(env, node, action): # pylint: disable=too-many-branches return ninja_build -def gen_get_response_file_command(env, rule, tool, tool_is_dynamic=False, custom_env={}): +def gen_get_response_file_command(env, rule, tool, tool_is_dynamic: bool=False, custom_env={}): """Generate a response file command provider for rule name.""" # If win32 using the environment with a response file command will cause diff --git a/SCons/Tool/ninja/NinjaState.py b/SCons/Tool/ninja/NinjaState.py index 5e7c289..707a9e2 100644 --- a/SCons/Tool/ninja/NinjaState.py +++ b/SCons/Tool/ninja/NinjaState.py @@ -52,7 +52,7 @@ from .Methods import get_command class NinjaState: """Maintains state of Ninja build system as it's translated from SCons.""" - def __init__(self, env, ninja_file, ninja_syntax): + def __init__(self, env, ninja_file, ninja_syntax) -> None: self.env = env self.ninja_file = ninja_file @@ -303,7 +303,7 @@ class NinjaState: } self.pools = {"scons_pool": 1} - def add_build(self, node): + def add_build(self, node) -> bool: if not node.has_builder(): return False @@ -348,12 +348,12 @@ class NinjaState: # TODO: rely on SCons to tell us what is generated source # or some form of user scanner maybe (Github Issue #3624) - def is_generated_source(self, output): + def is_generated_source(self, output) -> bool: """Check if output ends with a known generated suffix.""" _, suffix = splitext(output) return suffix in self.generated_suffixes - def has_generated_sources(self, output): + def has_generated_sources(self, output) -> bool: """ Determine if output indicates this is a generated header file. """ @@ -710,7 +710,7 @@ class NinjaState: class SConsToNinjaTranslator: """Translates SCons Actions into Ninja build objects.""" - def __init__(self, env): + def __init__(self, env) -> None: self.env = env self.func_handlers = { # Skip conftest builders diff --git a/SCons/Tool/ninja/Overrides.py b/SCons/Tool/ninja/Overrides.py index e98ec40..83d2efb 100644 --- a/SCons/Tool/ninja/Overrides.py +++ b/SCons/Tool/ninja/Overrides.py @@ -27,7 +27,7 @@ ninja file generation import SCons -def ninja_hack_linkcom(env): +def ninja_hack_linkcom(env) -> None: # TODO: change LINKCOM and SHLINKCOM to handle embedding manifest exe checks # without relying on the SCons hacks that SCons uses by default. if env["PLATFORM"] == "win32": @@ -42,7 +42,7 @@ def ninja_hack_linkcom(env): ] = '${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES", "$SHLINKCOMSTR")}' -def ninja_hack_arcom(env): +def ninja_hack_arcom(env) -> None: """ Force ARCOM so use 's' flag on ar instead of separately running ranlib """ @@ -68,12 +68,12 @@ class NinjaNoResponseFiles(SCons.Platform.TempFileMunge): def __call__(self, target, source, env, for_signature): return self.cmd - def _print_cmd_str(*_args, **_kwargs): + def _print_cmd_str(*_args, **_kwargs) -> None: """Disable this method""" pass -def ninja_always_serial(self, num, taskmaster): +def ninja_always_serial(self, num, taskmaster) -> None: """Replacement for SCons.Job.Jobs constructor which always uses the Serial Job class.""" # We still set self.num_jobs to num even though it's a lie. The # only consumer of this attribute is the Parallel Job class AND diff --git a/SCons/Tool/ninja/Utils.py b/SCons/Tool/ninja/Utils.py index 7269fb2..eb09daf 100644 --- a/SCons/Tool/ninja/Utils.py +++ b/SCons/Tool/ninja/Utils.py @@ -34,7 +34,7 @@ class NinjaExperimentalWarning(SCons.Warnings.WarningOnByDefault): pass -def ninja_add_command_line_options(): +def ninja_add_command_line_options() -> None: """ Add additional command line arguments to SCons specific to the ninja tool """ @@ -92,7 +92,7 @@ def alias_to_ninja_build(node): } -def check_invalid_ninja_node(node): +def check_invalid_ninja_node(node) -> bool: return not isinstance(node, (SCons.Node.FS.Base, SCons.Node.Alias.Alias)) @@ -129,7 +129,7 @@ def get_order_only(node): return [get_path(src_file(prereq)) for prereq in filter_ninja_nodes(node.prerequisites)] -def get_dependencies(node, skip_sources=False): +def get_dependencies(node, skip_sources: bool=False): """Return a list of dependencies for node.""" if skip_sources: return [ @@ -236,7 +236,7 @@ def to_escaped_list(env, lst): return sorted([dep.escape(env.get("ESCAPE", lambda x: x)) for dep in deps_list]) -def generate_depfile(env, node, dependencies): +def generate_depfile(env, node, dependencies) -> None: """ Ninja tool function for writing a depfile. The depfile should include the node path followed by all the dependent files in a makefile format. @@ -281,7 +281,7 @@ def ninja_recursive_sorted_dict(build): return sorted_dict -def ninja_sorted_build(ninja, **build): +def ninja_sorted_build(ninja, **build) -> None: sorted_dict = ninja_recursive_sorted_dict(build) ninja.build(**sorted_dict) @@ -437,7 +437,7 @@ def ninja_whereis(thing, *_args, **_kwargs): return path -def ninja_print_conf_log(s, target, source, env): +def ninja_print_conf_log(s, target, source, env) -> None: """Command line print only for conftest to generate a correct conf log.""" if target and target[0].is_conftest(): action = SCons.Action._ActionAction() diff --git a/SCons/Tool/ninja/__init__.py b/SCons/Tool/ninja/__init__.py index 2622641..0ee72d2 100644 --- a/SCons/Tool/ninja/__init__.py +++ b/SCons/Tool/ninja/__init__.py @@ -136,7 +136,7 @@ def ninja_builder(env, target, source): sys.stdout.write("\n") -def options(opts): +def options(opts) -> None: """ Add command line Variables for Ninja builder. """ @@ -302,7 +302,7 @@ def generate(env): # instead return something that looks more expanded. So to # continue working even if a user has done this we map both the # "bracketted" and semi-expanded versions. - def robust_rule_mapping(var, rule, tool): + def robust_rule_mapping(var, rule, tool) -> None: provider = gen_get_response_file_command(env, rule, tool) env.NinjaRuleMapping("${" + var + "}", provider) @@ -459,7 +459,7 @@ def generate(env): # In the future we may be able to use this to actually cache the build.ninja # file once we have the upstream support for referencing SConscripts as File # nodes. - def ninja_execute(self): + def ninja_execute(self) -> None: target = self.targets[0] if target.get_env().get('NINJA_SKIP'): @@ -475,7 +475,7 @@ def generate(env): # date-ness. SCons.Script.Main.BuildTask.needs_execute = lambda x: True - def ninja_Set_Default_Targets(env, tlist): + def ninja_Set_Default_Targets(env, tlist) -> None: """ Record the default targets if they were ever set by the user. Ninja will need to write the default targets and make sure not to include diff --git a/SCons/Tool/ninja/ninja_daemon_build.py b/SCons/Tool/ninja/ninja_daemon_build.py index 32c375d..f198d77 100644 --- a/SCons/Tool/ninja/ninja_daemon_build.py +++ b/SCons/Tool/ninja/ninja_daemon_build.py @@ -55,7 +55,7 @@ logging.basicConfig( ) -def log_error(msg): +def log_error(msg) -> None: logging.debug(msg) sys.stderr.write(msg) diff --git a/SCons/Tool/ninja/ninja_run_daemon.py b/SCons/Tool/ninja/ninja_run_daemon.py index 08029a2..666be0f 100644 --- a/SCons/Tool/ninja/ninja_run_daemon.py +++ b/SCons/Tool/ninja/ninja_run_daemon.py @@ -61,7 +61,7 @@ logging.basicConfig( level=logging.DEBUG, ) -def log_error(msg): +def log_error(msg) -> None: logging.debug(msg) sys.stderr.write(msg) diff --git a/SCons/Tool/ninja/ninja_scons_daemon.py b/SCons/Tool/ninja/ninja_scons_daemon.py index 6802af2..2084097 100644 --- a/SCons/Tool/ninja/ninja_scons_daemon.py +++ b/SCons/Tool/ninja/ninja_scons_daemon.py @@ -77,11 +77,11 @@ logging.basicConfig( ) -def daemon_log(message): +def daemon_log(message) -> None: logging.debug(message) -def custom_readlines(handle, line_separator="\n", chunk_size=1): +def custom_readlines(handle, line_separator: str="\n", chunk_size: int=1): buf = "" while not handle.closed: data = handle.read(chunk_size) @@ -98,7 +98,7 @@ def custom_readlines(handle, line_separator="\n", chunk_size=1): buf = "" -def custom_readerr(handle, line_separator="\n", chunk_size=1): +def custom_readerr(handle, line_separator: str="\n", chunk_size: int=1): buf = "" while not handle.closed: data = handle.read(chunk_size) @@ -112,13 +112,13 @@ def custom_readerr(handle, line_separator="\n", chunk_size=1): yield chunk + line_separator -def enqueue_output(out, queue): +def enqueue_output(out, queue) -> None: for line in iter(custom_readlines(out)): queue.put(line) out.close() -def enqueue_error(err, queue): +def enqueue_error(err, queue) -> None: for line in iter(custom_readerr(err)): queue.put(line) err.close() @@ -143,7 +143,7 @@ class StateInfo: shared_state = StateInfo() -def sigint_func(signum, frame): +def sigint_func(signum, frame) -> None: global shared_state shared_state.daemon_needs_to_shutdown = True @@ -264,7 +264,7 @@ logging.debug( keep_alive_timer = timer() -def server_thread_func(): +def server_thread_func() -> None: global shared_state class S(http.server.BaseHTTPRequestHandler): def do_GET(self): @@ -284,7 +284,7 @@ def server_thread_func(): daemon_log(f"Got request: {build[0]}") input_q.put(build[0]) - def pred(): + def pred() -> bool: return build[0] in shared_state.finished_building with building_cv: @@ -329,7 +329,7 @@ def server_thread_func(): daemon_log("SERVER ERROR: " + traceback.format_exc()) raise - def log_message(self, format, *args): + def log_message(self, format, *args) -> None: return socketserver.TCPServer.allow_reuse_address = True diff --git a/SCons/Tool/packaging/__init__.py b/SCons/Tool/packaging/__init__.py index 6fe01c1..c8e530d 100644 --- a/SCons/Tool/packaging/__init__.py +++ b/SCons/Tool/packaging/__init__.py @@ -199,7 +199,7 @@ def Package(env, target=None, source=None, **kw): # added = False -def generate(env): +def generate(env) -> None: global added if not added: added = True @@ -218,11 +218,11 @@ def generate(env): env['BUILDERS']['Tag'] = Tag -def exists(env): +def exists(env) -> int: return 1 -def options(opts): +def options(opts) -> None: opts.AddVariables( EnumVariable('PACKAGETYPE', 'the type of package to create.', @@ -235,7 +235,7 @@ def options(opts): # Internal utility functions # -def copy_attr(f1, f2): +def copy_attr(f1, f2) -> None: """ Copies the special packaging file attributes from f1 to f2. """ if f1._tags: @@ -247,7 +247,7 @@ def copy_attr(f1, f2): for attr in pattrs: f2.Tag(attr, f1.GetTag(attr)) -def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): +def putintopackageroot(target, source, env, pkgroot, honor_install_location: int=1): """ Copies all source files to the directory given in pkgroot. If honor_install_location is set and the copied source file has an @@ -298,7 +298,7 @@ def stripinstallbuilder(target, source, env): It also warns about files which have no install builder attached. """ - def has_no_install_location(file): + def has_no_install_location(file) -> bool: return not (file.has_builder() and hasattr(file.builder, 'name') and file.builder.name in ["InstallBuilder", "InstallAsBuilder"]) diff --git a/SCons/Tool/packaging/ipk.py b/SCons/Tool/packaging/ipk.py index ac8b992..930eacb 100644 --- a/SCons/Tool/packaging/ipk.py +++ b/SCons/Tool/packaging/ipk.py @@ -105,7 +105,7 @@ def gen_ipk_dir(proot, source, env, kw): # the packageroot directory does now contain the specfiles. return proot -def build_specfiles(source, target, env): +def build_specfiles(source, target, env) -> int: """ Filter the targets for the needed files and use the variables in env to create the specfile. """ diff --git a/SCons/Tool/packaging/msi.py b/SCons/Tool/packaging/msi.py index 458e81f..a0bed8f 100644 --- a/SCons/Tool/packaging/msi.py +++ b/SCons/Tool/packaging/msi.py @@ -130,7 +130,7 @@ def create_feature_dict(files): """ dict = {} - def add_to_dict( feature, file ): + def add_to_dict( feature, file ) -> None: if not SCons.Util.is_List( feature ): feature = [ feature ] @@ -150,7 +150,7 @@ def create_feature_dict(files): return dict -def generate_guids(root): +def generate_guids(root) -> None: """ generates globally unique identifiers for parts of the xml which need them. @@ -179,7 +179,7 @@ def generate_guids(root): node.attributes[attribute] = str(hash) -def string_wxsfile(target, source, env): +def string_wxsfile(target, source, env) -> str: return "building WiX file %s" % target[0].path def build_wxsfile(target, source, env): @@ -266,7 +266,7 @@ def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): # # mandatory and optional file tags # -def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set): +def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set) -> None: """ Builds the Component sections of the wxs file with their included files. Files need to be specified in 8.3 format and in the long name format, long @@ -358,7 +358,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, # # additional functions # -def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): +def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set) -> None: """ This function creates the tag based on the supplied xml tree. This is achieved by finding all s and adding them to a default target. @@ -413,7 +413,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): root.getElementsByTagName('Product')[0].childNodes.append(Feature) -def build_wxsfile_default_gui(root): +def build_wxsfile_default_gui(root) -> None: """ This function adds a default GUI to the wxs file """ factory = Document() @@ -427,7 +427,7 @@ def build_wxsfile_default_gui(root): UIRef.attributes['Id'] = 'WixUI_ErrorProgressText' Product.childNodes.append(UIRef) -def build_license_file(directory, spec): +def build_license_file(directory, spec) -> None: """ Creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" in the given directory """ @@ -451,7 +451,7 @@ def build_license_file(directory, spec): # # mandatory and optional package tags # -def build_wxsfile_header_section(root, spec): +def build_wxsfile_header_section(root, spec) -> None: """ Adds the xml file node which define the package meta-data. """ # Create the needed DOM nodes and add them at the correct position in the tree. diff --git a/SCons/Tool/packaging/rpm.py b/SCons/Tool/packaging/rpm.py index cdeabcf..a0c3172 100644 --- a/SCons/Tool/packaging/rpm.py +++ b/SCons/Tool/packaging/rpm.py @@ -317,7 +317,7 @@ class SimpleTagCompiler: "cdef ghij cdef gh ij" """ - def __init__(self, tagset, mandatory=1): + def __init__(self, tagset, mandatory: int=1) -> None: self.tagset = tagset self.mandatory = mandatory diff --git a/SCons/Tool/pdf.py b/SCons/Tool/pdf.py index 050f1a5..ddaaa8a 100644 --- a/SCons/Tool/pdf.py +++ b/SCons/Tool/pdf.py @@ -37,7 +37,7 @@ PDFBuilder = None EpsPdfAction = SCons.Action.Action('$EPSTOPDFCOM', '$EPSTOPDFCOMSTR') -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['PDF'] except KeyError: @@ -57,7 +57,7 @@ def generate(env): # 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): +def generate2(env) -> None: bld = env['BUILDERS']['PDF'] #bld.add_action('.ps', EpsPdfAction) # this is covered by direct Ghostcript action in gs.py bld.add_action('.eps', EpsPdfAction) @@ -66,7 +66,7 @@ def generate2(env): env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('') env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} --outfile=${TARGET}' -def exists(env): +def exists(env) -> int: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." return 1 diff --git a/SCons/Tool/pdflatex.py b/SCons/Tool/pdflatex.py index fbffb23..e3c733b 100644 --- a/SCons/Tool/pdflatex.py +++ b/SCons/Tool/pdflatex.py @@ -49,7 +49,7 @@ def PDFLaTeXAuxFunction(target = None, source= None, env=None): PDFLaTeXAuxAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for pdflatex to an Environment.""" global PDFLaTeXAction if PDFLaTeXAction is None: diff --git a/SCons/Tool/pdftex.py b/SCons/Tool/pdftex.py index e9a0bda..4b7707f 100644 --- a/SCons/Tool/pdftex.py +++ b/SCons/Tool/pdftex.py @@ -68,7 +68,7 @@ def PDFTeXLaTeXFunction(target = None, source= None, env=None): PDFTeXLaTeXAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for pdftex to an Environment.""" global PDFTeXAction if PDFTeXAction is None: diff --git a/SCons/Tool/python.py b/SCons/Tool/python.py index c61fc8d..2820afb 100644 --- a/SCons/Tool/python.py +++ b/SCons/Tool/python.py @@ -33,13 +33,13 @@ import SCons.Tool from SCons.Scanner.Python import PythonScanner, PythonSuffixes -def generate(env): +def generate(env) -> None: """Hook the python builder and scanner into the environment.""" for suffix in PythonSuffixes: SCons.Tool.SourceFileScanner.add_scanner(suffix, PythonScanner) -def exists(env): +def exists(env) -> bool: return True # Local Variables: diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py index 607b58d..376e2ba 100644 --- a/SCons/Tool/qt.py +++ b/SCons/Tool/qt.py @@ -34,5 +34,5 @@ def generate(env): "'qt3' will be removed entirely in a future release." ) -def exists(env): +def exists(env) -> bool: return False diff --git a/SCons/Tool/qt3.py b/SCons/Tool/qt3.py index 4e69756..d35b661 100644 --- a/SCons/Tool/qt3.py +++ b/SCons/Tool/qt3.py @@ -90,7 +90,7 @@ def find_platform_specific_qt3_paths(): QT3_BIN_DIR = find_platform_specific_qt3_paths() -def checkMocIncluded(target, source, env): +def checkMocIncluded(target, source, env) -> None: moc = target[0] cpp = source[0] # looks like cpp.includes is cleared before the build stage :-( @@ -116,7 +116,7 @@ class _Automoc: StaticLibraries. """ - def __init__(self, objBuilderName): + def __init__(self, objBuilderName) -> None: self.objBuilderName = objBuilderName def __call__(self, target, source, env): diff --git a/SCons/Tool/rmic.py b/SCons/Tool/rmic.py index 5c7a040..8523397 100644 --- a/SCons/Tool/rmic.py +++ b/SCons/Tool/rmic.py @@ -104,7 +104,7 @@ RMICBuilder = SCons.Builder.Builder(action = RMICAction, target_factory = SCons.Node.FS.Dir, source_factory = SCons.Node.FS.File) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for rmic to an Environment.""" env['BUILDERS']['RMIC'] = RMICBuilder @@ -123,7 +123,7 @@ def generate(env): env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}' env['JAVACLASSSUFFIX'] = '.class' -def exists(env): +def exists(env) -> int: # As reported by Jan Nijtmans in issue #2730, the simple # return env.Detect('rmic') # doesn't always work during initialization. For now, we diff --git a/SCons/Tool/rpcgen.py b/SCons/Tool/rpcgen.py index 5ed5658..d5f514a 100644 --- a/SCons/Tool/rpcgen.py +++ b/SCons/Tool/rpcgen.py @@ -42,7 +42,7 @@ rpcgen_header = cmd % ('h', '$RPCGENHEADERFLAGS') rpcgen_service = cmd % ('m', '$RPCGENSERVICEFLAGS') rpcgen_xdr = cmd % ('c', '$RPCGENXDRFLAGS') -def generate(env): +def generate(env) -> None: """Add RPCGEN Builders and construction variables for an Environment.""" client = Builder(action=rpcgen_client, suffix='_clnt.c', src_suffix='.x') diff --git a/SCons/Tool/rpm.py b/SCons/Tool/rpm.py index 2fd802a..94f5e57 100644 --- a/SCons/Tool/rpm.py +++ b/SCons/Tool/rpm.py @@ -46,7 +46,7 @@ import SCons.Util import SCons.Action import SCons.Defaults -def get_cmd(source, env): +def get_cmd(source, env) -> str: tar_file_with_included_specfile = source if SCons.Util.is_List(source): tar_file_with_included_specfile = source[0] @@ -110,7 +110,7 @@ RpmBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$RPMCOM', '$RPM -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for rpm to an Environment.""" try: bld = env['BUILDERS']['Rpm'] diff --git a/SCons/Tool/rpmutils.py b/SCons/Tool/rpmutils.py index 2c4fb32..209fcea 100644 --- a/SCons/Tool/rpmutils.py +++ b/SCons/Tool/rpmutils.py @@ -437,7 +437,7 @@ arch_canon = { # End of rpmrc dictionaries (Marker, don't change or remove!) -def defaultMachine(use_rpm_default=True): +def defaultMachine(use_rpm_default: bool=True): """ Return the canonicalized machine name. """ if use_rpm_default: @@ -471,7 +471,7 @@ def defaultNames(): """ Return the canonicalized machine and system name. """ return defaultMachine(), defaultSystem() -def updateRpmDicts(rpmrc, pyfile): +def updateRpmDicts(rpmrc, pyfile) -> None: """ Read the given rpmrc file with RPM definitions and update the info dictionaries in the file pyfile with it. The arguments will usually be 'rpmrc.in' from a recent RPM source @@ -531,10 +531,10 @@ def updateRpmDicts(rpmrc, pyfile): except: pass -def usage(): +def usage() -> None: print("rpmutils.py rpmrc.in rpmutils.py") -def main(): +def main() -> None: import sys if len(sys.argv) < 3: diff --git a/SCons/Tool/sgiar.py b/SCons/Tool/sgiar.py index 54f8b7b..72ce376 100644 --- a/SCons/Tool/sgiar.py +++ b/SCons/Tool/sgiar.py @@ -39,7 +39,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/sgicc.py b/SCons/Tool/sgicc.py index 94a0497..7950d10 100644 --- a/SCons/Tool/sgicc.py +++ b/SCons/Tool/sgicc.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gcc to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/sgicxx.py b/SCons/Tool/sgicxx.py index 48b04ea..796f7ab 100644 --- a/SCons/Tool/sgicxx.py +++ b/SCons/Tool/sgicxx.py @@ -40,7 +40,7 @@ cplusplus = SCons.Tool.cxx #cplusplus = __import__('cxx', globals(), locals(), []) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for SGI MIPS C++ to an Environment.""" cplusplus.generate(env) diff --git a/SCons/Tool/sgilink.py b/SCons/Tool/sgilink.py index e92c7b9..f66ad5a 100644 --- a/SCons/Tool/sgilink.py +++ b/SCons/Tool/sgilink.py @@ -36,7 +36,7 @@ from . import link linkers = ['CC', 'cc'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for MIPSPro to an Environment.""" link.generate(env) diff --git a/SCons/Tool/sunar.py b/SCons/Tool/sunar.py index 266e914..03223b6 100644 --- a/SCons/Tool/sunar.py +++ b/SCons/Tool/sunar.py @@ -38,7 +38,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/suncc.py b/SCons/Tool/suncc.py index 4651219..4ef0231 100644 --- a/SCons/Tool/suncc.py +++ b/SCons/Tool/suncc.py @@ -36,7 +36,7 @@ import SCons.Util from . import cc -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Forte C and C++ compilers to an Environment. diff --git a/SCons/Tool/suncxx.py b/SCons/Tool/suncxx.py index 7c4b094..51dc373 100644 --- a/SCons/Tool/suncxx.py +++ b/SCons/Tool/suncxx.py @@ -121,7 +121,7 @@ def get_cppc(env): return (cppcPath, 'CC', 'CC', cppcVersion) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for SunPRO C++.""" path, cxx, shcxx, version = get_cppc(env) if path: diff --git a/SCons/Tool/sunf77.py b/SCons/Tool/sunf77.py index 20d1893..efeb488 100644 --- a/SCons/Tool/sunf77.py +++ b/SCons/Tool/sunf77.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf77', 'f77'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sunf77 to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunf90.py b/SCons/Tool/sunf90.py index ce1697c..4ce03c1 100644 --- a/SCons/Tool/sunf90.py +++ b/SCons/Tool/sunf90.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf90', 'f90'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sun f90 compiler to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunf95.py b/SCons/Tool/sunf95.py index 218569c..273987b 100644 --- a/SCons/Tool/sunf95.py +++ b/SCons/Tool/sunf95.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf95', 'f95'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sunf95 to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunlink.py b/SCons/Tool/sunlink.py index b0c9816..c86d7c2 100644 --- a/SCons/Tool/sunlink.py +++ b/SCons/Tool/sunlink.py @@ -55,7 +55,7 @@ for d in dirs: break -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Forte to an Environment.""" link.generate(env) diff --git a/SCons/Tool/swig.py b/SCons/Tool/swig.py index ff0c80d..aefd7cb 100644 --- a/SCons/Tool/swig.py +++ b/SCons/Tool/swig.py @@ -46,7 +46,7 @@ swigs = [ 'swig', 'swig3.0', 'swig2.0' ] SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') -def swigSuffixEmitter(env, source): +def swigSuffixEmitter(env, source) -> str: if '-c++' in SCons.Util.CLVar(env.subst("$SWIGFLAGS", source=source)): return '$SWIGCXXFILESUFFIX' else: @@ -78,7 +78,7 @@ def _find_modules(src): directors = directors or 'directors' in m[0] return mnames, directors -def _add_director_header_targets(target, env): +def _add_director_header_targets(target, env) -> None: # Directors only work with C++ code, not C suffix = env.subst(env['SWIGCXXFILESUFFIX']) # For each file ending in SWIGCXXFILESUFFIX, add a new target director @@ -158,7 +158,7 @@ def _get_swig_version(env, swig): return version -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for swig to an Environment.""" c_file, cxx_file = SCons.Tool.createCFileBuilders(env) diff --git a/SCons/Tool/tar.py b/SCons/Tool/tar.py index 2593781..ba7f45c 100644 --- a/SCons/Tool/tar.py +++ b/SCons/Tool/tar.py @@ -50,7 +50,7 @@ TarBuilder = SCons.Builder.Builder(action = TarAction, multi = 1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for tar to an Environment.""" try: bld = env['BUILDERS']['Tar'] diff --git a/SCons/Tool/tex.py b/SCons/Tool/tex.py index 0a688f5..72526c3 100644 --- a/SCons/Tool/tex.py +++ b/SCons/Tool/tex.py @@ -149,11 +149,11 @@ _null = SCons.Scanner.LaTeX._null modify_env_var = SCons.Scanner.LaTeX.modify_env_var -def check_file_error_message(utility, filename='log'): +def check_file_error_message(utility, filename: str='log') -> None: msg = '%s returned an error, check the %s file\n' % (utility, filename) sys.stdout.write(msg) -def FindFile(name,suffixes,paths,env,requireExt=False): +def FindFile(name,suffixes,paths,env,requireExt: bool=False): if requireExt: name,ext = SCons.Util.splitext(name) # if the user gave an extension use it. @@ -253,7 +253,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None # .aux files already processed by BibTex already_bibtexed = [] - def check_content_hash(filenode, suffix): + def check_content_hash(filenode, suffix) -> bool: """ Routine to update content hash and compare """ @@ -840,7 +840,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): TeXLaTeXAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for TeX to an Environment.""" global TeXLaTeXAction @@ -859,7 +859,7 @@ def generate(env): bld.add_action('.tex', TeXLaTeXAction) bld.add_emitter('.tex', tex_eps_emitter) -def generate_darwin(env): +def generate_darwin(env) -> None: try: environ = env['ENV'] except KeyError: @@ -874,7 +874,7 @@ def generate_darwin(env): if ospath: env.AppendENVPath('PATH', ospath) -def generate_common(env): +def generate_common(env) -> None: """Add internal Builders and construction variables for LaTeX to an Environment.""" # Add OSX system paths so TeX tools can be found diff --git a/SCons/Tool/textfile.py b/SCons/Tool/textfile.py index 0ec31d8..9d98644 100644 --- a/SCons/Tool/textfile.py +++ b/SCons/Tool/textfile.py @@ -137,11 +137,11 @@ def _action(target, source, env): target_file.close() -def _strfunc(target, source, env): +def _strfunc(target, source, env) -> str: return "Creating '%s'" % target[0] -def _convert_list_R(newlist, sources): +def _convert_list_R(newlist, sources) -> None: for elem in sources: if is_Sequence(elem): _convert_list_R(newlist, elem) @@ -181,7 +181,7 @@ _subst_builder = SCons.Builder.Builder( ) -def generate(env): +def generate(env) -> None: env['LINESEPARATOR'] = LINESEP # os.linesep env['BUILDERS']['Textfile'] = _text_builder env['TEXTFILEPREFIX'] = '' @@ -192,7 +192,7 @@ def generate(env): env['FILE_ENCODING'] = env.get('FILE_ENCODING', 'utf-8') -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/tlib.py b/SCons/Tool/tlib.py index 33adb57..8b0e6dd 100644 --- a/SCons/Tool/tlib.py +++ b/SCons/Tool/tlib.py @@ -33,7 +33,7 @@ import SCons.Tool import SCons.Tool.bcc32 import SCons.Util -def generate(env): +def generate(env) -> None: SCons.Tool.bcc32.findIt('tlib', env) """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/wix.py b/SCons/Tool/wix.py index 04136ce..617abf2 100644 --- a/SCons/Tool/wix.py +++ b/SCons/Tool/wix.py @@ -36,7 +36,7 @@ import SCons.Builder import SCons.Action import os -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for WiX to an Environment.""" if not exists(env): return diff --git a/SCons/Tool/wixTests.py b/SCons/Tool/wixTests.py index 5b255d9..26b2295 100644 --- a/SCons/Tool/wixTests.py +++ b/SCons/Tool/wixTests.py @@ -41,7 +41,7 @@ test.write('light.exe', 'rem this is light') os.environ['PATH'] += os.pathsep + test.workdir class WixTestCase(unittest.TestCase): - def test_vars(self): + def test_vars(self) -> None: """Test that WiX tool adds vars""" env = Environment(tools=['wix']) assert env['WIXCANDLE'] is not None diff --git a/SCons/Tool/xgettext.py b/SCons/Tool/xgettext.py index ed76e25..f04c6a6 100644 --- a/SCons/Tool/xgettext.py +++ b/SCons/Tool/xgettext.py @@ -51,7 +51,7 @@ class _CmdRunner: variables. It also provides `strfunction()` method, which shall be used by scons Action objects to print command string. """ - def __init__(self, command, commandstr=None): + def __init__(self, command, commandstr=None) -> None: self.out = None self.err = None self.status = None @@ -169,7 +169,7 @@ class _POTBuilder(BuilderBase): return BuilderBase._execute(self, env, target, source, *args) -def _scan_xgettext_from_files(target, source, env, files=None, path=None): +def _scan_xgettext_from_files(target, source, env, files=None, path=None) -> int: """ Parses `POTFILES.in`-like file and returns list of extracted file names. """ if files is None: @@ -257,7 +257,7 @@ def _POTUpdateBuilder(env, **kw): return _POTBuilder(**kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate `xgettext` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 42ef1db..67ecd86 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -125,7 +125,7 @@ def yyEmitter(target, source, env) -> tuple: return _yaccEmitter(target, source, env, ['.yy'], '$YACCHXXFILESUFFIX') -def get_yacc_path(env, append_paths=False) -> Optional[str]: +def get_yacc_path(env, append_paths: bool=False) -> Optional[str]: """ Returns the path to the yacc tool, searching several possible names. diff --git a/SCons/Tool/zip.py b/SCons/Tool/zip.py index f3d38fe..4c04afc 100644 --- a/SCons/Tool/zip.py +++ b/SCons/Tool/zip.py @@ -57,7 +57,7 @@ def _create_zipinfo_for_file(fname, arcname, date_time, compression): return zinfo -def zip_builder(target, source, env): +def zip_builder(target, source, env) -> None: compression = env.get('ZIPCOMPRESSION', zipfile.ZIP_STORED) zip_root = str(env.get('ZIPROOT', '')) date_time = env.get('ZIP_OVERRIDE_TIMESTAMP') @@ -94,7 +94,7 @@ ZipBuilder = SCons.Builder.Builder(action=SCons.Action.Action('$ZIPCOM', '$ZIPCO multi=1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for zip to an Environment.""" try: bld = env['BUILDERS']['Zip'] @@ -110,7 +110,7 @@ def generate(env): env['ZIPROOT'] = SCons.Util.CLVar('') -def exists(env): +def exists(env) -> bool: return True # Local Variables: diff --git a/SCons/Util/__init__.py b/SCons/Util/__init__.py index 2760298..655c5ad 100644 --- a/SCons/Util/__init__.py +++ b/SCons/Util/__init__.py @@ -183,10 +183,10 @@ class NodeList(UserList): ['foo', 'bar'] """ - def __bool__(self): + def __bool__(self) -> bool: return bool(self.data) - def __str__(self): + def __str__(self) -> str: return ' '.join(map(str, self.data)) def __iter__(self): @@ -214,7 +214,7 @@ class DisplayEngine: print_it = True - def __call__(self, text, append_newline=1): + def __call__(self, text, append_newline: int=1) -> None: if not self.print_it: return @@ -231,14 +231,14 @@ class DisplayEngine: with suppress(IOError): sys.stdout.write(str(text)) - def set_mode(self, mode): + def set_mode(self, mode) -> None: self.print_it = mode display = DisplayEngine() # TODO: W0102: Dangerous default value [] as argument (dangerous-default-value) -def render_tree(root, child_func, prune=0, margin=[0], visited=None) -> str: +def render_tree(root, child_func, prune: int=0, margin=[0], visited=None) -> str: """Render a tree of nodes into an ASCII tree view. Args: @@ -302,8 +302,8 @@ BOX_HORIZ_DOWN = chr(0x252c) # '┬' def print_tree( root, child_func, - prune=0, - showtags=False, + prune: int=0, + showtags: bool=False, margin=[0], visited=None, lastChild: bool = False, @@ -432,7 +432,7 @@ def do_flatten( isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes, -): # pylint: disable=redefined-outer-name,redefined-builtin +) -> None: # pylint: disable=redefined-outer-name,redefined-builtin for item in sequence: if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): result.append(item) @@ -564,7 +564,7 @@ class Proxy: __str__ = Delegate('__str__') """ - def __init__(self, subject): + def __init__(self, subject) -> None: """Wrap an object as a Proxy object""" self._subject = subject @@ -593,7 +593,7 @@ class Delegate: class Foo(Proxy): __str__ = Delegate('__str__') """ - def __init__(self, attribute): + def __init__(self, attribute) -> None: self.attribute = attribute def __get__(self, obj, cls): @@ -858,7 +858,7 @@ class CLVar(UserList): 6 ['--some', '--opts', 'and', 'args', 'strips', 'spaces'] """ - def __init__(self, initlist=None): + def __init__(self, initlist=None) -> None: super().__init__(Split(initlist if initlist is not None else [])) def __add__(self, other): @@ -870,7 +870,7 @@ class CLVar(UserList): def __iadd__(self, other): return super().__iadd__(CLVar(other)) - def __str__(self): + def __str__(self) -> str: # Some cases the data can contain Nodes, so make sure they # processed to string before handing them over to join. return ' '.join([str(d) for d in self.data]) @@ -923,7 +923,7 @@ else: return os.path.normcase(s1) != os.path.normcase(s2) -def adjustixes(fname, pre, suf, ensure_suffix=False) -> str: +def adjustixes(fname, pre, suf, ensure_suffix: bool=False) -> str: """Adjust filename prefixes and suffixes as needed. Add `prefix` to `fname` if specified. @@ -1050,7 +1050,7 @@ class LogicalLines: Allows us to read all "logical" lines at once from a given file object. """ - def __init__(self, fileobj): + def __init__(self, fileobj) -> None: self.fileobj = fileobj def readlines(self): @@ -1064,16 +1064,16 @@ class UniqueList(UserList): up on access by those methods which need to act on a unique list to be correct. That means things like "in" don't have to eat the uniquing time. """ - def __init__(self, initlist=None): + def __init__(self, initlist=None) -> None: super().__init__(initlist) self.unique = True - def __make_unique(self): + def __make_unique(self) -> None: if not self.unique: self.data = uniquer_hashables(self.data) self.unique = True - def __repr__(self): + def __repr__(self) -> str: self.__make_unique() return super().__repr__() @@ -1103,7 +1103,7 @@ class UniqueList(UserList): # __contains__ doesn't need to worry about uniquing, inherit - def __len__(self): + def __len__(self) -> int: self.__make_unique() return super().__len__() @@ -1111,7 +1111,7 @@ class UniqueList(UserList): self.__make_unique() return super().__getitem__(i) - def __setitem__(self, i, item): + def __setitem__(self, i, item) -> None: super().__setitem__(i, item) self.unique = False @@ -1147,11 +1147,11 @@ class UniqueList(UserList): result.unique = False return result - def append(self, item): + def append(self, item) -> None: super().append(item) self.unique = False - def insert(self, i, item): + def insert(self, i, item) -> None: super().insert(i, item) self.unique = False @@ -1163,7 +1163,7 @@ class UniqueList(UserList): self.__make_unique() return super().index(item, *args) - def reverse(self): + def reverse(self) -> None: self.__make_unique() super().reverse() @@ -1172,7 +1172,7 @@ class UniqueList(UserList): self.__make_unique() return super().sort(*args, **kwds) - def extend(self, other): + def extend(self, other) -> None: super().extend(other) self.unique = False @@ -1182,10 +1182,10 @@ class Unbuffered: Delegates everything else to the wrapped object. """ - def __init__(self, file): + def __init__(self, file) -> None: self.file = file - def write(self, arg): + def write(self, arg) -> None: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed # is that the user has press ctrl-c. It this is the case, @@ -1197,7 +1197,7 @@ class Unbuffered: self.file.write(arg) self.file.flush() - def writelines(self, arg): + def writelines(self, arg) -> None: with suppress(IOError): self.file.writelines(arg) self.file.flush() @@ -1244,7 +1244,7 @@ def print_time(): return print_time -def wait_for_process_to_die(pid): +def wait_for_process_to_die(pid) -> None: """ Wait for specified process to die, or alternatively kill it NOTE: This function operates best with psutil pypi package @@ -1278,7 +1278,7 @@ def wait_for_process_to_die(pid): # From: https://stackoverflow.com/questions/1741972/how-to-use-different-formatters-with-the-same-logging-handler-in-python class DispatchingFormatter(Formatter): - def __init__(self, formatters, default_formatter): + def __init__(self, formatters, default_formatter) -> None: self._formatters = formatters self._default_formatter = default_formatter diff --git a/SCons/Util/envs.py b/SCons/Util/envs.py index 963c963..64e728a 100644 --- a/SCons/Util/envs.py +++ b/SCons/Util/envs.py @@ -16,7 +16,7 @@ from .types import is_List, is_Tuple, is_String def PrependPath( - oldpath, newpath, sep=os.pathsep, delete_existing=True, canonicalize=None + oldpath, newpath, sep=os.pathsep, delete_existing: bool=True, canonicalize=None ) -> Union[list, str]: """Prepend *newpath* path elements to *oldpath*. @@ -102,7 +102,7 @@ def PrependPath( def AppendPath( - oldpath, newpath, sep=os.pathsep, delete_existing=True, canonicalize=None + oldpath, newpath, sep=os.pathsep, delete_existing: bool=True, canonicalize=None ) -> Union[list, str]: """Append *newpath* path elements to *oldpath*. @@ -187,7 +187,7 @@ def AppendPath( return sep.join(paths) -def AddPathIfNotExists(env_dict, key, path, sep=os.pathsep): +def AddPathIfNotExists(env_dict, key, path, sep=os.pathsep) -> None: """Add a path element to a construction variable. `key` is looked up in `env_dict`, and `path` is added to it if it @@ -229,7 +229,7 @@ class MethodWrapper: a new underlying object being copied (without which we wouldn't need to save that info). """ - def __init__(self, obj, method, name=None): + def __init__(self, obj, method, name=None) -> None: if name is None: name = method.__name__ self.object = obj @@ -265,7 +265,7 @@ class MethodWrapper: # is not needed, the remaining bit is now used inline in AddMethod. -def AddMethod(obj, function, name=None): +def AddMethod(obj, function, name=None) -> None: """Add a method to an object. Adds *function* to *obj* if *obj* is a class object. diff --git a/SCons/Util/hashes.py b/SCons/Util/hashes.py index b97cd4d..e14da01 100644 --- a/SCons/Util/hashes.py +++ b/SCons/Util/hashes.py @@ -314,7 +314,7 @@ def hash_signature(s, hash_format=None): return m.hexdigest() -def hash_file_signature(fname, chunksize=65536, hash_format=None): +def hash_file_signature(fname, chunksize: int=65536, hash_format=None): """ Generate the md5 signature of a file @@ -358,7 +358,7 @@ def hash_collect(signatures, hash_format=None): _MD5_WARNING_SHOWN = False -def _show_md5_warning(function_name): +def _show_md5_warning(function_name) -> None: """Shows a deprecation warning for various MD5 functions.""" global _MD5_WARNING_SHOWN @@ -380,7 +380,7 @@ def MD5signature(s): return hash_signature(s) -def MD5filesignature(fname, chunksize=65536): +def MD5filesignature(fname, chunksize: int=65536): """Deprecated. Use :func:`hash_file_signature` instead.""" _show_md5_warning("MD5filesignature") diff --git a/SCons/Util/types.py b/SCons/Util/types.py index 2071217..44aae5f 100644 --- a/SCons/Util/types.py +++ b/SCons/Util/types.py @@ -115,16 +115,16 @@ class Null: cls._instance = super(Null, cls).__new__(cls, *args, **kwargs) return cls._instance - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: pass def __call__(self, *args, **kwargs): return self - def __repr__(self): + def __repr__(self) -> str: return f"Null(0x{id(self):08X})" - def __bool__(self): + def __bool__(self) -> bool: return False def __getattr__(self, name): @@ -140,7 +140,7 @@ class Null: class NullSeq(Null): """A Null object that can also be iterated over.""" - def __len__(self): + def __len__(self) -> int: return 0 def __iter__(self): @@ -245,7 +245,7 @@ def to_String_for_signature( # pylint: disable=redefined-outer-name,redefined-b return f() -def get_env_bool(env, name, default=False) -> bool: +def get_env_bool(env, name, default: bool=False) -> bool: """Convert a construction variable to bool. If the value of *name* in *env* is 'true', 'yes', 'y', 'on' (case @@ -279,7 +279,7 @@ def get_env_bool(env, name, default=False) -> bool: return default -def get_os_env_bool(name, default=False) -> bool: +def get_os_env_bool(name, default: bool=False) -> bool: """Convert an environment variable to bool. Conversion is the same as for :func:`get_env_bool`. diff --git a/SCons/UtilTests.py b/SCons/UtilTests.py index 785caf7..860724e 100644 --- a/SCons/UtilTests.py +++ b/SCons/UtilTests.py @@ -84,15 +84,15 @@ from SCons.Util.hashes import ( class OutBuffer: - def __init__(self): + def __init__(self) -> None: self.buffer = "" - def write(self, str): + def write(self, str) -> None: self.buffer = self.buffer + str class dictifyTestCase(unittest.TestCase): - def test_dictify(self): + def test_dictify(self) -> None: """Test the dictify() function""" r = dictify(['a', 'b', 'c'], [1, 2, 3]) assert r == {'a': 1, 'b': 2, 'c': 3}, r @@ -105,45 +105,45 @@ class dictifyTestCase(unittest.TestCase): class UtilTestCase(unittest.TestCase): - def test_splitext(self): + def test_splitext(self) -> None: assert splitext('foo') == ('foo', '') assert splitext('foo.bar') == ('foo', '.bar') assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'), '') class Node: - def __init__(self, name, children=[]): + def __init__(self, name, children=[]) -> None: self.children = children self.name = name self.nocache = None - def __str__(self): + def __str__(self) -> str: return self.name - def exists(self): + def exists(self) -> int: return 1 - def rexists(self): + def rexists(self) -> int: return 1 - def has_builder(self): + def has_builder(self) -> int: return 1 - def has_explicit_builder(self): + def has_explicit_builder(self) -> int: return 1 - def side_effect(self): + def side_effect(self) -> int: return 1 - def precious(self): + def precious(self) -> int: return 1 - def always_build(self): + def always_build(self) -> int: return 1 - def is_up_to_date(self): + def is_up_to_date(self) -> int: return 1 - def noclean(self): + def noclean(self) -> int: return 1 def tree_case_1(self): @@ -174,7 +174,7 @@ class UtilTestCase(unittest.TestCase): return foo, expect, withtags - def tree_case_2(self, prune=1): + def tree_case_2(self, prune: int=1): """Fixture for the render_tree() and print_tree() tests.""" types_h = self.Node('types.h') @@ -209,7 +209,7 @@ class UtilTestCase(unittest.TestCase): return blat_o, expect, withtags - def test_render_tree(self): + def test_render_tree(self) -> None: """Test the render_tree() function""" def get_children(node): @@ -230,7 +230,7 @@ class UtilTestCase(unittest.TestCase): actual = render_tree(node, get_children, 1) assert expect == actual, (expect, actual) - def test_print_tree(self): + def test_print_tree(self) -> None: """Test the print_tree() function""" def get_children(node): @@ -290,7 +290,7 @@ class UtilTestCase(unittest.TestCase): finally: sys.stdout = save_stdout - def test_is_Dict(self): + def test_is_Dict(self) -> None: assert is_Dict({}) assert is_Dict(UserDict()) try: @@ -305,7 +305,7 @@ class UtilTestCase(unittest.TestCase): assert not is_Dict("") - def test_is_List(self): + def test_is_List(self) -> None: assert is_List([]) assert is_List(UserList()) try: @@ -319,7 +319,7 @@ class UtilTestCase(unittest.TestCase): assert not is_List({}) assert not is_List("") - def test_is_String(self): + def test_is_String(self) -> None: assert is_String("") assert is_String(UserString('')) try: @@ -333,7 +333,7 @@ class UtilTestCase(unittest.TestCase): assert not is_String([]) assert not is_String(()) - def test_is_Tuple(self): + def test_is_Tuple(self) -> None: assert is_Tuple(()) try: class mytuple(tuple): @@ -346,13 +346,13 @@ class UtilTestCase(unittest.TestCase): assert not is_Tuple({}) assert not is_Tuple("") - def test_to_Bytes(self): + def test_to_Bytes(self) -> None: """ Test the to_Bytes method""" self.assertEqual(to_bytes('Hello'), bytearray('Hello', 'utf-8'), "Check that to_bytes creates byte array when presented with non byte string.") - def test_to_String(self): + def test_to_String(self) -> None: """Test the to_String() method.""" assert to_String(1) == "1", to_String(1) assert to_String([1, 2, 3]) == str([1, 2, 3]), to_String([1, 2, 3]) @@ -374,7 +374,7 @@ class UtilTestCase(unittest.TestCase): assert to_String(s2) == 'foo', s2 - def test_WhereIs(self): + def test_WhereIs(self) -> None: test = TestCmd.TestCmd(workdir='') sub1_xxx_exe = test.workpath('sub1', 'xxx.exe') @@ -454,7 +454,7 @@ class UtilTestCase(unittest.TestCase): finally: os.environ['PATH'] = env_path - def test_get_env_var(self): + def test_get_env_var(self) -> None: """Testing get_environment_var().""" assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO") assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}") @@ -467,21 +467,21 @@ class UtilTestCase(unittest.TestCase): assert get_environment_var("${some('complex expression')}") is None, get_environment_var( "${some('complex expression')}") - def test_Proxy(self): + def test_Proxy(self) -> None: """Test generic Proxy class.""" class Subject: - def foo(self): + def foo(self) -> int: return 1 - def bar(self): + def bar(self) -> int: return 2 s = Subject() s.baz = 3 class ProxyTest(Proxy): - def bar(self): + def bar(self) -> int: return 4 p = ProxyTest(s) @@ -496,7 +496,7 @@ class UtilTestCase(unittest.TestCase): assert p.baz == 5, p.baz assert p.get() == s, p.get() - def test_display(self): + def test_display(self) -> None: old_stdout = sys.stdout sys.stdout = OutBuffer() display("line1") @@ -512,7 +512,7 @@ class UtilTestCase(unittest.TestCase): assert sys.stdout.buffer == "line1\nline3\nline4\n" sys.stdout = old_stdout - def test_get_native_path(self): + def test_get_native_path(self) -> None: """Test the get_native_path() function.""" import tempfile f, filename = tempfile.mkstemp(text=True) @@ -529,7 +529,7 @@ class UtilTestCase(unittest.TestCase): except OSError: pass - def test_PrependPath(self): + def test_PrependPath(self) -> None: """Test prepending to a path""" p1 = r'C:\dir\num\one;C:\dir\num\two' p2 = r'C:\mydir\num\one;C:\mydir\num\two' @@ -547,7 +547,7 @@ class UtilTestCase(unittest.TestCase): p3 = PrependPath(p3, r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\two', sep=';') assert p3 == r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\one', p3 - def test_AppendPath(self): + def test_AppendPath(self) -> None: """Test appending to a path.""" p1 = r'C:\dir\num\one;C:\dir\num\two' p2 = r'C:\mydir\num\one;C:\mydir\num\two' @@ -565,7 +565,7 @@ class UtilTestCase(unittest.TestCase): p3 = AppendPath(p3, r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\two', sep=';') assert p3 == r'C:\dir\num\one;C:\dir\num\three;C:\dir\num\two', p3 - def test_PrependPathPreserveOld(self): + def test_PrependPathPreserveOld(self) -> None: """Test prepending to a path while preserving old paths""" p1 = r'C:\dir\num\one;C:\dir\num\two' # have to include the pathsep here so that the test will work on UNIX too. @@ -573,7 +573,7 @@ class UtilTestCase(unittest.TestCase): p1 = PrependPath(p1, r'C:\dir\num\three', sep=';') assert p1 == r'C:\dir\num\three;C:\dir\num\one;C:\dir\num\two', p1 - def test_AppendPathPreserveOld(self): + def test_AppendPathPreserveOld(self) -> None: """Test appending to a path while preserving old paths""" p1 = r'C:\dir\num\one;C:\dir\num\two' # have to include the pathsep here so that the test will work on UNIX too. @@ -581,7 +581,7 @@ class UtilTestCase(unittest.TestCase): p1 = AppendPath(p1, r'C:\dir\num\three', sep=';') assert p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three', p1 - def test_addPathIfNotExists(self): + def test_addPathIfNotExists(self) -> None: """Test the AddPathIfNotExists() function""" env_dict = {'FOO': os.path.normpath('/foo/bar') + os.pathsep + \ os.path.normpath('/baz/blat'), @@ -605,7 +605,7 @@ class UtilTestCase(unittest.TestCase): os.path.normpath('/foo/bar'), os.path.normpath('/baz/blat')], env_dict['BLAT'] - def test_CLVar(self): + def test_CLVar(self) -> None: """Test the command-line construction variable class""" # the default value should be an empty list @@ -728,14 +728,14 @@ class UtilTestCase(unittest.TestCase): assert str(f) == 'aa bb cc dd', str(f) - def test_Selector(self): + def test_Selector(self) -> None: """Test the Selector class""" class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def get_suffix(self): @@ -782,7 +782,7 @@ class UtilTestCase(unittest.TestCase): ret = s(env, [MyNode('bar.g')]) assert ret == 'GGG', ret - def test_adjustixes(self): + def test_adjustixes(self) -> None: """Test the adjustixes() function""" r = adjustixes('file', 'pre-', '-suf') assert r == 'pre-file-suf', r @@ -802,22 +802,22 @@ class UtilTestCase(unittest.TestCase): r = adjustixes('PREFIX', 'PREFIX', 'SUFFIX') assert r == 'PREFIXPREFIXSUFFIX', "Failed handling when filename = PREFIX [r='%s']" % r - def test_containsAny(self): + def test_containsAny(self) -> None: """Test the containsAny() function""" assert containsAny('*.py', '*?[]') assert not containsAny('file.txt', '*?[]') - def test_containsAll(self): + def test_containsAll(self) -> None: """Test the containsAll() function""" assert containsAll('43221', '123') assert not containsAll('134', '123') - def test_containsOnly(self): + def test_containsOnly(self) -> None: """Test the containsOnly() function""" assert containsOnly('.83', '0123456789.') assert not containsOnly('43221', '123') - def test_LogicalLines(self): + def test_LogicalLines(self) -> None: """Test the LogicalLines class""" content = """ foo \\ @@ -838,7 +838,7 @@ bling 'bling\n', ], lines - def test_intern(self): + def test_intern(self) -> None: s1 = silent_intern("spam") s3 = silent_intern(42) s4 = silent_intern("spam") @@ -847,7 +847,7 @@ bling class HashTestCase(unittest.TestCase): - def test_collect(self): + def test_collect(self) -> None: """Test collecting a list of signatures into a new signature value """ for algorithm, expected in { @@ -873,7 +873,7 @@ class HashTestCase(unittest.TestCase): assert expected[1] == hash_collect(s[0:2], hash_format=algorithm) assert expected[2] == hash_collect(s, hash_format=algorithm) - def test_MD5signature(self): + def test_MD5signature(self) -> None: """Test generating a signature""" for algorithm, expected in { 'md5': ('698d51a19d8a121ce581499d7b701668', @@ -900,7 +900,7 @@ class HashTestCase(unittest.TestCase): # with using OpenSSL. class FIPSHashTestCase(unittest.TestCase): - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) ############################### @@ -958,17 +958,17 @@ class FIPSHashTestCase(unittest.TestCase): self.sys_v4_8 = unittest.mock.Mock(version_info=v4_8) ############################### - def test_basic_failover_bad_hashlib_hash_init(self): + def test_basic_failover_bad_hashlib_hash_init(self) -> None: """Tests that if the hashing function is entirely missing from hashlib (hashlib returns None), the hash init function returns None""" assert _attempt_init_of_python_3_9_hash_object(None) is None - def test_basic_failover_bad_hashlib_hash_get(self): + def test_basic_failover_bad_hashlib_hash_get(self) -> None: """Tests that if the hashing function is entirely missing from hashlib (hashlib returns None), the hash get function returns None""" assert _attempt_get_hash_function("nonexist", self.no_algorithms) is None - def test_usedforsecurity_flag_behavior(self): + def test_usedforsecurity_flag_behavior(self) -> None: """Test usedforsecurity flag -> should be set to 'True' on older versions of python, and 'False' on Python >= 3.9""" for version, expected in { self.sys_v3_8: (True, 'md5'), @@ -977,7 +977,7 @@ class FIPSHashTestCase(unittest.TestCase): }.items(): assert _attempt_init_of_python_3_9_hash_object(self.fake_md5, version) == expected - def test_automatic_default_to_md5(self): + def test_automatic_default_to_md5(self) -> None: """Test automatic default to md5 even if sha1 available""" for version, expected in { self.sys_v3_8: (True, 'md5'), @@ -988,7 +988,7 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.md5Default, version) assert _get_hash_object(None, self.md5Default, version) == expected - def test_automatic_default_to_sha256(self): + def test_automatic_default_to_sha256(self) -> None: """Test automatic default to sha256 if other algorithms available but throw""" for version, expected in { self.sys_v3_8: (True, 'sha256'), @@ -999,7 +999,7 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.sha256Default, version) assert _get_hash_object(None, self.sha256Default, version) == expected - def test_automatic_default_to_sha1(self): + def test_automatic_default_to_sha1(self) -> None: """Test automatic default to sha1 if md5 is missing from hashlib entirely""" for version, expected in { self.sys_v3_8: (True, 'sha1'), @@ -1010,13 +1010,13 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.sha1Default, version) assert _get_hash_object(None, self.sha1Default, version) == expected - def test_no_available_algorithms(self): + def test_no_available_algorithms(self) -> None: """expect exceptions on no available algorithms or when all algorithms throw""" self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.no_algorithms) self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.all_throw) self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.unsupported_algorithm) - def test_bad_algorithm_set_attempt(self): + def test_bad_algorithm_set_attempt(self) -> None: """expect exceptions on user setting an unsupported algorithm selections, either by host or by SCons""" # nonexistant hash algorithm, not supported by SCons @@ -1035,18 +1035,18 @@ class FIPSHashTestCase(unittest.TestCase): _set_allowed_viable_default_hashes(self.sha1Default) self.assertRaises(SCons.Errors.UserError, set_hash_format, 'unsupported', hashlib_used=self.unsupported_algorithm) - def tearDown(self): + def tearDown(self) -> None: """Return SCons back to the normal global state for the hashing functions.""" _set_allowed_viable_default_hashes(hashlib, sys) set_hash_format(None) class NodeListTestCase(unittest.TestCase): - def test_simple_attributes(self): + def test_simple_attributes(self) -> None: """Test simple attributes of a NodeList class""" class TestClass: - def __init__(self, name, child=None): + def __init__(self, name, child=None) -> None: self.child = child self.bar = name @@ -1059,11 +1059,11 @@ class NodeListTestCase(unittest.TestCase): assert nl[0:2].child.bar == ['t1child', 't2child'], \ nl[0:2].child.bar - def test_callable_attributes(self): + def test_callable_attributes(self) -> None: """Test callable attributes of a NodeList class""" class TestClass: - def __init__(self, name, child=None): + def __init__(self, name, child=None) -> None: self.child = child self.bar = name @@ -1097,12 +1097,12 @@ class NodeListTestCase(unittest.TestCase): class flattenTestCase(unittest.TestCase): - def test_scalar(self): + def test_scalar(self) -> None: """Test flattening a scalar""" result = flatten('xyz') self.assertEqual(result, ['xyz'], result) - def test_dictionary_values(self): + def test_dictionary_values(self) -> None: """Test flattening the dictionary values""" items = {"a": 1, "b": 2, "c": 3} result = flatten(items.values()) @@ -1112,14 +1112,14 @@ class flattenTestCase(unittest.TestCase): class OsEnviron: """Used to temporarily mock os.environ""" - def __init__(self, environ): + def __init__(self, environ) -> None: self._environ = environ - def start(self): + def start(self) -> None: self._stored = os.environ os.environ = self._environ - def stop(self): + def stop(self) -> None: os.environ = self._stored del self._stored @@ -1127,12 +1127,12 @@ class OsEnviron: self.start() return os.environ - def __exit__(self, *args): + def __exit__(self, *args) -> None: self.stop() class get_env_boolTestCase(unittest.TestCase): - def test_missing(self): + def test_missing(self) -> None: env = dict() var = get_env_bool(env, 'FOO') assert var is False, "var should be False, not %s" % repr(var) @@ -1140,7 +1140,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'BAR') assert var is False, "var should be False, not %s" % repr(var) - def test_true(self): + def test_true(self) -> None: for foo in ['TRUE', 'True', 'true', 'YES', 'Yes', 'yes', 'Y', 'y', @@ -1150,7 +1150,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'FOO') assert var is True, 'var should be True, not %s' % repr(var) - def test_false(self): + def test_false(self) -> None: for foo in ['FALSE', 'False', 'false', 'NO', 'No', 'no', 'N', 'n', @@ -1160,7 +1160,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'FOO', True) assert var is False, 'var should be True, not %s' % repr(var) - def test_default(self): + def test_default(self) -> None: env = {'FOO': 'other'} var = get_env_bool(env, 'FOO', True) assert var is True, 'var should be True, not %s' % repr(var) @@ -1169,7 +1169,7 @@ class get_env_boolTestCase(unittest.TestCase): class get_os_env_boolTestCase(unittest.TestCase): - def test_missing(self): + def test_missing(self) -> None: with OsEnviron(dict()): var = get_os_env_bool('FOO') assert var is False, "var should be False, not %s" % repr(var) @@ -1177,7 +1177,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('BAR') assert var is False, "var should be False, not %s" % repr(var) - def test_true(self): + def test_true(self) -> None: for foo in ['TRUE', 'True', 'true', 'YES', 'Yes', 'yes', 'Y', 'y', @@ -1187,7 +1187,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('FOO') assert var is True, 'var should be True, not %s' % repr(var) - def test_false(self): + def test_false(self) -> None: for foo in ['FALSE', 'False', 'false', 'NO', 'No', 'no', 'N', 'n', @@ -1197,7 +1197,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('FOO', True) assert var is False, 'var should be True, not %s' % repr(var) - def test_default(self): + def test_default(self) -> None: with OsEnviron({'FOO': 'other'}): var = get_os_env_bool('FOO', True) assert var is True, 'var should be True, not %s' % repr(var) diff --git a/SCons/Utilities/ConfigureCache.py b/SCons/Utilities/ConfigureCache.py index 67aac3c..f0de77b 100644 --- a/SCons/Utilities/ConfigureCache.py +++ b/SCons/Utilities/ConfigureCache.py @@ -38,7 +38,7 @@ import glob import json import os -def rearrange_cache_entries(current_prefix_len, new_prefix_len): +def rearrange_cache_entries(current_prefix_len, new_prefix_len) -> None: """Move cache files if prefix length changed. Move the existing cache files to new directories of the diff --git a/SCons/Utilities/sconsign.py b/SCons/Utilities/sconsign.py index ae69196..c12782d 100644 --- a/SCons/Utilities/sconsign.py +++ b/SCons/Utilities/sconsign.py @@ -72,7 +72,7 @@ def my_import(mname): class Flagger: default_value = 1 - def __setitem__(self, item, value): + def __setitem__(self, item, value) -> None: self.__dict__[item] = value self.default_value = 0 @@ -201,7 +201,7 @@ def field(name, entry, verbose=Verbose): return val -def nodeinfo_raw(name, ninfo, prefix=""): +def nodeinfo_raw(name, ninfo, prefix: str=""): """ This just formats the dictionary, which we would normally use str() to do, except that we want the keys sorted for deterministic output. @@ -219,7 +219,7 @@ def nodeinfo_raw(name, ninfo, prefix=""): return name + ': {' + ', '.join(values) + '}' -def nodeinfo_cooked(name, ninfo, prefix=""): +def nodeinfo_cooked(name, ninfo, prefix: str=""): try: field_list = ninfo.field_list except AttributeError: @@ -239,7 +239,7 @@ def nodeinfo_cooked(name, ninfo, prefix=""): nodeinfo_string = nodeinfo_cooked -def printfield(name, entry, prefix=""): +def printfield(name, entry, prefix: str="") -> None: outlist = field("implicit", entry, 0) if outlist: if Verbose: @@ -253,7 +253,7 @@ def printfield(name, entry, prefix=""): print(" " + outact) -def printentries(entries, location): +def printentries(entries, location) -> None: if Print_Entries: for name in Print_Entries: try: @@ -282,7 +282,7 @@ def printentries(entries, location): class Do_SConsignDB: - def __init__(self, dbm_name, dbm): + def __init__(self, dbm_name, dbm) -> None: self.dbm_name = dbm_name self.dbm = dbm @@ -346,7 +346,7 @@ class Do_SConsignDB: self.printentries(dir, db[dir]) @staticmethod - def printentries(dir, val): + def printentries(dir, val) -> None: try: print('=== ' + dir + ':') except TypeError: @@ -376,7 +376,7 @@ def Do_SConsignDir(name): ############################################################################## -def main(): +def main() -> None: global Do_Call global nodeinfo_string global args diff --git a/SCons/Variables/BoolVariableTests.py b/SCons/Variables/BoolVariableTests.py index 868e7e0..9cf3ae1 100644 --- a/SCons/Variables/BoolVariableTests.py +++ b/SCons/Variables/BoolVariableTests.py @@ -27,7 +27,7 @@ import SCons.Errors import SCons.Variables class BoolVariableTestCase(unittest.TestCase): - def test_BoolVariable(self): + def test_BoolVariable(self) -> None: """Test BoolVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) @@ -39,7 +39,7 @@ class BoolVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the BoolVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) @@ -80,7 +80,7 @@ class BoolVariableTestCase(unittest.TestCase): caught = True assert caught, "did not catch expected ValueError for 'x'" - def test_validator(self): + def test_validator(self) -> None: """Test the BoolVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) diff --git a/SCons/Variables/EnumVariable.py b/SCons/Variables/EnumVariable.py index e39eb02..1a4f3fb 100644 --- a/SCons/Variables/EnumVariable.py +++ b/SCons/Variables/EnumVariable.py @@ -56,7 +56,7 @@ def _validator(key, val, env, vals) -> None: 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals)) -def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0) -> Tuple[str, str, str, Callable, Callable]: +def EnumVariable(key, help, default, allowed_values, map={}, ignorecase: int=0) -> Tuple[str, str, str, Callable, Callable]: """Return a tuple describing an enumaration SCons Variable. The input parameters describe an option with only certain values diff --git a/SCons/Variables/EnumVariableTests.py b/SCons/Variables/EnumVariableTests.py index 75bb54f..cc004f8 100644 --- a/SCons/Variables/EnumVariableTests.py +++ b/SCons/Variables/EnumVariableTests.py @@ -27,7 +27,7 @@ import SCons.Errors import SCons.Variables class EnumVariableTestCase(unittest.TestCase): - def test_EnumVariable(self): + def test_EnumVariable(self) -> None: """Test EnumVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, @@ -41,7 +41,7 @@ class EnumVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the EnumVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, @@ -127,7 +127,7 @@ class EnumVariableTestCase(unittest.TestCase): x = o2.converter(k) assert x == l[2], "o2 got %s, expected %s" % (x, l[2]) - def test_validator(self): + def test_validator(self) -> None: """Test the EnumVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test0', 'test option help', 0, @@ -153,10 +153,10 @@ class EnumVariableTestCase(unittest.TestCase): o1 = opts.options[1] o2 = opts.options[2] - def valid(o, v): + def valid(o, v) -> None: o.validator('X', v, {}) - def invalid(o, v): + def invalid(o, v) -> None: caught = None try: o.validator('X', v, {}) diff --git a/SCons/Variables/ListVariable.py b/SCons/Variables/ListVariable.py index 7bd6053..bfa48f5 100644 --- a/SCons/Variables/ListVariable.py +++ b/SCons/Variables/ListVariable.py @@ -61,7 +61,7 @@ __all__ = ['ListVariable',] class _ListVariable(collections.UserList): - def __init__(self, initlist=None, allowedElems=None): + def __init__(self, initlist=None, allowedElems=None) -> None: if initlist is None: initlist = [] if allowedElems is None: @@ -87,7 +87,7 @@ class _ListVariable(collections.UserList): def __lt__(self, other): raise NotImplementedError - def __str__(self): + def __str__(self) -> str: if not len(self): return 'none' self.data.sort() diff --git a/SCons/Variables/ListVariableTests.py b/SCons/Variables/ListVariableTests.py index c73cef3..172a54f 100644 --- a/SCons/Variables/ListVariableTests.py +++ b/SCons/Variables/ListVariableTests.py @@ -28,7 +28,7 @@ import SCons.Errors import SCons.Variables class ListVariableTestCase(unittest.TestCase): - def test_ListVariable(self): + def test_ListVariable(self) -> None: """Test ListVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', @@ -49,7 +49,7 @@ class ListVariableTestCase(unittest.TestCase): o = opts.options[0] assert o.default == 'one,three' - def test_converter(self): + def test_converter(self) -> None: """Test the ListVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', @@ -108,7 +108,7 @@ class ListVariableTestCase(unittest.TestCase): caught = 1 assert caught, "did not catch expected ValueError" - def test_copy(self): + def test_copy(self) -> None: """Test copying a ListVariable like an Environment would""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', diff --git a/SCons/Variables/PackageVariableTests.py b/SCons/Variables/PackageVariableTests.py index 988fbe0..ad5ba06 100644 --- a/SCons/Variables/PackageVariableTests.py +++ b/SCons/Variables/PackageVariableTests.py @@ -29,7 +29,7 @@ import SCons.Variables import TestCmd class PackageVariableTestCase(unittest.TestCase): - def test_PackageVariable(self): + def test_PackageVariable(self) -> None: """Test PackageVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) @@ -41,7 +41,7 @@ class PackageVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the PackageVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) @@ -82,7 +82,7 @@ class PackageVariableTestCase(unittest.TestCase): x = o.converter(str(False)) assert not x, "converter returned a string when given str(False)" - def test_validator(self): + def test_validator(self) -> None: """Test the PackageVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) diff --git a/SCons/Variables/PathVariableTests.py b/SCons/Variables/PathVariableTests.py index a9aa8f0..aacfc9e 100644 --- a/SCons/Variables/PathVariableTests.py +++ b/SCons/Variables/PathVariableTests.py @@ -30,7 +30,7 @@ import SCons.Variables import TestCmd class PathVariableTestCase(unittest.TestCase): - def test_PathVariable(self): + def test_PathVariable(self) -> None: """Test PathVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PathVariable('test', @@ -164,7 +164,7 @@ class PathVariableTestCase(unittest.TestCase): except: raise Exception("did not catch expected UserError") - def test_PathAccept(self): + def test_PathAccept(self) -> None: """Test the PathAccept validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PathVariable('test', diff --git a/SCons/Variables/VariablesTests.py b/SCons/Variables/VariablesTests.py index 4672cdd..fcc1e14 100644 --- a/SCons/Variables/VariablesTests.py +++ b/SCons/Variables/VariablesTests.py @@ -32,24 +32,24 @@ from SCons.Util import cmp class Environment: - def __init__(self): + def __init__(self) -> None: self.dict = {} def subst(self, x): return SCons.Subst.scons_subst(x, self, gvars=self.dict) - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dict[key] = value def __getitem__(self, key): return self.dict[key] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict -def check(key, value, env): +def check(key, value, env) -> None: assert int(value) == 6 * 9, "key %s = %s" % (key, repr(value)) # Check saved option file by executing and comparing against # the expected dictionary -def checkSave(file, expected): +def checkSave(file, expected) -> None: gdict = {} ldict = {} with open(file, 'r') as f: @@ -59,7 +59,7 @@ def checkSave(file, expected): class VariablesTestCase(unittest.TestCase): - def test_keys(self): + def test_keys(self) -> None: """Test the Variables.keys() method""" opts = SCons.Variables.Variables() @@ -72,7 +72,7 @@ class VariablesTestCase(unittest.TestCase): keys = list(opts.keys()) assert keys == ['VAR1', 'VAR2'], keys - def test_Add(self): + def test_Add(self) -> None: """Test adding to a Variables object""" opts = SCons.Variables.Variables() @@ -96,7 +96,7 @@ class VariablesTestCase(unittest.TestCase): assert o.default == "42" o.validator(o.key, o.converter(o.default), {}) - def test_it(var, opts=opts): + def test_it(var, opts=opts) -> None: exc_caught = None try: opts.Add(var) @@ -107,7 +107,7 @@ class VariablesTestCase(unittest.TestCase): test_it('foo-bar') test_it('foo.bar') - def test_AddVariables(self): + def test_AddVariables(self) -> None: """Test adding a list of options to a Variables object""" opts = SCons.Variables.Variables() @@ -131,7 +131,7 @@ class VariablesTestCase(unittest.TestCase): assert o.default == "42", o.default o.validator(o.key, o.converter(o.default), {}) - def test_Update(self): + def test_Update(self) -> None: """Test updating an Environment""" # Test that a default value is validated correctly. @@ -270,7 +270,7 @@ class VariablesTestCase(unittest.TestCase): opts.Update(env, {}) assert 'ANSWER' not in env - def test_noaggregation(self): + def test_noaggregation(self) -> None: """Test that the 'files' and 'args' attributes of the Variables class don't aggregate entries from one instance to another. This used to be a bug in SCons version 2.4.1 and earlier. @@ -286,7 +286,7 @@ class VariablesTestCase(unittest.TestCase): assert len(nopts.files) == 0 assert len(nopts.args) == 0 - def test_args(self): + def test_args(self) -> None: """Test updating an Environment with arguments overridden""" # Test that a bad (command-line) argument is used @@ -343,7 +343,7 @@ class VariablesTestCase(unittest.TestCase): opts.Update(env, {'ANSWER':42}) assert env['ANSWER'] == 54 - def test_Save(self): + def test_Save(self) -> None: """Testing saving Variables""" test = TestSCons.TestSCons() @@ -396,9 +396,9 @@ class VariablesTestCase(unittest.TestCase): # Test against some old bugs class Foo: - def __init__(self, x): + def __init__(self, x) -> None: self.x = x - def __str__(self): + def __str__(self) -> str: return self.x test = TestSCons.TestSCons() @@ -426,7 +426,7 @@ class VariablesTestCase(unittest.TestCase): 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", 'THIS_SHOULD_WORK' : 'baz' }) - def test_GenerateHelpText(self): + def test_GenerateHelpText(self) -> None: """Test generating the default format help text""" opts = SCons.Variables.Variables() @@ -507,11 +507,11 @@ A: a - alpha test expectBackwards, ) - def test_FormatVariableHelpText(self): + def test_FormatVariableHelpText(self) -> None: """Test generating custom format help text""" opts = SCons.Variables.Variables() - def my_format(env, opt, help, default, actual, aliases): + def my_format(env, opt, help, default, actual, aliases) -> str: return '%s %s %s %s %s\n' % (opt, default, actual, help, aliases) opts.FormatVariableHelpText = my_format @@ -554,7 +554,7 @@ B 42 54 b - alpha test ['B'] text = opts.GenerateHelpText(env, sort=cmp) assert text == expectAlpha, text - def test_Aliases(self): + def test_Aliases(self) -> None: """Test option aliases""" # test alias as a tuple opts = SCons.Variables.Variables() @@ -595,7 +595,7 @@ B 42 54 b - alpha test ['B'] class UnknownVariablesTestCase(unittest.TestCase): - def test_unknown(self): + def test_unknown(self) -> None: """Test the UnknownVariables() method""" opts = SCons.Variables.Variables() @@ -615,7 +615,7 @@ class UnknownVariablesTestCase(unittest.TestCase): assert r == {'UNKNOWN' : 'unknown'}, r assert env['ANSWER'] == 'answer', env['ANSWER'] - def test_AddOptionUpdatesUnknown(self): + def test_AddOptionUpdatesUnknown(self) -> None: """Test updating of the 'unknown' dict""" opts = SCons.Variables.Variables() @@ -650,7 +650,7 @@ class UnknownVariablesTestCase(unittest.TestCase): assert len(r) == 0, r assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] - def test_AddOptionWithAliasUpdatesUnknown(self): + def test_AddOptionWithAliasUpdatesUnknown(self) -> None: """Test updating of the 'unknown' dict (with aliases)""" opts = SCons.Variables.Variables() diff --git a/SCons/Variables/__init__.py b/SCons/Variables/__init__.py index fc78de5..4d40986 100644 --- a/SCons/Variables/__init__.py +++ b/SCons/Variables/__init__.py @@ -57,7 +57,7 @@ class Variables: """ instance = None - def __init__(self, files=None, args=None, is_global=True): + def __init__(self, files=None, args=None, is_global: bool=True) -> None: if args is None: args = {} self.options = [] @@ -76,7 +76,7 @@ class Variables: if not Variables.instance: Variables.instance=self - def _do_add(self, key, help="", default=None, validator=None, converter=None, **kwargs) -> None: + def _do_add(self, key, help: str="", default=None, validator=None, converter=None, **kwargs) -> None: class Variable: pass diff --git a/SCons/Warnings.py b/SCons/Warnings.py index f77a24a..5c2a0db 100644 --- a/SCons/Warnings.py +++ b/SCons/Warnings.py @@ -144,15 +144,15 @@ _warningAsException = False # If not None, a function to call with the warning _warningOut = None -def suppressWarningClass(clazz): +def suppressWarningClass(clazz) -> None: """Suppresses all warnings of type clazz or derived from clazz.""" _enabled.insert(0, (clazz, False)) -def enableWarningClass(clazz): +def enableWarningClass(clazz) -> None: """Enables all warnings of type clazz or derived from clazz.""" _enabled.insert(0, (clazz, True)) -def warningAsException(flag=True): +def warningAsException(flag: bool=True): """Set global _warningAsExeption flag. Args: @@ -185,7 +185,7 @@ def warn(clazz, *args): _warningOut(warning) break -def process_warn_strings(arguments): +def process_warn_strings(arguments) -> None: """Process requests to enable/disable warnings. The requests are strings passed to the --warn option or the diff --git a/SCons/WarningsTests.py b/SCons/WarningsTests.py index c22b049..85dbb6e 100644 --- a/SCons/WarningsTests.py +++ b/SCons/WarningsTests.py @@ -26,14 +26,14 @@ import unittest import SCons.Warnings class TestOutput: - def __call__(self, x): + def __call__(self, x) -> None: args = x.args[0] if len(args) == 1: args = args[0] self.out = str(args) class WarningsTestCase(unittest.TestCase): - def test_Warning(self): + def test_Warning(self) -> None: """Test warn function.""" # Reset global state @@ -50,7 +50,7 @@ class WarningsTestCase(unittest.TestCase): "Foo", 1) assert to.out == "('Foo', 1)", to.out - def test_WarningAsExc(self): + def test_WarningAsExc(self) -> None: """Test warnings as exceptions.""" # Reset global state @@ -76,7 +76,7 @@ class WarningsTestCase(unittest.TestCase): exc_caught = 1 assert exc_caught == 0 - def test_Disable(self): + def test_Disable(self) -> None: """Test disabling/enabling warnings.""" # Reset global state diff --git a/SCons/compat/__init__.py b/SCons/compat/__init__.py index 03b12af..2174f38 100644 --- a/SCons/compat/__init__.py +++ b/SCons/compat/__init__.py @@ -64,7 +64,7 @@ import importlib PYPY = hasattr(sys, 'pypy_translation_info') -def rename_module(new, old): +def rename_module(new, old) -> bool: """ Attempt to import the old module and load it under the new name. Used for purely cosmetic name changes in Python 3.x. diff --git a/SCons/cpp.py b/SCons/cpp.py index 144f498..c9c9a70 100644 --- a/SCons/cpp.py +++ b/SCons/cpp.py @@ -180,7 +180,7 @@ del override class FunctionEvaluator: """Handles delayed evaluation of a #define function call.""" - def __init__(self, name, args, expansion): + def __init__(self, name, args, expansion) -> None: """ Squirrels away the arguments and expansion value of a #define macro function for later evaluation when we must actually expand @@ -230,7 +230,7 @@ function_arg_separator = re.compile(r',\s*') class PreProcessor: """The main workhorse class for handling C pre-processing.""" - def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0, depth=-1): + def __init__(self, current=os.curdir, cpppath=(), dict={}, all: int=0, depth=-1) -> None: global Table cpppath = tuple(cpppath) @@ -339,7 +339,7 @@ class PreProcessor: # Dispatch table stack manipulation methods. - def save(self): + def save(self) -> None: """ Pushes the current dispatch table on the stack and re-initializes the current dispatch table to the default. @@ -347,7 +347,7 @@ class PreProcessor: self.stack.append(self.dispatch_table) self.dispatch_table = self.default_table.copy() - def restore(self): + def restore(self) -> None: """ Pops the previous dispatch table off the stack and makes it the current one. @@ -357,14 +357,14 @@ class PreProcessor: # Utility methods. - def do_nothing(self, t): + def do_nothing(self, t) -> None: """ Null method for when we explicitly want the action for a specific preprocessor directive to do nothing. """ pass - def scons_current_file(self, t): + def scons_current_file(self, t) -> None: self.current_file = t[1] def eval_expression(self, t): @@ -381,7 +381,7 @@ class PreProcessor: except (NameError, TypeError, SyntaxError): return 0 - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = [fname] def finalize_result(self, fname): @@ -407,7 +407,7 @@ class PreProcessor: # Start and stop processing include lines. - def start_handling_includes(self, t=None): + def start_handling_includes(self, t=None) -> None: """ Causes the PreProcessor object to start processing #import, #include and #include_next lines. @@ -424,7 +424,7 @@ class PreProcessor: for k in ('import', 'include', 'include_next', 'define', 'undef'): d[k] = p[k] - def stop_handling_includes(self, t=None): + def stop_handling_includes(self, t=None) -> None: """ Causes the PreProcessor object to stop processing #import, #include and #include_next lines. @@ -444,7 +444,7 @@ class PreProcessor: # (Note that what actually gets called for a given directive at any # point in time is really controlled by the dispatch_table.) - def _do_if_else_condition(self, condition): + def _do_if_else_condition(self, condition) -> None: """ Common logic for evaluating the conditions on #if, #ifdef and #ifndef lines. @@ -460,25 +460,25 @@ class PreProcessor: d['elif'] = self.do_elif d['else'] = self.start_handling_includes - def do_ifdef(self, t): + def do_ifdef(self, t) -> None: """ Default handling of a #ifdef line. """ self._do_if_else_condition(t[1] in self.cpp_namespace) - def do_ifndef(self, t): + def do_ifndef(self, t) -> None: """ Default handling of a #ifndef line. """ self._do_if_else_condition(t[1] not in self.cpp_namespace) - def do_if(self, t): + def do_if(self, t) -> None: """ Default handling of a #if line. """ self._do_if_else_condition(self.eval_expression(t)) - def do_elif(self, t): + def do_elif(self, t) -> None: """ Default handling of a #elif line. """ @@ -488,19 +488,19 @@ class PreProcessor: d['elif'] = self.stop_handling_includes d['else'] = self.stop_handling_includes - def do_else(self, t): + def do_else(self, t) -> None: """ Default handling of a #else line. """ pass - def do_endif(self, t): + def do_endif(self, t) -> None: """ Default handling of a #endif line. """ self.restore() - def do_define(self, t): + def do_define(self, t) -> None: """ Default handling of a #define line. """ @@ -519,21 +519,21 @@ class PreProcessor: else: self.cpp_namespace[name] = expansion - def do_undef(self, t): + def do_undef(self, t) -> None: """ Default handling of a #undef line. """ try: del self.cpp_namespace[t[1]] except KeyError: pass - def do_import(self, t): + def do_import(self, t) -> None: """ Default handling of a #import line. """ # XXX finish this -- maybe borrow/share logic from do_include()...? pass - def do_include(self, t): + def do_include(self, t) -> None: """ Default handling of a #include line. """ @@ -614,7 +614,7 @@ class PreProcessor: return None return (t[0], s[0], s[1:-1]) - def all_include(self, t): + def all_include(self, t) -> None: """ """ self.result.append(self.resolve_include(t)) @@ -630,7 +630,7 @@ class DumbPreProcessor(PreProcessor): an example of how the main PreProcessor class can be sub-classed to tailor its behavior. """ - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: PreProcessor.__init__(self, *args, **kw) d = self.default_table for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: diff --git a/SCons/cppTests.py b/SCons/cppTests.py index f781e81..5f00d50 100644 --- a/SCons/cppTests.py +++ b/SCons/cppTests.py @@ -441,89 +441,89 @@ if_no_space_input = """ class cppTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.cpp = self.cpp_class(current = ".", cpppath = ['/usr/include'], dict={"SHELL_ESCAPED_H": '\\"file-shell-computed-yes\\"'}) - def test_basic(self): + def test_basic(self) -> None: """Test basic #include scanning""" expect = self.basic_expect result = self.cpp.process_contents(basic_input) assert expect == result, (expect, result) - def test_substitution(self): + def test_substitution(self) -> None: """Test substitution of #include files using CPP variables""" expect = self.substitution_expect result = self.cpp.process_contents(substitution_input) assert expect == result, (expect, result) - def test_ifdef(self): + def test_ifdef(self) -> None: """Test basic #ifdef processing""" expect = self.ifdef_expect result = self.cpp.process_contents(ifdef_input) assert expect == result, (expect, result) - def test_if_boolean(self): + def test_if_boolean(self) -> None: """Test #if with Boolean values""" expect = self.if_boolean_expect result = self.cpp.process_contents(if_boolean_input) assert expect == result, (expect, result) - def test_if_defined(self): + def test_if_defined(self) -> None: """Test #if defined() idioms""" expect = self.if_defined_expect result = self.cpp.process_contents(if_defined_input) assert expect == result, (expect, result) - def test_expression(self): + def test_expression(self) -> None: """Test #if with arithmetic expressions""" expect = self.expression_expect result = self.cpp.process_contents(expression_input) assert expect == result, (expect, result) - def test_undef(self): + def test_undef(self) -> None: """Test #undef handling""" expect = self.undef_expect result = self.cpp.process_contents(undef_input) assert expect == result, (expect, result) - def test_macro_function(self): + def test_macro_function(self) -> None: """Test using macro functions to express file names""" expect = self.macro_function_expect result = self.cpp.process_contents(macro_function_input) assert expect == result, (expect, result) - def test_token_pasting(self): + def test_token_pasting(self) -> None: """Test token-pasting to construct file names""" expect = self.token_pasting_expect result = self.cpp.process_contents(token_pasting_input) assert expect == result, (expect, result) - def test_no_space(self): + def test_no_space(self) -> None: """Test no space between #include and the quote""" expect = self.no_space_expect result = self.cpp.process_contents(no_space_input) assert expect == result, (expect, result) - def test_nested_ifs(self): + def test_nested_ifs(self) -> None: expect = self.nested_ifs_expect result = self.cpp.process_contents(nested_ifs_input) assert expect == result, (expect, result) - def test_ifndef(self): + def test_ifndef(self) -> None: """Test basic #ifndef processing""" expect = self.ifndef_expect result = self.cpp.process_contents(ifndef_input) assert expect == result, (expect, result) - def test_if_defined_no_space(self): + def test_if_defined_no_space(self) -> None: """Test #if(defined, i.e.without space but parenthesis""" expect = self.if_defined_no_space_expect result = self.cpp.process_contents(if_defined_no_space_input) assert expect == result, (expect, result) - def test_if_no_space(self): + def test_if_no_space(self) -> None: """Test #if(, i.e. without space but parenthesis""" expect = self.if_no_space_expect result = self.cpp.process_contents(if_no_space_input) @@ -531,7 +531,7 @@ class cppTestCase(unittest.TestCase): class cppAllTestCase(cppTestCase): - def setUp(self): + def setUp(self) -> None: self.cpp = self.cpp_class(current = ".", cpppath = ['/usr/include'], dict={"SHELL_ESCAPED_H": '\\"file-shell-computed-yes\\"'}, @@ -792,7 +792,7 @@ import tempfile _Cleanup = [] -def _clean(): +def _clean() -> None: for dir in _Cleanup: if os.path.exists(dir): shutil.rmtree(dir) @@ -807,14 +807,14 @@ else: class fileTestCase(unittest.TestCase): cpp_class = cpp.DumbPreProcessor - def setUp(self): + def setUp(self) -> None: path = tempfile.mkdtemp(prefix=tmpprefix) _Cleanup.append(path) self.tempdir = path self.orig_cwd = os.getcwd() os.chdir(path) - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.orig_cwd) shutil.rmtree(self.tempdir) _Cleanup.remove(self.tempdir) @@ -828,11 +828,11 @@ class fileTestCase(unittest.TestCase): return l return '\n'.join(map(strip_spaces, lines)) - def write(self, file, contents): + def write(self, file, contents) -> None: with open(file, 'w') as f: f.write(self.strip_initial_spaces(contents)) - def test_basic(self): + def test_basic(self) -> None: """Test basic file inclusion""" self.write('f1.h', """\ #include "f2.h" @@ -847,7 +847,7 @@ class fileTestCase(unittest.TestCase): result = p('f1.h') assert result == ['f2.h', 'f3.h'], result - def test_current_file(self): + def test_current_file(self) -> None: """Test use of the .current_file attribute""" self.write('f1.h', """\ #include @@ -858,7 +858,7 @@ class fileTestCase(unittest.TestCase): self.write('f3.h', """\ """) class MyPreProcessor(cpp.DumbPreProcessor): - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.files = [] def __call__(self, file): diff --git a/SCons/dblite.py b/SCons/dblite.py index 9cf975c..dd05f66 100644 --- a/SCons/dblite.py +++ b/SCons/dblite.py @@ -37,7 +37,7 @@ KEEP_ALL_FILES = False IGNORE_CORRUPT_DBFILES = False -def corruption_warning(filename): +def corruption_warning(filename) -> None: """Local warning for corrupt db. Used for self-tests. SCons overwrites this with a @@ -76,7 +76,7 @@ class dblite: _shutil_copyfile = shutil.copyfile _time_time = time.time - def __init__(self, file_base_name, flag, mode): + def __init__(self, file_base_name, flag, mode) -> None: assert flag in (None, "r", "w", "c", "n") if flag is None: flag = "r" @@ -136,14 +136,14 @@ class dblite: else: raise - def close(self): + def close(self) -> None: if self._needs_sync: self.sync() - def __del__(self): + def __del__(self) -> None: self.close() - def sync(self): + def sync(self) -> None: self._check_writable() with self._open(self._tmp_name, "wb", self._mode) as f: self._pickle_dump(self._dict, f, self._pickle_protocol) @@ -197,17 +197,17 @@ class dblite: def keys(self): return list(self._dict.keys()) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self._dict def __iter__(self): return iter(self._dict) - def __len__(self): + def __len__(self) -> int: return len(self._dict) -def open(file, flag=None, mode=0o666): +def open(file, flag=None, mode: int=0o666): return dblite(file, flag, mode) diff --git a/SCons/exitfuncs.py b/SCons/exitfuncs.py index ba6243a..d28bba4 100644 --- a/SCons/exitfuncs.py +++ b/SCons/exitfuncs.py @@ -28,7 +28,7 @@ import atexit _exithandlers = [] -def _run_exitfuncs(): +def _run_exitfuncs() -> None: """run any registered exit functions _exithandlers is traversed in reverse order so functions are executed @@ -39,7 +39,7 @@ def _run_exitfuncs(): func, targs, kargs = _exithandlers.pop() func(*targs, **kargs) -def register(func, *targs, **kargs): +def register(func, *targs, **kargs) -> None: """register a function to be executed upon normal program termination func - function to be called at exit diff --git a/testing/framework/TestCmd.py b/testing/framework/TestCmd.py index b109843..5cdeea0 100644 --- a/testing/framework/TestCmd.py +++ b/testing/framework/TestCmd.py @@ -427,7 +427,7 @@ def clean_up_ninja_daemon(self, result_type) -> None: shutil.rmtree(daemon_dir) -def fail_test(self=None, condition=True, function=None, skip=0, message=None): +def fail_test(self=None, condition: bool=True, function=None, skip: int=0, message=None) -> None: """Causes a test to exit with a fail. Reports that the test FAILED and exits with a status of 1, unless @@ -468,7 +468,7 @@ def fail_test(self=None, condition=True, function=None, skip=0, message=None): sys.exit(1) -def no_result(self=None, condition=True, function=None, skip=0): +def no_result(self=None, condition: bool=True, function=None, skip: int=0) -> None: """Causes a test to exit with a no result. In testing parlance NO RESULT means the test could not be completed @@ -510,7 +510,7 @@ def no_result(self=None, condition=True, function=None, skip=0): sys.exit(2) -def pass_test(self=None, condition=True, function=None): +def pass_test(self=None, condition: bool=True, function=None) -> None: """Causes a test to exit with a pass. Reports that the test PASSED and exits with a status of 0, unless @@ -644,8 +644,8 @@ def match_re_dotall(lines=None, res=None): return expr.match(lines) -def simple_diff(a, b, fromfile='', tofile='', - fromfiledate='', tofiledate='', n=0, lineterm=''): +def simple_diff(a, b, fromfile: str='', tofile: str='', + fromfiledate: str='', tofiledate: str='', n: int=0, lineterm: str=''): r"""Compare two sequences of lines; generate the delta as a simple diff. Similar to difflib.context_diff and difflib.unified_diff but @@ -694,8 +694,8 @@ def simple_diff(a, b, fromfile='', tofile='', yield f"> {l}" -def diff_re(a, b, fromfile='', tofile='', - fromfiledate='', tofiledate='', n=3, lineterm='\n'): +def diff_re(a, b, fromfile: str='', tofile: str='', + fromfiledate: str='', tofiledate: str='', n: int=3, lineterm: str='\n'): """Compare a and b (lists of strings) where a are regular expressions. A simple "diff" of two sets of lines when the expected lines @@ -864,7 +864,7 @@ class Popen(subprocess.Popen): def recv_err(self, maxsize=None): return self._recv('stderr', maxsize) - def send_recv(self, input='', maxsize=None): + def send_recv(self, input: str='', maxsize=None): return self.send(input), self.recv(maxsize), self.recv_err(maxsize) def get_conn_maxsize(self, which, maxsize): @@ -874,7 +874,7 @@ class Popen(subprocess.Popen): maxsize = 1 return getattr(self, which), maxsize - def _close(self, which): + def _close(self, which) -> None: getattr(self, which).close() setattr(self, which, None) @@ -969,7 +969,7 @@ class Popen(subprocess.Popen): disconnect_message = "Other end disconnected!" -def recv_some(p, t=.1, e=1, tr=5, stderr=0): +def recv_some(p, t: float=.1, e: int=1, tr: int=5, stderr: int=0): if tr < 1: tr = 1 x = time.time() + t @@ -1004,7 +1004,7 @@ _Cleanup = [] @atexit.register -def _clean(): +def _clean() -> None: global _Cleanup cleanlist = [c for c in _Cleanup if c] del _Cleanup[:] @@ -1030,10 +1030,10 @@ class TestCmd: diff=None, diff_stdout=None, diff_stderr=None, - combine=0, - universal_newlines=True, + combine: int=0, + universal_newlines: bool=True, timeout=None, - ): + ) -> None: self.external = os.environ.get('SCONS_EXTERNAL_TEST', 0) self._cwd = os.getcwd() self.description_set(description) @@ -1087,16 +1087,16 @@ class TestCmd: self.fixture_dirs = [] - def __del__(self): + def __del__(self) -> None: self.cleanup() - def __repr__(self): + def __repr__(self) -> str: return f"{id(self):x}" banner_char = '=' banner_width = 80 - def banner(self, s, width=None): + def banner(self, s, width=None) -> str: if width is None: width = self.banner_width return f"{s:{self.banner_char}<{width}}" @@ -1110,12 +1110,12 @@ class TestCmd: path = os.path.join(self.workdir, path) return path - def chmod(self, path, mode): + def chmod(self, path, mode) -> None: """Changes permissions on the specified file or directory.""" path = self.canonicalize(path) os.chmod(path, mode) - def cleanup(self, condition=None): + def cleanup(self, condition=None) -> None: """Removes any temporary working directories. Cleans the TestCmd instance. If the environment variable PRESERVE was @@ -1182,11 +1182,11 @@ class TestCmd: cmd.extend(arguments) return cmd - def description_set(self, description): + def description_set(self, description) -> None: """Set the description of the functionality being tested. """ self.description = description - def set_diff_function(self, diff=_Null, stdout=_Null, stderr=_Null): + def set_diff_function(self, diff=_Null, stdout=_Null, stderr=_Null) -> None: """Sets the specified diff functions.""" if diff is not _Null: self._diff_function = diff @@ -1195,7 +1195,7 @@ class TestCmd: if stderr is not _Null: self._diff_stderr_function = stderr - def diff(self, a, b, name=None, diff_function=None, *args, **kw): + def diff(self, a, b, name=None, diff_function=None, *args, **kw) -> None: if diff_function is None: try: diff_function = getattr(self, self._diff_function) @@ -1239,7 +1239,7 @@ class TestCmd: unified_diff = staticmethod(difflib.unified_diff) - def fail_test(self, condition=True, function=None, skip=0, message=None): + def fail_test(self, condition: bool=True, function=None, skip: int=0, message=None) -> None: """Cause the test to fail.""" if not condition: return @@ -1250,13 +1250,13 @@ class TestCmd: skip=skip, message=message) - def interpreter_set(self, interpreter): + def interpreter_set(self, interpreter) -> None: """Set the program to be used to interpret the program under test as a script. """ self.interpreter = interpreter - def set_match_function(self, match=_Null, stdout=_Null, stderr=_Null): + def set_match_function(self, match=_Null, stdout=_Null, stderr=_Null) -> None: """Sets the specified match functions. """ if match is not _Null: self._match_function = match @@ -1306,7 +1306,7 @@ class TestCmd: match_re_dotall = staticmethod(match_re_dotall) - def no_result(self, condition=True, function=None, skip=0): + def no_result(self, condition: bool=True, function=None, skip: int=0) -> None: """Report that the test could not be run.""" if not condition: return @@ -1316,14 +1316,14 @@ class TestCmd: function=function, skip=skip) - def pass_test(self, condition=True, function=None): + def pass_test(self, condition: bool=True, function=None) -> None: """Cause the test to pass.""" if not condition: return self.condition = 'pass_test' pass_test(self=self, condition=condition, function=function) - def preserve(self, *conditions): + def preserve(self, *conditions) -> None: """Preserves temporary working directories. Arrange for the temporary working directories for the @@ -1337,14 +1337,14 @@ class TestCmd: for cond in conditions: self._preserve[cond] = 1 - def program_set(self, program): + def program_set(self, program) -> None: """Sets the executable program or script to be tested.""" if not self.external: if program and not os.path.isabs(program): program = os.path.join(self._cwd, program) self.program = program - def read(self, file, mode='rb', newline=None): + def read(self, file, mode: str='rb', newline=None): """Reads and returns the contents of the specified file name. The file name may be a list, in which case the elements are @@ -1364,7 +1364,7 @@ class TestCmd: with open(file, mode) as f: return f.read() - def rmdir(self, dir): + def rmdir(self, dir) -> None: """Removes the specified dir name. The dir name may be a list, in which case the elements are @@ -1377,7 +1377,7 @@ class TestCmd: os.rmdir(dir) - def parse_path(self, path, suppress_current=False): + def parse_path(self, path, suppress_current: bool=False): """Return a list with the single path components of path.""" head, tail = os.path.split(path) result = [] @@ -1395,7 +1395,7 @@ class TestCmd: return result - def dir_fixture(self, srcdir, dstdir=None): + def dir_fixture(self, srcdir, dstdir=None) -> None: """ Copies the contents of the fixture directory to the test directory. If srcdir is an absolute path, it is tried directly, else @@ -1444,7 +1444,7 @@ class TestCmd: else: shutil.copy(epath, dpath) - def file_fixture(self, srcfile, dstfile=None): + def file_fixture(self, srcfile, dstfile=None) -> None: """ Copies a fixture file to the test directory, optionally renaming. If srcfile is an absolute path, it is tried directly, else @@ -1575,7 +1575,7 @@ class TestCmd: stream = stream.decode('utf-8', errors='replace') return stream.replace('\r\n', '\n') - def finish(self, popen=None, **kw): + def finish(self, popen=None, **kw) -> None: """ Finishes and waits for the process. Process being run under control of the specified popen argument @@ -1620,7 +1620,7 @@ class TestCmd: chdir=None, stdin=None, universal_newlines=None, - timeout=None): + timeout=None) -> None: """Runs a test of the program or script for the test environment. Output and error output are saved for future retrieval via @@ -1709,7 +1709,7 @@ class TestCmd: write(err) write('============ END STDERR\n') - def sleep(self, seconds=default_sleep_seconds): + def sleep(self, seconds=default_sleep_seconds) -> None: """Sleeps at least the specified number of seconds. If no number is specified, sleeps at least the minimum number of @@ -1789,7 +1789,7 @@ class TestCmd: return count - def symlink(self, target, link): + def symlink(self, target, link) -> None: """Creates a symlink to the specified target. The link name may be a list, in which case the elements are @@ -1849,7 +1849,7 @@ class TestCmd: return path - def touch(self, path, mtime=None): + def touch(self, path, mtime=None) -> None: """Updates the modification time on the specified file or directory. The default is to update to the @@ -1861,7 +1861,7 @@ class TestCmd: mtime = time.time() os.utime(path, (atime, mtime)) - def unlink(self, file): + def unlink(self, file) -> None: """Unlinks the specified file name. The file name may be a list, in which case the elements are @@ -1872,7 +1872,7 @@ class TestCmd: file = self.canonicalize(file) os.unlink(file) - def verbose_set(self, verbose): + def verbose_set(self, verbose) -> None: """Sets the verbose level.""" self.verbose = verbose @@ -1884,7 +1884,7 @@ class TestCmd: file = where_is(file, path, pathext) return file - def workdir_set(self, path): + def workdir_set(self, path) -> None: """Creates a temporary working directory with the specified path name. If the path is a null string (''), a unique directory name is created. @@ -1903,7 +1903,7 @@ class TestCmd: """ return os.path.join(self.workdir, *args) - def readable(self, top, read=True): + def readable(self, top, read: bool=True) -> None: """Makes the specified directory tree readable or unreadable. Tree is made readable if `read` evaluates True (the default), @@ -1917,7 +1917,7 @@ class TestCmd: return if read: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -1926,7 +1926,7 @@ class TestCmd: os.chmod(fname, stat.S_IMODE( st[stat.ST_MODE] | stat.S_IREAD)) else: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -1958,7 +1958,7 @@ class TestCmd: do_chmod(os.path.join(dirpath, name)) do_chmod(top) - def writable(self, top, write=True): + def writable(self, top, write: bool=True) -> None: """Make the specified directory tree writable or unwritable. Tree is made writable if `write` evaluates True (the default), @@ -1968,13 +1968,13 @@ class TestCmd: if sys.platform == 'win32': if write: - def do_chmod(fname): + def do_chmod(fname) -> None: try: os.chmod(fname, stat.S_IWRITE) except OSError: pass else: - def do_chmod(fname): + def do_chmod(fname) -> None: try: os.chmod(fname, stat.S_IREAD) except OSError: @@ -1983,7 +1983,7 @@ class TestCmd: else: if write: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -1991,7 +1991,7 @@ class TestCmd: else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE] | 0o200)) else: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -2008,7 +2008,7 @@ class TestCmd: for name in dirnames + filenames: do_chmod(os.path.join(dirpath, name)) - def executable(self, top, execute=True): + def executable(self, top, execute: bool=True) -> None: """Make the specified directory tree executable or not executable. Tree is made executable if `execute` evaluates True (the default), @@ -2022,7 +2022,7 @@ class TestCmd: return if execute: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -2031,7 +2031,7 @@ class TestCmd: os.chmod(fname, stat.S_IMODE( st[stat.ST_MODE] | stat.S_IEXEC)) else: - def do_chmod(fname): + def do_chmod(fname) -> None: try: st = os.stat(fname) except OSError: @@ -2063,7 +2063,7 @@ class TestCmd: do_chmod(os.path.join(dirpath, name)) do_chmod(top) - def write(self, file, content, mode='wb'): + def write(self, file, content, mode: str='wb'): """Writes data to file. The file is created under the temporary working directory. diff --git a/testing/framework/TestCmdTests.py b/testing/framework/TestCmdTests.py index 0a1fa26..dc752ba 100644 --- a/testing/framework/TestCmdTests.py +++ b/testing/framework/TestCmdTests.py @@ -54,7 +54,7 @@ def _is_executable(path): # XXX this doesn't take into account UID, it assumes it's our file return os.stat(path)[stat.ST_MODE] & stat.S_IEXEC -def _clear_dict(dict, *keys): +def _clear_dict(dict, *keys) -> None: for key in keys: try: del dict[key] @@ -68,10 +68,10 @@ class ExitError(Exception): class TestCmdTestCase(unittest.TestCase): """Base class for TestCmd test cases, with fixture and utility methods.""" - def setUp(self): + def setUp(self) -> None: self.orig_cwd = os.getcwd() - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.orig_cwd) def setup_run_scripts(self): @@ -145,7 +145,7 @@ class TestCmdTestCase(unittest.TestCase): stderr = self.translate_newlines(to_str(cp.stderr)) return stdout, stderr, cp.returncode - def popen_python(self, indata, status=0, stdout="", stderr="", python=None): + def popen_python(self, indata, status: int=0, stdout: str="", stderr: str="", python=None) -> None: if python is None: python = sys.executable _stdout, _stderr, _status = self.call_python(indata, python) @@ -164,7 +164,7 @@ class TestCmdTestCase(unittest.TestCase): f"Actual STDERR ============\n{_stderr}" ) - def run_match(self, content, *args): + def run_match(self, content, *args) -> None: expect = "%s: %s: %s: %s\n" % args content = self.translate_newlines(to_str(content)) assert content == expect, ( @@ -175,7 +175,7 @@ class TestCmdTestCase(unittest.TestCase): class __init__TestCase(TestCmdTestCase): - def test_init(self): + def test_init(self) -> None: """Test init()""" test = TestCmd.TestCmd() test = TestCmd.TestCmd(description = 'test') @@ -187,14 +187,14 @@ class __init__TestCase(TestCmdTestCase): class basename_TestCase(TestCmdTestCase): - def test_basename(self): + def test_basename(self) -> None: """Test basename() [XXX TO BE WRITTEN]""" assert 1 == 1 class cleanup_TestCase(TestCmdTestCase): - def test_cleanup(self): + def test_cleanup(self) -> None: """Test cleanup()""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir @@ -202,7 +202,7 @@ class cleanup_TestCase(TestCmdTestCase): test.cleanup() assert not os.path.exists(wdir) - def test_writable(self): + def test_writable(self) -> None: """Test cleanup() when the directory isn't writable""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir @@ -212,7 +212,7 @@ class cleanup_TestCase(TestCmdTestCase): test.cleanup() assert not os.path.exists(wdir) - def test_shutil(self): + def test_shutil(self) -> None: """Test cleanup() when used with shutil""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir @@ -220,7 +220,7 @@ class cleanup_TestCase(TestCmdTestCase): import shutil save_rmtree = shutil.rmtree - def my_rmtree(dir, ignore_errors=0, wdir=wdir, _rmtree=save_rmtree): + def my_rmtree(dir, ignore_errors: int=0, wdir=wdir, _rmtree=save_rmtree): assert os.getcwd() != wdir return _rmtree(dir, ignore_errors=ignore_errors) try: @@ -229,7 +229,7 @@ class cleanup_TestCase(TestCmdTestCase): finally: shutil.rmtree = save_rmtree - def test_atexit(self): + def test_atexit(self) -> None: """Test cleanup when atexit is used""" self.popen_python(f"""\ import atexit @@ -248,7 +248,7 @@ sys.exit(0) class chmod_TestCase(TestCmdTestCase): - def test_chmod(self): + def test_chmod(self) -> None: """Test chmod()""" test = TestCmd.TestCmd(workdir = '', subdir = 'sub') @@ -381,7 +381,7 @@ run2 STDERR third line class description_TestCase(TestCmdTestCase): - def test_description(self): + def test_description(self) -> None: """Test description()""" test = TestCmd.TestCmd() assert test.description is None, 'initialized description?' @@ -393,7 +393,7 @@ class description_TestCase(TestCmdTestCase): class diff_TestCase(TestCmdTestCase): - def test_diff_re(self): + def test_diff_re(self) -> None: """Test diff_re()""" result = TestCmd.diff_re(["abcde"], ["abcde"]) result = list(result) @@ -405,7 +405,7 @@ class diff_TestCase(TestCmdTestCase): result = list(result) assert result == ['1c1', "< 'a.*e'", '---', "> 'xxx'"], result - def test_diff_custom_function(self): + def test_diff_custom_function(self) -> None: """Test diff() using a custom function""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -431,7 +431,7 @@ STDOUT========================================================================== ***** """) - def test_diff_string(self): + def test_diff_string(self) -> None: self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path import TestCmd @@ -447,7 +447,7 @@ STDOUT========================================================================== > 'b2' """) - def test_error(self): + def test_error(self) -> None: """Test handling a compilation error in TestCmd.diff_re()""" script_input = f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -462,7 +462,7 @@ sys.exit(0) assert (stderr.find(expect1) != -1 or stderr.find(expect2) != -1), repr(stderr) - def test_simple_diff_static_method(self): + def test_simple_diff_static_method(self) -> None: """Test calling the TestCmd.TestCmd.simple_diff() static method""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -475,7 +475,7 @@ assert result == expect, result sys.exit(0) """) - def test_context_diff_static_method(self): + def test_context_diff_static_method(self) -> None: """Test calling the TestCmd.TestCmd.context_diff() static method""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -504,7 +504,7 @@ assert result == expect, result sys.exit(0) """) - def test_unified_diff_static_method(self): + def test_unified_diff_static_method(self) -> None: """Test calling the TestCmd.TestCmd.unified_diff() static method""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -528,7 +528,7 @@ assert result == expect, result sys.exit(0) """) - def test_diff_re_static_method(self): + def test_diff_re_static_method(self) -> None: """Test calling the TestCmd.TestCmd.diff_re() static method""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -557,7 +557,7 @@ sys.exit(0) class diff_stderr_TestCase(TestCmdTestCase): - def test_diff_stderr_default(self): + def test_diff_stderr_default(self) -> None: """Test diff_stderr() default behavior""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -573,7 +573,7 @@ sys.exit(0) > b2 """) - def test_diff_stderr_not_affecting_diff_stdout(self): + def test_diff_stderr_not_affecting_diff_stdout(self) -> None: """Test diff_stderr() not affecting diff_stdout() behavior""" self.popen_python(fr""" import sys @@ -595,7 +595,7 @@ diff_stdout: > bb """) - def test_diff_stderr_custom_function(self): + def test_diff_stderr_custom_function(self) -> None: """Test diff_stderr() using a custom function""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -613,7 +613,7 @@ b: def """) - def test_diff_stderr_TestCmd_function(self): + def test_diff_stderr_TestCmd_function(self) -> None: """Test diff_stderr() using a TestCmd function""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -629,7 +629,7 @@ sys.exit(0) > 'b' """) - def test_diff_stderr_static_method(self): + def test_diff_stderr_static_method(self) -> None: """Test diff_stderr() using a static method""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -645,7 +645,7 @@ sys.exit(0) > 'b' """) - def test_diff_stderr_string(self): + def test_diff_stderr_string(self) -> None: """Test diff_stderr() using a string to fetch the diff method""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -664,7 +664,7 @@ sys.exit(0) class diff_stdout_TestCase(TestCmdTestCase): - def test_diff_stdout_default(self): + def test_diff_stdout_default(self) -> None: """Test diff_stdout() default behavior""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -680,7 +680,7 @@ sys.exit(0) > b2 """) - def test_diff_stdout_not_affecting_diff_stderr(self): + def test_diff_stdout_not_affecting_diff_stderr(self) -> None: """Test diff_stdout() not affecting diff_stderr() behavior""" self.popen_python(fr""" import sys @@ -702,7 +702,7 @@ diff_stderr: > bb """) - def test_diff_stdout_custom_function(self): + def test_diff_stdout_custom_function(self) -> None: """Test diff_stdout() using a custom function""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -720,7 +720,7 @@ b: def """) - def test_diff_stdout_TestCmd_function(self): + def test_diff_stdout_TestCmd_function(self) -> None: """Test diff_stdout() using a TestCmd function""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -736,7 +736,7 @@ sys.exit(0) > 'b' """) - def test_diff_stdout_static_method(self): + def test_diff_stdout_static_method(self) -> None: """Test diff_stdout() using a static method""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -752,7 +752,7 @@ sys.exit(0) > 'b' """) - def test_diff_stdout_string(self): + def test_diff_stdout_string(self) -> None: """Test diff_stdout() using a string to fetch the diff method""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -771,7 +771,7 @@ sys.exit(0) class exit_TestCase(TestCmdTestCase): - def test_exit(self): + def test_exit(self) -> None: """Test exit()""" def _test_it(cwd, tempdir, condition, preserved): close_true = {'pass_test': 1, 'fail_test': 0, 'no_result': 0} @@ -845,7 +845,7 @@ test.{condition}() class fail_test_TestCase(TestCmdTestCase): - def test_fail_test(self): + def test_fail_test(self) -> None: """Test fail_test()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys @@ -912,7 +912,7 @@ test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) class interpreter_TestCase(TestCmdTestCase): - def test_interpreter(self): + def test_interpreter(self) -> None: """Test interpreter()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys @@ -932,7 +932,7 @@ sys.stderr.write("run: STDERR\\n") class match_TestCase(TestCmdTestCase): - def test_match_default(self): + def test_match_default(self) -> None: """Test match() default behavior""" test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") @@ -941,7 +941,7 @@ class match_TestCase(TestCmdTestCase): regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match(lines, regexes) - def test_match_custom_function(self): + def test_match_custom_function(self) -> None: """Test match() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) @@ -954,7 +954,7 @@ class match_TestCase(TestCmdTestCase): regexes = ["1\n", "1\n"] assert test.match(lines, regexes) # due to equal numbers of lines - def test_match_TestCmd_function(self): + def test_match_TestCmd_function(self) -> None: """Test match() using a TestCmd function""" test = TestCmd.TestCmd(match = TestCmd.match_exact) assert not test.match("abcde\n", "a.*e\n") @@ -966,7 +966,7 @@ class match_TestCase(TestCmdTestCase): assert not test.match(lines, regexes) assert test.match(lines, lines) - def test_match_static_method(self): + def test_match_static_method(self) -> None: """Test match() using a static method""" test = TestCmd.TestCmd(match=TestCmd.TestCmd.match_exact) assert not test.match("abcde\n", "a.*e\n") @@ -978,7 +978,7 @@ class match_TestCase(TestCmdTestCase): assert not test.match(lines, regexes) assert test.match(lines, lines) - def test_match_string(self): + def test_match_string(self) -> None: """Test match() using a string to fetch the match method""" test = TestCmd.TestCmd(match='match_exact') assert not test.match("abcde\n", "a.*e\n") @@ -993,23 +993,23 @@ class match_TestCase(TestCmdTestCase): class match_exact_TestCase(TestCmdTestCase): - def test_match_exact_function(self): + def test_match_exact_function(self) -> None: """Test calling the TestCmd.match_exact() function""" assert not TestCmd.match_exact("abcde\\n", "a.*e\\n") assert TestCmd.match_exact("abcde\\n", "abcde\\n") - def test_match_exact_instance_method(self): + def test_match_exact_instance_method(self) -> None: """Test calling the TestCmd.TestCmd().match_exact() instance method""" test = TestCmd.TestCmd() assert not test.match_exact("abcde\\n", "a.*e\\n") assert test.match_exact("abcde\\n", "abcde\\n") - def test_match_exact_static_method(self): + def test_match_exact_static_method(self) -> None: """Test calling the TestCmd.TestCmd.match_exact() static method""" assert not TestCmd.TestCmd.match_exact("abcde\\n", "a.*e\\n") assert TestCmd.TestCmd.match_exact("abcde\\n", "abcde\\n") - def test_evaluation(self): + def test_evaluation(self) -> None: """Test match_exact() evaluation""" test = TestCmd.TestCmd() assert not test.match_exact("abcde\n", "a.*e\n") @@ -1034,20 +1034,20 @@ class match_exact_TestCase(TestCmdTestCase): class match_re_dotall_TestCase(TestCmdTestCase): - def test_match_re_dotall_function(self): + def test_match_re_dotall_function(self) -> None: """Test calling the TestCmd.match_re_dotall() function""" assert TestCmd.match_re_dotall("abcde\nfghij\n", r"a.*j\n") - def test_match_re_dotall_instance_method(self): + def test_match_re_dotall_instance_method(self) -> None: """Test calling the TestCmd.TestCmd().match_re_dotall() instance method""" test = TestCmd.TestCmd() test.match_re_dotall("abcde\\nfghij\\n", r"a.*j\\n") - def test_match_re_dotall_static_method(self): + def test_match_re_dotall_static_method(self) -> None: """Test calling the TestCmd.TestCmd.match_re_dotall() static method""" assert TestCmd.TestCmd.match_re_dotall("abcde\nfghij\n", r"a.*j\n") - def test_error(self): + def test_error(self) -> None: """Test handling a compilation error in TestCmd.match_re_dotall()""" run_env = TestCmd.TestCmd(workdir = '') cwd = os.getcwd() @@ -1070,7 +1070,7 @@ sys.exit(0) finally: os.chdir(cwd) - def test_evaluation(self): + def test_evaluation(self) -> None: """Test match_re_dotall() evaluation""" test = TestCmd.TestCmd() assert test.match_re_dotall("abcde\nfghij\n", r"a.*e\nf.*j\n") @@ -1107,20 +1107,20 @@ sys.exit(0) class match_re_TestCase(TestCmdTestCase): - def test_match_re_function(self): + def test_match_re_function(self) -> None: """Test calling the TestCmd.match_re() function""" assert TestCmd.match_re("abcde\n", "a.*e\n") - def test_match_re_instance_method(self): + def test_match_re_instance_method(self) -> None: """Test calling the TestCmd.TestCmd().match_re() instance method""" test = TestCmd.TestCmd() assert test.match_re("abcde\n", "a.*e\n") - def test_match_re_static_method(self): + def test_match_re_static_method(self) -> None: """Test calling the TestCmd.TestCmd.match_re() static method""" assert TestCmd.TestCmd.match_re("abcde\n", "a.*e\n") - def test_error(self): + def test_error(self) -> None: """Test handling a compilation error in TestCmd.match_re()""" run_env = TestCmd.TestCmd(workdir = '') cwd = os.getcwd() @@ -1145,7 +1145,7 @@ sys.exit(0) finally: os.chdir(cwd) - def test_evaluation(self): + def test_evaluation(self) -> None: """Test match_re() evaluation""" test = TestCmd.TestCmd() assert test.match_re("abcde\n", "a.*e\n") @@ -1170,7 +1170,7 @@ sys.exit(0) class match_stderr_TestCase(TestCmdTestCase): - def test_match_stderr_default(self): + def test_match_stderr_default(self) -> None: """Test match_stderr() default behavior""" test = TestCmd.TestCmd() assert test.match_stderr("abcde\n", "a.*e\n") @@ -1179,7 +1179,7 @@ class match_stderr_TestCase(TestCmdTestCase): regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"] assert test.match_stderr(lines, regexes) - def test_match_stderr_not_affecting_match_stdout(self): + def test_match_stderr_not_affecting_match_stdout(self) -> None: """Test match_stderr() not affecting match_stdout() behavior""" test = TestCmd.TestCmd(match_stderr=TestCmd.TestCmd.match_exact) @@ -1198,7 +1198,7 @@ class match_stderr_TestCase(TestCmdTestCase): regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"] assert test.match_stdout(lines, regexes) - def test_match_stderr_custom_function(self): + def test_match_stderr_custom_function(self) -> None: """Test match_stderr() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) @@ -1211,7 +1211,7 @@ class match_stderr_TestCase(TestCmdTestCase): regexes = [r"1\n", r"1\n"] assert test.match_stderr(lines, regexes) # equal numbers of lines - def test_match_stderr_TestCmd_function(self): + def test_match_stderr_TestCmd_function(self) -> None: """Test match_stderr() using a TestCmd function""" test = TestCmd.TestCmd(match_stderr = TestCmd.match_exact) assert not test.match_stderr("abcde\n", "a.*e\n") @@ -1223,7 +1223,7 @@ class match_stderr_TestCase(TestCmdTestCase): assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) - def test_match_stderr_static_method(self): + def test_match_stderr_static_method(self) -> None: """Test match_stderr() using a static method""" test = TestCmd.TestCmd(match_stderr=TestCmd.TestCmd.match_exact) assert not test.match_stderr("abcde\n", "a.*e\n") @@ -1235,7 +1235,7 @@ class match_stderr_TestCase(TestCmdTestCase): assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) - def test_match_stderr_string(self): + def test_match_stderr_string(self) -> None: """Test match_stderr() using a string to fetch the match method""" test = TestCmd.TestCmd(match_stderr='match_exact') assert not test.match_stderr("abcde\n", "a.*e\n") @@ -1250,7 +1250,7 @@ class match_stderr_TestCase(TestCmdTestCase): class match_stdout_TestCase(TestCmdTestCase): - def test_match_stdout_default(self): + def test_match_stdout_default(self) -> None: """Test match_stdout() default behavior""" test = TestCmd.TestCmd() assert test.match_stdout("abcde\n", "a.*e\n") @@ -1259,7 +1259,7 @@ class match_stdout_TestCase(TestCmdTestCase): regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"] assert test.match_stdout(lines, regexes) - def test_match_stdout_not_affecting_match_stderr(self): + def test_match_stdout_not_affecting_match_stderr(self) -> None: """Test match_stdout() not affecting match_stderr() behavior""" test = TestCmd.TestCmd(match_stdout=TestCmd.TestCmd.match_exact) @@ -1278,7 +1278,7 @@ class match_stdout_TestCase(TestCmdTestCase): regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"] assert test.match_stderr(lines, regexes) - def test_match_stdout_custom_function(self): + def test_match_stdout_custom_function(self) -> None: """Test match_stdout() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) @@ -1291,7 +1291,7 @@ class match_stdout_TestCase(TestCmdTestCase): regexes = [r"1\n", r"1\n"] assert test.match_stdout(lines, regexes) # equal numbers of lines - def test_match_stdout_TestCmd_function(self): + def test_match_stdout_TestCmd_function(self) -> None: """Test match_stdout() using a TestCmd function""" test = TestCmd.TestCmd(match_stdout = TestCmd.match_exact) assert not test.match_stdout("abcde\n", "a.*e\n") @@ -1303,7 +1303,7 @@ class match_stdout_TestCase(TestCmdTestCase): assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) - def test_match_stdout_static_method(self): + def test_match_stdout_static_method(self) -> None: """Test match_stdout() using a static method""" test = TestCmd.TestCmd(match_stdout=TestCmd.TestCmd.match_exact) assert not test.match_stdout("abcde\n", "a.*e\n") @@ -1315,7 +1315,7 @@ class match_stdout_TestCase(TestCmdTestCase): assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) - def test_match_stdout_string(self): + def test_match_stdout_string(self) -> None: """Test match_stdout() using a string to fetch the match method""" test = TestCmd.TestCmd(match_stdout='match_exact') assert not test.match_stdout("abcde\n", "a.*e\n") @@ -1330,7 +1330,7 @@ class match_stdout_TestCase(TestCmdTestCase): class no_result_TestCase(TestCmdTestCase): - def test_no_result(self): + def test_no_result(self) -> None: """Test no_result()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys @@ -1397,7 +1397,7 @@ test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) class pass_test_TestCase(TestCmdTestCase): - def test_pass_test(self): + def test_pass_test(self) -> None: """Test pass_test()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys @@ -1436,9 +1436,9 @@ test.pass_test(condition = (test.status == 0), function = brag) class preserve_TestCase(TestCmdTestCase): - def test_preserve(self): + def test_preserve(self) -> None: """Test preserve()""" - def cleanup_test(test, cond=None, stdout=""): + def cleanup_test(test, cond=None, stdout: str="") -> None: save = sys.stdout with closing(StringIO()) as io: sys.stdout = io @@ -1526,7 +1526,7 @@ class preserve_TestCase(TestCmdTestCase): class program_TestCase(TestCmdTestCase): - def test_program(self): + def test_program(self) -> None: """Test program()""" test = TestCmd.TestCmd() assert test.program is None, 'initialized program?' @@ -1572,7 +1572,7 @@ class read_TestCase(TestCmdTestCase): except: raise - def _file_matches(file, contents, expected): + def _file_matches(file, contents, expected) -> None: contents = to_str(contents) assert contents == expected, \ "Expected contents of " + str(file) + "==========\n" + \ @@ -1649,7 +1649,7 @@ class rmdir_TestCase(TestCmdTestCase): class run_TestCase(TestCmdTestCase): - def test_run(self): + def test_run(self) -> None: """Test run()""" t = self.setup_run_scripts() @@ -1799,7 +1799,7 @@ class run_TestCase(TestCmdTestCase): finally: os.chdir(t.orig_cwd) - def test_run_subclass(self): + def test_run_subclass(self) -> None: """Test run() through a subclass with different signatures""" t = self.setup_run_scripts() @@ -1827,7 +1827,7 @@ class run_TestCase(TestCmdTestCase): class run_verbose_TestCase(TestCmdTestCase): - def test_run_verbose(self): + def test_run_verbose(self) -> None: """Test the run() method's verbose attribute""" # Prepare our "source directory." @@ -2043,7 +2043,7 @@ class run_verbose_TestCase(TestCmdTestCase): class set_diff_function_TestCase(TestCmdTestCase): - def test_set_diff_function(self): + def test_set_diff_function(self) -> None: """Test set_diff_function()""" self.popen_python(fr"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -2055,7 +2055,7 @@ test.diff(".\n", "a\n") sys.exit(0) """) - def test_set_diff_function_stdout(self): + def test_set_diff_function_stdout(self) -> None: """Test set_diff_function(): stdout""" self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -2083,7 +2083,7 @@ diff: diff_stdout: """) - def test_set_diff_function_stderr(self): + def test_set_diff_function_stderr(self) -> None: """Test set_diff_function(): stderr """ self.popen_python(f"""import sys sys.path = [r'{self.orig_cwd}'] + sys.path @@ -2114,7 +2114,7 @@ diff_stderr: class set_match_function_TestCase(TestCmdTestCase): - def test_set_match_function(self): + def test_set_match_function(self) -> None: """Test set_match_function()""" test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") @@ -2125,7 +2125,7 @@ class set_match_function_TestCase(TestCmdTestCase): assert not test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") - def test_set_match_function_stdout(self): + def test_set_match_function_stdout(self) -> None: """Test set_match_function(): stdout """ test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") @@ -2140,7 +2140,7 @@ class set_match_function_TestCase(TestCmdTestCase): assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") - def test_set_match_function_stderr(self): + def test_set_match_function_stderr(self) -> None: """Test set_match_function(): stderr """ test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") @@ -2158,7 +2158,7 @@ class set_match_function_TestCase(TestCmdTestCase): class sleep_TestCase(TestCmdTestCase): - def test_sleep(self): + def test_sleep(self) -> None: """Test sleep()""" test = TestCmd.TestCmd() @@ -2216,7 +2216,7 @@ sys.stderr.write("run2 STDERR second line\\n") class command_args_TestCase(TestCmdTestCase): - def test_command_args(self): + def test_command_args(self) -> None: """Test command_args()""" run_env = TestCmd.TestCmd(workdir = '') os.chdir(run_env.workdir) @@ -2317,14 +2317,14 @@ with open(r'{t.recv_out_path}', 'w') as logfp: os.chmod(t.recv_script_path, 0o644) # XXX UNIX-specific return t - def _cleanup(self, popen): + def _cleanup(self, popen) -> None: """Quiet Python ResourceWarning after wait()""" if popen.stdout: popen.stdout.close() if popen.stderr: popen.stderr.close() - def test_start(self): + def test_start(self) -> None: """Test start()""" t = self.setup_run_scripts() @@ -2467,7 +2467,7 @@ with open(r'{t.recv_out_path}', 'w') as logfp: finally: os.chdir(t.orig_cwd) - def test_finish(self): + def test_finish(self) -> None: """Test finish()""" t = self.setup_run_scripts() @@ -2528,7 +2528,7 @@ script_recv: STDERR: input finally: os.chdir(t.orig_cwd) - def test_recv(self): + def test_recv(self) -> None: """Test the recv() method of objects returned by start()""" t = self.setup_run_scripts() @@ -2554,7 +2554,7 @@ script_recv: STDERR: input finally: os.chdir(t.orig_cwd) - def test_recv_err(self): + def test_recv_err(self) -> None: """Test the recv_err() method of objects returned by start()""" t = self.setup_run_scripts() @@ -2582,7 +2582,7 @@ script_recv: STDERR: input finally: os.chdir(t.orig_cwd) - def test_send(self): + def test_send(self) -> None: """Test the send() method of objects returned by start()""" t = self.setup_run_scripts() @@ -2620,7 +2620,7 @@ script_recv: STDERR: input os.chdir(t.orig_cwd) # TODO(sgk): figure out how to eliminate the race conditions here. - def __FLAKY__test_send_recv(self): + def __FLAKY__test_send_recv(self) -> None: """Test the send_recv() method of objects returned by start()""" t = self.setup_run_scripts() @@ -2682,7 +2682,7 @@ script_recv: STDERR: input to the receive script class stdin_TestCase(TestCmdTestCase): - def test_stdin(self): + def test_stdin(self) -> None: """Test stdin()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """\ @@ -2745,7 +2745,7 @@ sys.stderr.write("run2 STDERR second line\\n") class subdir_TestCase(TestCmdTestCase): - def test_subdir(self): + def test_subdir(self) -> None: """Test subdir()""" # intermediate directories are created test = TestCmd.TestCmd(workdir='', subdir=['no', 'such', 'subdir']) @@ -2788,7 +2788,7 @@ class subdir_TestCase(TestCmdTestCase): class symlink_TestCase(TestCmdTestCase): @unittest.skipIf(sys.platform == 'win32', "Skip symlink test on win32") - def test_symlink(self): + def test_symlink(self) -> None: """Test symlink()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') wdir_file1 = os.path.join(test.workdir, 'file1') @@ -2817,16 +2817,16 @@ class symlink_TestCase(TestCmdTestCase): class tempdir_TestCase(TestCmdTestCase): - def setUp(self): + def setUp(self) -> None: TestCmdTestCase.setUp(self) self._tempdir = tempfile.mkdtemp() os.chdir(self._tempdir) - def tearDown(self): + def tearDown(self) -> None: TestCmdTestCase.tearDown(self) os.rmdir(self._tempdir) - def test_tempdir(self): + def test_tempdir(self) -> None: """Test tempdir()""" test = TestCmd.TestCmd() tdir1 = test.tempdir() @@ -2859,7 +2859,7 @@ sys.exit(0) """ class timeout_TestCase(TestCmdTestCase): - def test_initialization(self): + def test_initialization(self) -> None: """Test initializating a TestCmd with a timeout""" test = TestCmd.TestCmd(workdir='', timeout=2) test.write('sleep.py', timeout_script) @@ -2872,7 +2872,7 @@ class timeout_TestCase(TestCmdTestCase): assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\n', test.stdout() - def test_cancellation(self): + def test_cancellation(self) -> None: """Test timer cancellation after firing""" test = TestCmd.TestCmd(workdir='', timeout=4) test.write('sleep.py', timeout_script) @@ -2889,7 +2889,7 @@ class timeout_TestCase(TestCmdTestCase): assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 6\n', test.stdout() - def test_run(self): + def test_run(self) -> None: """Test run() timeout""" test = TestCmd.TestCmd(workdir='', timeout=8) test.write('sleep.py', timeout_script) @@ -2995,7 +2995,7 @@ class unlink_TestCase(TestCmdTestCase): class touch_TestCase(TestCmdTestCase): - def test_touch(self): + def test_touch(self) -> None: """Test touch()""" test = TestCmd.TestCmd(workdir = '', subdir = 'sub') @@ -3032,7 +3032,7 @@ class touch_TestCase(TestCmdTestCase): class verbose_TestCase(TestCmdTestCase): - def test_verbose(self): + def test_verbose(self) -> None: """Test verbose()""" test = TestCmd.TestCmd() assert test.verbose == 0, 'verbose already initialized?' @@ -3094,7 +3094,7 @@ class workdir_TestCase(TestCmdTestCase): class workdirs_TestCase(TestCmdTestCase): - def test_workdirs(self): + def test_workdirs(self) -> None: """Test workdirs()""" test = TestCmd.TestCmd() assert test.workdir is None @@ -3111,7 +3111,7 @@ class workdirs_TestCase(TestCmdTestCase): class workpath_TestCase(TestCmdTestCase): - def test_workpath(self): + def test_workpath(self) -> None: """Test workpath()""" test = TestCmd.TestCmd() assert test.workdir is None @@ -3123,7 +3123,7 @@ class workpath_TestCase(TestCmdTestCase): class readable_TestCase(TestCmdTestCase): @unittest.skipIf(sys.platform == 'win32', "Skip permission fiddling on win32") - def test_readable(self): + def test_readable(self) -> None: """Test readable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") @@ -3162,7 +3162,7 @@ class readable_TestCase(TestCmdTestCase): class writable_TestCase(TestCmdTestCase): @unittest.skipIf(sys.platform == 'win32', "Skip permission fiddling on win32") - def test_writable(self): + def test_writable(self) -> None: """Test writable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") @@ -3198,18 +3198,18 @@ class writable_TestCase(TestCmdTestCase): class executable_TestCase(TestCmdTestCase): @unittest.skipIf(sys.platform == 'win32', "Skip permission fiddling on win32") - def test_executable(self): + def test_executable(self) -> None: """Test executable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") test.write(['foo', 'file2'], "Test file #2\n") os.symlink('no_such_file', test.workpath('dangling_symlink')) - def make_executable(fname): + def make_executable(fname) -> None: st = os.stat(fname) os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0o100)) - def make_non_executable(fname): + def make_non_executable(fname) -> None: st = os.stat(fname) os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0o100)) @@ -3312,7 +3312,7 @@ class write_TestCase(TestCmdTestCase): class variables_TestCase(TestCmdTestCase): - def test_variables(self): + def test_variables(self) -> None: """Test global variables""" run_env = TestCmd.TestCmd(workdir = '') diff --git a/testing/framework/TestCommon.py b/testing/framework/TestCommon.py index 91d5332..b0879a6 100644 --- a/testing/framework/TestCommon.py +++ b/testing/framework/TestCommon.py @@ -211,7 +211,7 @@ def separate_files(flist): missing.append(f) return existing, missing -def contains(seq, subseq, find): +def contains(seq, subseq, find) -> bool: # Returns True or False. if find is None: return subseq in seq @@ -234,14 +234,14 @@ def find_index(seq, subseq, find): if os.name == 'posix': - def _failed(self, status = 0): + def _failed(self, status: int = 0): if self.status is None or status is None: return None return _status(self) != status def _status(self): return self.status elif os.name == 'nt': - def _failed(self, status = 0): + def _failed(self, status: int = 0): return not (self.status is None or status is None) and \ self.status != status def _status(self): @@ -256,7 +256,7 @@ class TestCommon(TestCmd): # # $test->copy('src_file', 'dst_file'); - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialize a new TestCommon instance. This involves just calling the base class initialization, and then changing directory to the workdir. @@ -281,7 +281,7 @@ class TestCommon(TestCmd): return arguments - def must_be_writable(self, *files): + def must_be_writable(self, *files) -> None: """Ensures that the specified file(s) exist and are writable. An individual file can be specified as a list of directory names, in which case the pathname will be constructed by concatenating @@ -297,7 +297,7 @@ class TestCommon(TestCmd): print("Unwritable files: `%s'" % "', `".join(unwritable)) self.fail_test(missing + unwritable) - def must_contain(self, file, required, mode='rb', find=None): + def must_contain(self, file, required, mode: str='rb', find=None) -> None: """Ensures specified file contains the required text. Args: @@ -326,7 +326,7 @@ class TestCommon(TestCmd): print(file_contents) self.fail_test() - def must_contain_all(self, output, input, title=None, find=None): + def must_contain_all(self, output, input, title=None, find=None) -> None: """Ensures that the specified output string (first argument) contains all of the specified input as a block (second argument). @@ -349,7 +349,7 @@ class TestCommon(TestCmd): print(output) self.fail_test() - def must_contain_all_lines(self, output, lines, title=None, find=None): + def must_contain_all_lines(self, output, lines, title=None, find=None) -> None: """Ensures that the specified output string (first argument) contains all of the specified lines (second argument). @@ -374,7 +374,7 @@ class TestCommon(TestCmd): sys.stdout.write(output) self.fail_test() - def must_contain_single_instance_of(self, output, lines, title=None): + def must_contain_single_instance_of(self, output, lines, title=None) -> None: """Ensures that the specified output string (first argument) contains one instance of the specified lines (second argument). @@ -401,7 +401,7 @@ class TestCommon(TestCmd): sys.stdout.write(output) self.fail_test() - def must_contain_any_line(self, output, lines, title=None, find=None): + def must_contain_any_line(self, output, lines, title=None, find=None) -> None: """Ensures that the specified output string (first argument) contains at least one of the specified lines (second argument). @@ -425,7 +425,7 @@ class TestCommon(TestCmd): sys.stdout.write(output) self.fail_test() - def must_contain_exactly_lines(self, output, expect, title=None, find=None): + def must_contain_exactly_lines(self, output, expect, title=None, find=None) -> None: """Ensures that the specified output string (first argument) contains all of the lines in the expected string (second argument) with none left over. @@ -477,7 +477,7 @@ class TestCommon(TestCmd): # Deprecated; retain for backwards compatibility. return self.must_contain_all_lines(output, lines, title, find) - def must_exist(self, *files): + def must_exist(self, *files) -> None: """Ensures that the specified file(s) must exist. An individual file be specified as a list of directory names, in which case the pathname will be constructed by concatenating them. Exits FAILED @@ -489,7 +489,7 @@ class TestCommon(TestCmd): print("Missing files: `%s'" % "', `".join(missing)) self.fail_test(missing) - def must_exist_one_of(self, files): + def must_exist_one_of(self, files) -> None: """Ensures that at least one of the specified file(s) exists. The filenames can be given as a list, where each entry may be a single path string, or a tuple of folder names and the final @@ -509,7 +509,7 @@ class TestCommon(TestCmd): print("Missing one of: `%s'" % "', `".join(missing)) self.fail_test(missing) - def must_match(self, file, expect, mode = 'rb', match=None, message=None, newline=None): + def must_match(self, file, expect, mode: str = 'rb', match=None, message=None, newline=None): """Matches the contents of the specified file (first argument) against the expected contents (second argument). The expected contents are a list of lines or a string which will be split @@ -527,7 +527,7 @@ class TestCommon(TestCmd): self.diff(expect, file_contents, 'contents ') raise - def must_match_file(self, file, golden_file, mode='rb', match=None, message=None, newline=None): + def must_match_file(self, file, golden_file, mode: str='rb', match=None, message=None, newline=None): """Matches the contents of the specified file (first argument) against the expected contents (second argument). The expected contents are a list of lines or a string which will be split @@ -548,7 +548,7 @@ class TestCommon(TestCmd): self.diff(golden_file_contents, file_contents, 'contents ') raise - def must_not_contain(self, file, banned, mode = 'rb', find = None): + def must_not_contain(self, file, banned, mode: str = 'rb', find = None) -> None: """Ensures that the specified file doesn't contain the banned text. """ file_contents = self.read(file, mode) @@ -561,7 +561,7 @@ class TestCommon(TestCmd): print(file_contents) self.fail_test() - def must_not_contain_any_line(self, output, lines, title=None, find=None): + def must_not_contain_any_line(self, output, lines, title=None, find=None) -> None: """Ensures that the specified output string (first argument) does not contain any of the specified lines (second argument). @@ -590,7 +590,7 @@ class TestCommon(TestCmd): def must_not_contain_lines(self, lines, output, title=None, find=None): return self.must_not_contain_any_line(output, lines, title, find) - def must_not_exist(self, *files): + def must_not_exist(self, *files) -> None: """Ensures that the specified file(s) must not exist. An individual file be specified as a list of directory names, in which case the pathname will be constructed by concatenating them. @@ -602,7 +602,7 @@ class TestCommon(TestCmd): print("Unexpected files exist: `%s'" % "', `".join(existing)) self.fail_test(existing) - def must_not_exist_any_of(self, files): + def must_not_exist_any_of(self, files) -> None: """Ensures that none of the specified file(s) exists. The filenames can be given as a list, where each entry may be a single path string, or a tuple of folder names and the final @@ -622,7 +622,7 @@ class TestCommon(TestCmd): print("Unexpected files exist: `%s'" % "', `".join(existing)) self.fail_test(existing) - def must_not_be_empty(self, file): + def must_not_be_empty(self, file) -> None: """Ensures that the specified file exists, and that it is not empty. Exits FAILED if the file doesn't exist or is empty. """ @@ -639,7 +639,7 @@ class TestCommon(TestCmd): print(f"File is empty: `{file}'") self.fail_test(file) - def must_not_be_writable(self, *files): + def must_not_be_writable(self, *files) -> None: """Ensures that the specified file(s) exist and are not writable. An individual file can be specified as a list of directory names, in which case the pathname will be constructed by concatenating @@ -656,7 +656,7 @@ class TestCommon(TestCmd): self.fail_test(missing + writable) def _complete(self, actual_stdout, expected_stdout, - actual_stderr, expected_stderr, status, match): + actual_stderr, expected_stderr, status, match) -> None: """ Post-processes running a subcommand, checking for failure status and displaying output appropriately. @@ -716,7 +716,7 @@ class TestCommon(TestCmd): sys.stderr.write(f'Exception trying to execute: {cmd_args}\n') raise e - def finish(self, popen, stdout = None, stderr = '', status = 0, **kw): + def finish(self, popen, stdout = None, stderr: str = '', status: int = 0, **kw) -> None: """ Finishes and waits for the process being run under control of the specified popen argument. Additional arguments are similar @@ -740,7 +740,7 @@ class TestCommon(TestCmd): self.stderr(), stderr, status, match) def run(self, options = None, arguments = None, - stdout = None, stderr = '', status = 0, **kw): + stdout = None, stderr: str = '', status: int = 0, **kw) -> None: """Runs the program under test, checking that the test succeeded. The parameters are the same as the base TestCmd.run() method, @@ -775,7 +775,7 @@ class TestCommon(TestCmd): self._complete(self.stdout(), stdout, self.stderr(), stderr, status, match) - def skip_test(self, message="Skipping test.\n", from_fw=False): + def skip_test(self, message: str="Skipping test.\n", from_fw: bool=False) -> None: """Skips a test. Proper test-skipping behavior is dependent on the external @@ -818,7 +818,7 @@ class TestCommon(TestCmd): self.pass_test() @staticmethod - def detailed_diff(value, expect): + def detailed_diff(value, expect) -> str: v_split = value.split('\n') e_split = expect.split('\n') if len(v_split) != len(e_split): diff --git a/testing/framework/TestCommonTests.py b/testing/framework/TestCommonTests.py index 6d8c27f..c551771 100644 --- a/testing/framework/TestCommonTests.py +++ b/testing/framework/TestCommonTests.py @@ -60,15 +60,15 @@ class TestCommonTestCase(unittest.TestCase): """Base class for TestCommon test cases, fixture and utility methods.""" create_run_env = True - def setUp(self): + def setUp(self) -> None: self.orig_cwd = os.getcwd() if self.create_run_env: self.run_env = TestCmd.TestCmd(workdir = '') - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.orig_cwd) - def set_up_execution_scripts(self): + def set_up_execution_scripts(self) -> None: run_env = self.run_env run_env.subdir('sub dir') @@ -118,7 +118,7 @@ class TestCommonTestCase(unittest.TestCase): run_env.write(self.stdin_script, wrapper % stdin_body) - def run_execution_test(self, script, expect_stdout, expect_stderr): + def run_execution_test(self, script, expect_stdout, expect_stderr) -> None: self.set_up_execution_scripts() run_env = self.run_env @@ -150,7 +150,7 @@ class TestCommonTestCase(unittest.TestCase): class __init__TestCase(TestCommonTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test initialization""" run_env = self.run_env @@ -170,7 +170,7 @@ class __init__TestCase(TestCommonTestCase): class banner_TestCase(TestCommonTestCase): create_run_env = False - def test_banner(self): + def test_banner(self) -> None: """Test banner()""" tc = TestCommon.TestCommon(workdir='') @@ -191,7 +191,7 @@ class banner_TestCase(TestCommonTestCase): assert b == "xyzzy ----", b class must_be_writable_TestCase(TestCommonTestCase): - def test_file_does_not_exists(self): + def test_file_does_not_exists(self) -> None: """Test must_be_writable(): file does not exist""" run_env = self.run_env @@ -207,7 +207,7 @@ class must_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_writable_file_exists(self): + def test_writable_file_exists(self) -> None: """Test must_be_writable(): writable file exists""" run_env = self.run_env @@ -229,7 +229,7 @@ class must_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_non_writable_file_exists(self): + def test_non_writable_file_exists(self) -> None: """Test must_be_writable(): non-writable file exists""" run_env = self.run_env @@ -251,7 +251,7 @@ class must_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_file_specified_as_list(self): + def test_file_specified_as_list(self) -> None: """Test must_be_writable(): file specified as list""" run_env = self.run_env @@ -276,7 +276,7 @@ class must_be_writable_TestCase(TestCommonTestCase): class must_contain_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_contain(): success""" run_env = self.run_env @@ -293,7 +293,7 @@ class must_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_success_index_0(self): + def test_success_index_0(self) -> None: """Test must_contain(): success at index 0""" run_env = self.run_env @@ -310,7 +310,7 @@ class must_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_missing(self): + def test_file_missing(self) -> None: """Test must_contain(): file missing""" run_env = self.run_env @@ -326,7 +326,7 @@ class must_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("No such file or directory:") != -1, stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_contain(): failure""" run_env = self.run_env @@ -350,7 +350,7 @@ class must_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_mode(self): + def test_mode(self) -> None: """Test must_contain(): mode""" run_env = self.run_env @@ -372,7 +372,7 @@ class must_contain_TestCase(TestCommonTestCase): class must_contain_all_lines_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_contain_all_lines(): success""" run_env = self.run_env @@ -405,7 +405,7 @@ class must_contain_all_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_contain_all_lines(): failure""" run_env = self.run_env @@ -443,7 +443,7 @@ class must_contain_all_lines_TestCase(TestCommonTestCase): assert stdout == expect, assert_display(expect, stdout, stderr) assert stderr.find("FAILED") != -1, stderr - def test_find(self): + def test_find(self) -> None: """Test must_contain_all_lines(): find""" run_env = self.run_env @@ -477,7 +477,7 @@ class must_contain_all_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_title(self): + def test_title(self) -> None: """Test must_contain_all_lines(): title""" run_env = self.run_env @@ -518,7 +518,7 @@ class must_contain_all_lines_TestCase(TestCommonTestCase): class must_contain_any_line_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_contain_any_line(): success""" run_env = self.run_env @@ -551,7 +551,7 @@ class must_contain_any_line_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_contain_any_line(): failure""" run_env = self.run_env @@ -589,7 +589,7 @@ class must_contain_any_line_TestCase(TestCommonTestCase): assert stdout == expect, assert_display(expect, stdout, stderr) assert stderr.find("FAILED") != -1, stderr - def test_find(self): + def test_find(self) -> None: """Test must_contain_any_line(): find""" run_env = self.run_env @@ -623,7 +623,7 @@ class must_contain_any_line_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_title(self): + def test_title(self) -> None: """Test must_contain_any_line(): title""" run_env = self.run_env @@ -664,7 +664,7 @@ class must_contain_any_line_TestCase(TestCommonTestCase): class must_contain_exactly_lines_TestCase(TestCommonTestCase): - def test_success_list(self): + def test_success_list(self) -> None: """Test must_contain_exactly_lines(): success (input list)""" run_env = self.run_env @@ -697,7 +697,7 @@ class must_contain_exactly_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_success_string(self): + def test_success_string(self) -> None: """Test must_contain_exactly_lines(): success (input string)""" run_env = self.run_env @@ -730,7 +730,7 @@ class must_contain_exactly_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_contain_exactly_lines(): failure""" run_env = self.run_env @@ -770,7 +770,7 @@ class must_contain_exactly_lines_TestCase(TestCommonTestCase): assert stdout == expect, assert_display(expect, stdout, stderr) assert stderr.find("FAILED") != -1, stderr - def test_find(self): + def test_find(self) -> None: """Test must_contain_exactly_lines(): find""" run_env = self.run_env @@ -812,7 +812,7 @@ class must_contain_exactly_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_title(self): + def test_title(self) -> None: """Test must_contain_exactly_lines(): title""" run_env = self.run_env @@ -855,7 +855,7 @@ class must_contain_exactly_lines_TestCase(TestCommonTestCase): class must_contain_lines_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_contain_lines(): success""" run_env = self.run_env @@ -886,7 +886,7 @@ class must_contain_lines_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_contain_lines(): failure""" run_env = self.run_env @@ -927,7 +927,7 @@ class must_contain_lines_TestCase(TestCommonTestCase): class must_exist_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_exist(): success""" run_env = self.run_env @@ -944,7 +944,7 @@ class must_exist_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_exist(): failure""" run_env = self.run_env @@ -960,7 +960,7 @@ class must_exist_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_file_specified_as_list(self): + def test_file_specified_as_list(self) -> None: """Test must_exist(): file specified as list""" run_env = self.run_env @@ -979,7 +979,7 @@ class must_exist_TestCase(TestCommonTestCase): assert stderr == "PASSED\n", stderr @unittest.skipIf(sys.platform == 'win32', "Skip symlink test on win32") - def test_broken_link(self) : + def test_broken_link(self) -> None : """Test must_exist(): exists but it is a broken link""" run_env = self.run_env @@ -997,7 +997,7 @@ class must_exist_TestCase(TestCommonTestCase): assert stderr == "PASSED\n", stderr class must_exist_one_of_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_exist_one_of(): success""" run_env = self.run_env @@ -1014,7 +1014,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_exist_one_of(): failure""" run_env = self.run_env @@ -1030,7 +1030,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_files_specified_as_list(self): + def test_files_specified_as_list(self) -> None: """Test must_exist_one_of(): files specified as list""" run_env = self.run_env @@ -1047,7 +1047,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_files_specified_with_wildcards(self): + def test_files_specified_with_wildcards(self) -> None: """Test must_exist_one_of(): files specified with wildcards""" run_env = self.run_env @@ -1064,7 +1064,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_given_as_list(self): + def test_file_given_as_list(self) -> None: """Test must_exist_one_of(): file given as list""" run_env = self.run_env @@ -1083,7 +1083,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_given_as_sequence(self): + def test_file_given_as_sequence(self) -> None: """Test must_exist_one_of(): file given as sequence""" run_env = self.run_env @@ -1103,7 +1103,7 @@ class must_exist_one_of_TestCase(TestCommonTestCase): assert stderr == "PASSED\n", stderr class must_match_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_match(): success""" run_env = self.run_env @@ -1120,7 +1120,7 @@ class must_match_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_does_not_exists(self): + def test_file_does_not_exists(self) -> None: """Test must_match(): file does not exist""" run_env = self.run_env @@ -1136,7 +1136,7 @@ class must_match_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("No such file or directory:") != -1, stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_match(): failure""" run_env = self.run_env @@ -1165,7 +1165,7 @@ class must_match_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_mode(self): + def test_mode(self) -> None: """Test must_match(): mode""" run_env = self.run_env @@ -1187,7 +1187,7 @@ class must_match_TestCase(TestCommonTestCase): class must_not_be_writable_TestCase(TestCommonTestCase): - def test_file_does_not_exists(self): + def test_file_does_not_exists(self) -> None: """Test must_not_be_writable(): file does not exist""" run_env = self.run_env @@ -1203,7 +1203,7 @@ class must_not_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_writable_file_exists(self): + def test_writable_file_exists(self) -> None: """Test must_not_be_writable(): writable file exists""" run_env = self.run_env @@ -1225,7 +1225,7 @@ class must_not_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_non_writable_file_exists(self): + def test_non_writable_file_exists(self) -> None: """Test must_not_be_writable(): non-writable file exists""" run_env = self.run_env @@ -1247,7 +1247,7 @@ class must_not_be_writable_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_specified_as_list(self): + def test_file_specified_as_list(self) -> None: """Test must_not_be_writable(): file specified as list""" run_env = self.run_env @@ -1273,7 +1273,7 @@ class must_not_be_writable_TestCase(TestCommonTestCase): class must_not_contain_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_not_contain(): success""" run_env = self.run_env @@ -1290,7 +1290,7 @@ class must_not_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_does_not_exist(self): + def test_file_does_not_exist(self) -> None: """Test must_not_contain(): file does not exist""" run_env = self.run_env @@ -1306,7 +1306,7 @@ class must_not_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("No such file or directory:") != -1, stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_not_contain(): failure""" run_env = self.run_env @@ -1331,7 +1331,7 @@ class must_not_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_failure_index_0(self): + def test_failure_index_0(self) -> None: """Test must_not_contain(): failure at index 0""" run_env = self.run_env @@ -1356,7 +1356,7 @@ class must_not_contain_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_mode(self): + def test_mode(self) -> None: """Test must_not_contain(): mode""" run_env = self.run_env @@ -1378,7 +1378,7 @@ class must_not_contain_TestCase(TestCommonTestCase): class must_not_contain_any_line_TestCase(TestCommonTestCase): - def test_failure(self): + def test_failure(self) -> None: """Test must_not_contain_any_line(): failure""" run_env = self.run_env @@ -1422,7 +1422,7 @@ class must_not_contain_any_line_TestCase(TestCommonTestCase): assert stdout == expect, assert_display(expect, stdout, stderr) assert stderr.find("FAILED") != -1, stderr - def test_find(self): + def test_find(self) -> None: """Test must_not_contain_any_line(): find""" run_env = self.run_env @@ -1454,7 +1454,7 @@ class must_not_contain_any_line_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_success(self): + def test_success(self) -> None: """Test must_not_contain_any_line(): success""" run_env = self.run_env @@ -1483,7 +1483,7 @@ class must_not_contain_any_line_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_title(self): + def test_title(self) -> None: """Test must_not_contain_any_line(): title""" run_env = self.run_env @@ -1528,7 +1528,7 @@ class must_not_contain_any_line_TestCase(TestCommonTestCase): class must_not_contain_lines_TestCase(TestCommonTestCase): - def test_failure(self): + def test_failure(self) -> None: """Test must_not_contain_lines(): failure""" run_env = self.run_env @@ -1570,7 +1570,7 @@ class must_not_contain_lines_TestCase(TestCommonTestCase): assert stdout == expect, assert_display(expect, stdout, stderr) assert stderr.find("FAILED") != -1, stderr - def test_success(self): + def test_success(self) -> None: """Test must_not_contain_lines(): success""" run_env = self.run_env @@ -1602,7 +1602,7 @@ class must_not_contain_lines_TestCase(TestCommonTestCase): class must_not_exist_TestCase(TestCommonTestCase): - def test_failure(self): + def test_failure(self) -> None: """Test must_not_exist(): failure""" run_env = self.run_env @@ -1619,7 +1619,7 @@ class must_not_exist_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_success(self): + def test_success(self) -> None: """Test must_not_exist(): success""" run_env = self.run_env @@ -1635,7 +1635,7 @@ class must_not_exist_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_specified_as_list(self): + def test_file_specified_as_list(self) -> None: """Test must_not_exist(): file specified as list""" run_env = self.run_env @@ -1653,7 +1653,7 @@ class must_not_exist_TestCase(TestCommonTestCase): assert stderr == "PASSED\n", stderr @unittest.skipIf(sys.platform == 'win32', "Skip symlink test on win32") - def test_existing_broken_link(self): + def test_existing_broken_link(self) -> None: """Test must_not_exist(): exists but it is a broken link""" run_env = self.run_env @@ -1671,7 +1671,7 @@ class must_not_exist_TestCase(TestCommonTestCase): assert stderr.find("FAILED") != -1, stderr class must_not_exist_any_of_TestCase(TestCommonTestCase): - def test_success(self): + def test_success(self) -> None: """Test must_not_exist_any_of(): success""" run_env = self.run_env @@ -1687,7 +1687,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_failure(self): + def test_failure(self) -> None: """Test must_not_exist_any_of(): failure""" run_env = self.run_env @@ -1704,7 +1704,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_files_specified_as_list(self): + def test_files_specified_as_list(self) -> None: """Test must_not_exist_any_of(): files specified as list""" run_env = self.run_env @@ -1720,7 +1720,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_files_specified_with_wildcards(self): + def test_files_specified_with_wildcards(self) -> None: """Test must_not_exist_any_of(): files specified with wildcards""" run_env = self.run_env @@ -1737,7 +1737,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_given_as_list(self): + def test_file_given_as_list(self) -> None: """Test must_not_exist_any_of(): file given as list""" run_env = self.run_env @@ -1756,7 +1756,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_given_as_sequence(self): + def test_file_given_as_sequence(self) -> None: """Test must_not_exist_any_of(): file given as sequence""" run_env = self.run_env @@ -1776,7 +1776,7 @@ class must_not_exist_any_of_TestCase(TestCommonTestCase): assert stderr == "PASSED\n", stderr class must_not_be_empty_TestCase(TestCommonTestCase): - def test_failure(self): + def test_failure(self) -> None: """Test must_not_be_empty(): failure""" run_env = self.run_env @@ -1793,7 +1793,7 @@ class must_not_be_empty_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr.find("FAILED") != -1, stderr - def test_success(self): + def test_success(self) -> None: """Test must_not_be_empty(): success""" run_env = self.run_env @@ -1810,7 +1810,7 @@ class must_not_be_empty_TestCase(TestCommonTestCase): stderr = run_env.stderr() assert stderr == "PASSED\n", stderr - def test_file_doesnt_exist(self): + def test_file_doesnt_exist(self) -> None: """Test must_not_be_empty(): failure""" run_env = self.run_env @@ -1827,7 +1827,7 @@ class must_not_be_empty_TestCase(TestCommonTestCase): assert stderr.find("FAILED") != -1, stderr class run_TestCase(TestCommonTestCase): - def test_argument_handling(self): + def test_argument_handling(self) -> None: """Test run(): argument handling""" script = lstrip("""\ @@ -1842,7 +1842,7 @@ class run_TestCase(TestCommonTestCase): self.run_execution_test(script, "", "") - def test_default_pass(self): + def test_default_pass(self) -> None: """Test run(): default arguments, script passes""" script = lstrip("""\ @@ -1855,7 +1855,7 @@ class run_TestCase(TestCommonTestCase): self.run_execution_test(script, "", "") - def test_default_fail(self): + def test_default_fail(self) -> None: """Test run(): default arguments, script fails""" script = lstrip("""\ @@ -1885,7 +1885,7 @@ class run_TestCase(TestCommonTestCase): self.run_execution_test(script, expect_stdout, expect_stderr) - def test_default_stderr(self): + def test_default_stderr(self) -> None: """Test run(): default arguments, error output""" script = lstrip("""\ from TestCommon import TestCommon @@ -1914,7 +1914,7 @@ class run_TestCase(TestCommonTestCase): self.run_execution_test(script, expect_stdout, expect_stderr) - def test_exception_handling(self): + def test_exception_handling(self) -> None: """Test run(): exception handling""" script = lstrip("""\ import TestCmd @@ -1954,7 +1954,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_ignore_stderr(self): + def test_ignore_stderr(self) -> None: """Test run(): ignore stderr""" script = lstrip("""\ @@ -1967,7 +1967,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_match_function_stdout(self): + def test_match_function_stdout(self) -> None: """Test run(): explicit match function, stdout""" script = lstrip("""\ @@ -1984,7 +1984,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_match_function_stderr(self): + def test_match_function_stderr(self) -> None: """Test run(): explicit match function, stderr""" script = lstrip("""\ @@ -2001,7 +2001,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_matched_status_fails(self): + def test_matched_status_fails(self) -> None: """Test run(): matched status, script fails""" script = lstrip("""\ @@ -2014,7 +2014,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_matched_stdout(self): + def test_matched_stdout(self) -> None: """Test run(): matched stdout""" script = lstrip("""\ @@ -2028,7 +2028,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_matched_stderr(self): + def test_matched_stderr(self) -> None: """Test run(): matched stderr""" script = lstrip("""\ @@ -2042,7 +2042,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_mismatched_status_pass(self): + def test_mismatched_status_pass(self) -> None: """Test run(): mismatched status, script passes""" script = lstrip("""\ @@ -2072,7 +2072,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_mismatched_status_fail(self): + def test_mismatched_status_fail(self) -> None: """Test run(): mismatched status, script fails""" script = lstrip("""\ @@ -2102,7 +2102,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_mismatched_stdout(self): + def test_mismatched_stdout(self) -> None: """Test run(): mismatched stdout""" script = lstrip("""\ @@ -2134,7 +2134,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_mismatched_stderr(self): + def test_mismatched_stderr(self) -> None: """Test run(): mismatched stderr""" script = lstrip("""\ @@ -2168,7 +2168,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_option_handling(self): + def test_option_handling(self) -> None: """Test run(): option handling""" script = lstrip("""\ @@ -2183,7 +2183,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_options_plus_arguments(self): + def test_options_plus_arguments(self) -> None: """Test run(): option handling with arguments""" script = lstrip("""\ @@ -2199,7 +2199,7 @@ TypeError: forced TypeError self.run_execution_test(script, "", "") - def test_signal_handling(self): + def test_signal_handling(self) -> None: """Test run(): signal handling""" try: @@ -2237,7 +2237,7 @@ TypeError: forced TypeError self.run_execution_test(script, expect_stdout, expect_stderr) - def test_stdin(self): + def test_stdin(self) -> None: """Test run(): stdin handling""" script = lstrip("""\ @@ -2265,7 +2265,7 @@ TypeError: forced TypeError class start_TestCase(TestCommonTestCase): - def test_option_handling(self): + def test_option_handling(self) -> None: """Test start(): option handling""" script = lstrip("""\ @@ -2281,7 +2281,7 @@ class start_TestCase(TestCommonTestCase): self.run_execution_test(script, "", "") - def test_options_plus_arguments(self): + def test_options_plus_arguments(self) -> None: """Test start(): option handling with arguments""" script = lstrip("""\ @@ -2301,7 +2301,7 @@ class start_TestCase(TestCommonTestCase): class skip_test_TestCase(TestCommonTestCase): - def test_skip_test(self): + def test_skip_test(self) -> None: """Test skip_test()""" run_env = self.run_env @@ -2356,7 +2356,7 @@ class skip_test_TestCase(TestCommonTestCase): class variables_TestCase(TestCommonTestCase): - def test_variables(self): + def test_variables(self) -> None: """Test global variables""" run_env = self.run_env diff --git a/testing/framework/TestRuntest.py b/testing/framework/TestRuntest.py index 378f441..d2b3b70 100644 --- a/testing/framework/TestRuntest.py +++ b/testing/framework/TestRuntest.py @@ -99,7 +99,7 @@ class TestRuntest(TestCommon): initializations. """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialize a Runtest testing object. If they're not overridden by keyword arguments, this @@ -161,7 +161,7 @@ class TestRuntest(TestCommon): os.environ['PYTHONPATH'] = '' - def write_fake_scons_source_tree(self): + def write_fake_scons_source_tree(self) -> None: os.mkdir('scripts') self.write('scripts/scons.py', fake_scons_py) @@ -170,13 +170,13 @@ class TestRuntest(TestCommon): os.mkdir('SCons/Script') self.write('SCons/Script/__init__.py', fake___init___py) - def write_failing_test(self, name): + def write_failing_test(self, name) -> None: self.write(name, failing_test_template) - def write_no_result_test(self, name): + def write_no_result_test(self, name) -> None: self.write(name, no_result_test_template) - def write_passing_test(self, name): + def write_passing_test(self, name) -> None: self.write(name, passing_test_template) # Local Variables: diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py index b65d807..0211283 100644 --- a/testing/framework/TestSCons.py +++ b/testing/framework/TestSCons.py @@ -107,7 +107,7 @@ dll_ = dll_prefix if sys.platform == 'cygwin': # On Cygwin, os.path.normcase() lies, so just report back the # fact that the underlying Win32 OS is case-insensitive. - def case_sensitive_suffixes(s1, s2): + def case_sensitive_suffixes(s1, s2) -> int: return 0 else: def case_sensitive_suffixes(s1, s2): @@ -212,7 +212,7 @@ def initialize_sconsflags(ignore_python_version): return save_sconsflags -def restore_sconsflags(sconsflags): +def restore_sconsflags(sconsflags) -> None: if sconsflags is None: del os.environ['SCONSFLAGS'] else: @@ -232,7 +232,7 @@ class NoMatch(Exception): """ Exception for matchPart to indicate there was no match found in the passed logfile """ - def __init__(self, p): + def __init__(self, p) -> None: self.pos = p @@ -258,7 +258,7 @@ class TestSCons(TestCommon): scons_version = SConsVersion javac_is_gcj = False - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialize an SCons testing object. If they're not overridden by keyword arguments, this @@ -416,7 +416,7 @@ class TestSCons(TestCommon): return None - def wrap_stdout(self, build_str="", read_str="", error=0, cleaning=0) -> str: + def wrap_stdout(self, build_str: str="", read_str: str="", error: int=0, cleaning: int=0) -> str: """Wraps "expect" strings in SCons boilerplate. Given strings of expected output specific to a test, @@ -448,7 +448,7 @@ class TestSCons(TestCommon): build_str + \ term - def run(self, *args, **kw): + def run(self, *args, **kw) -> None: """ Set up SCONSFLAGS for every command so test scripts don't need to worry about unexpected warnings in their output. @@ -482,7 +482,7 @@ class TestSCons(TestCommon): # kw['options'] = ' '.join(options) # TestCommon.run(self, *args, **kw) - def up_to_date(self, arguments='.', read_str="", **kw): + def up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: """Asserts that all of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. @@ -498,7 +498,7 @@ class TestSCons(TestCommon): kw['match'] = self.match_re_dotall self.run(**kw) - def not_up_to_date(self, arguments='.', read_str="", **kw): + def not_up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: """Asserts that none of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. @@ -529,7 +529,7 @@ class TestSCons(TestCommon): kw['arguments'] = f"{option} {arguments}" return self.run(**kw) - def deprecated_wrap(self, msg): + def deprecated_wrap(self, msg) -> str: """ Calculate the pattern that matches a deprecation warning. """ @@ -592,7 +592,7 @@ class TestSCons(TestCommon): """ warning = self.deprecated_fatal(warn, msg) - def RunPair(option, expected): + def RunPair(option, expected) -> None: # run the same test with the option on the command line and # then with the option passed via SetOption(). self.run(options=f"--warn={option}", @@ -616,7 +616,7 @@ class TestSCons(TestCommon): return warning - def diff_substr(self, expect, actual, prelen=20, postlen=40): + def diff_substr(self, expect, actual, prelen: int=20, postlen: int=40) -> str: i = 0 for x, y in zip(expect, actual): if x != y: @@ -668,7 +668,7 @@ class TestSCons(TestCommon): return s @staticmethod - def to_bytes_re_sub(pattern, repl, str, count=0, flags=0): + def to_bytes_re_sub(pattern, repl, str, count: int=0, flags: int=0): """ Wrapper around re.sub to change pattern and repl to bytes to work with both python 2 & 3 @@ -749,7 +749,7 @@ class TestSCons(TestCommon): return database_prefix - def unlink_sconsignfile(self, name='.sconsign.dblite'): + def unlink_sconsignfile(self, name: str='.sconsign.dblite') -> None: """Delete the sconsign file. Note on python it seems to append .p3 to the file name so we take @@ -1066,7 +1066,7 @@ class TestSCons(TestCommon): result.append(os.path.join(dirpath, fname)) return sorted(result) - def Qt_dummy_installation(self, dir='qt'): + def Qt_dummy_installation(self, dir: str='qt') -> None: # create a dummy qt installation self.subdir(dir, [dir, 'bin'], [dir, 'include'], [dir, 'lib']) @@ -1172,7 +1172,7 @@ else: self.QT_UIC = f"{_python_} {self.workpath(dir, 'bin', 'myuic.py')}" self.QT_LIB_DIR = self.workpath(dir, 'lib') - def Qt_create_SConstruct(self, place, qt_tool='qt3'): + def Qt_create_SConstruct(self, place, qt_tool: str='qt3') -> None: if isinstance(place, list): place = test.workpath(*place) @@ -1221,12 +1221,12 @@ SConscript(sconscript) # to use cygwin compilers on cmd.exe -> uncomment following line # Configure_lib = 'm' - def coverage_run(self): + def coverage_run(self) -> bool: """ Check if the the tests are being run under coverage. """ return 'COVERAGE_PROCESS_START' in os.environ or 'COVERAGE_FILE' in os.environ - def skip_if_not_msvc(self, check_platform=True): + def skip_if_not_msvc(self, check_platform: bool=True) -> None: """ Skip test if MSVC is not available. Check whether we are on a Windows platform and skip the test if @@ -1251,10 +1251,10 @@ SConscript(sconscript) pass def checkConfigureLogAndStdout(self, checks, - logfile='config.log', - sconf_dir='.sconf_temp', - sconstruct="SConstruct", - doCheckLog=True, doCheckStdout=True): + logfile: str='config.log', + sconf_dir: str='.sconf_temp', + sconstruct: str="SConstruct", + doCheckLog: bool=True, doCheckStdout: bool=True): """ Verify expected output from Configure. Used to verify the expected output from using Configure() @@ -1386,7 +1386,7 @@ SConscript(sconscript) def checkLogAndStdout(self, checks, results, cached, logfile, sconf_dir, sconstruct, - doCheckLog=True, doCheckStdout=True): + doCheckLog: bool=True, doCheckStdout: bool=True): """ Verify expected output from Configure. Used to verify the expected output from using Configure() @@ -1547,7 +1547,7 @@ SConscript(sconscript) # see also sys.prefix documentation return python_minor_version_string() - def get_platform_python_info(self, python_h_required=False): + def get_platform_python_info(self, python_h_required: bool=False): """Return information about Python. Returns a path to a Python executable suitable for testing on @@ -1640,7 +1640,7 @@ else: restore_sconsflags(sconsflags) return p - def wait_for(self, fname, timeout=20.0, popen=None): + def wait_for(self, fname, timeout: float=20.0, popen=None) -> None: """ Waits for the specified file name to exist. """ @@ -1702,7 +1702,7 @@ else: class Stat: - def __init__(self, name, units, expression, convert=None): + def __init__(self, name, units, expression, convert=None) -> None: if convert is None: convert = lambda x: x self.name = name @@ -1736,7 +1736,7 @@ StatList = [ class TimeSCons(TestSCons): """Class for timing SCons.""" - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: """ In addition to normal TestSCons.TestSCons intialization, this enables verbose mode (which causes the command lines to @@ -1784,7 +1784,7 @@ class TimeSCons(TestSCons): self.test_dir = os.path.join(self.orig_cwd, self.test_dir) self.copy_timing_configuration(self.test_dir, self.workpath()) - def main(self, *args, **kw): + def main(self, *args, **kw) -> None: """ The main entry point for standard execution of timings. @@ -1814,7 +1814,7 @@ class TimeSCons(TestSCons): self.full(*args, **kw) self.null(*args, **kw) - def trace(self, graph, name, value, units, sort=None): + def trace(self, graph, name, value, units, sort=None) -> None: fmt = "TRACE: graph=%s name=%s value=%s units=%s" line = fmt % (graph, name, value, units) if sort is not None: @@ -1823,7 +1823,7 @@ class TimeSCons(TestSCons): sys.stdout.write(line) sys.stdout.flush() - def report_traces(self, trace, stats): + def report_traces(self, trace, stats) -> None: self.trace('TimeSCons-elapsed', trace, self.elapsed_time(), @@ -1832,7 +1832,7 @@ class TimeSCons(TestSCons): for name, args in stats.items(): self.trace(name, trace, **args) - def uptime(self): + def uptime(self) -> None: try: fp = open('/proc/loadavg') except EnvironmentError: @@ -1856,7 +1856,7 @@ class TimeSCons(TestSCons): result[stat.name] = {'value': value, 'units': stat.units} return result - def add_timing_options(self, kw, additional=None): + def add_timing_options(self, kw, additional=None) -> None: """ Add the necessary timings options to the kw['options'] value. """ @@ -1865,7 +1865,7 @@ class TimeSCons(TestSCons): options += additional kw['options'] = f"{options} --debug=memory,time" - def startup(self, *args, **kw): + def startup(self, *args, **kw) -> None: """ Runs scons with the --help option. @@ -1886,7 +1886,7 @@ class TimeSCons(TestSCons): del stats['time-commands'] self.report_traces('startup', stats) - def full(self, *args, **kw): + def full(self, *args, **kw) -> None: """ Runs a full build of SCons. """ @@ -1899,7 +1899,7 @@ class TimeSCons(TestSCons): self.trace('full-memory', 'prebuild', **stats['memory-prebuild']) self.trace('full-memory', 'final', **stats['memory-final']) - def calibration(self, *args, **kw): + def calibration(self, *args, **kw) -> None: """ Runs a full build of SCons, but only reports calibration information (the variable(s) that were set for this configuration, @@ -1912,7 +1912,7 @@ class TimeSCons(TestSCons): sys.stdout.write(f'VARIABLE: {variable}={value}\n') sys.stdout.write(f'ELAPSED: {self.elapsed_time()}\n') - def null(self, *args, **kw): + def null(self, *args, **kw) -> None: """ Runs an up-to-date null build of SCons. """ @@ -1960,7 +1960,7 @@ class TimeSCons(TestSCons): self.endTime = time.perf_counter() return result - def copy_timing_configuration(self, source_dir, dest_dir): + def copy_timing_configuration(self, source_dir, dest_dir) -> None: """ Copies the timing configuration from the specified source_dir (the directory in which the controlling script lives) to the specified @@ -1985,7 +1985,7 @@ class TimeSCons(TestSCons): destination = source.replace(source_dir, dest_dir) shutil.copy2(source, destination) - def up_to_date(self, arguments='.', read_str="", **kw): + def up_to_date(self, arguments: str='.', read_str: str="", **kw) -> None: """Asserts that all of the targets listed in arguments is up to date, but does not make any assumptions on other targets. This function is most useful in conjunction with the -n option. diff --git a/testing/framework/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py index b001d79..92e436d 100644 --- a/testing/framework/TestSConsMSVS.py +++ b/testing/framework/TestSConsMSVS.py @@ -684,7 +684,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) return self._msvs_versions - def vcproj_sys_path(self, fname): + def vcproj_sys_path(self, fname) -> None: """ """ orig = 'sys.path = [ join(sys' @@ -700,7 +700,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) subdir=None, sconscript=None, python=None, project_guid=None, - vcproj_sccinfo='', sln_sccinfo=''): + vcproj_sccinfo: str='', sln_sccinfo: str=''): if not hasattr(self, '_msvs_versions'): self.msvs_versions() @@ -786,7 +786,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) return host - def validate_msvs_file(self, file): + def validate_msvs_file(self, file) -> None: try: x = ElementTree.parse(file) except: @@ -809,7 +809,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) minor = 0 if len(components) < 2 else int(components[1]) return major, minor - def _get_solution_file_format_version(self, vc_version): + def _get_solution_file_format_version(self, vc_version) -> str: """ Returns the Visual Studio format version expected in the .sln file. """ @@ -825,7 +825,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) else: raise SCons.Errors.UserError(f'Received unexpected VC version {vc_version}') - def _get_solution_file_vs_number(self, vc_version): + def _get_solution_file_vs_number(self, vc_version) -> str: """ Returns the Visual Studio number expected in the .sln file. """ @@ -848,7 +848,7 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions())) else: raise SCons.Errors.UserError(f'Received unexpected VC version {vc_version}') - def _get_vcxproj_file_tools_version(self, vc_version): + def _get_vcxproj_file_tools_version(self, vc_version) -> str: """ Returns the version entry expected in the project file. For .vcxproj files, this goes is ToolsVersion. diff --git a/testing/framework/TestSCons_time.py b/testing/framework/TestSCons_time.py index 282a9a6..b84bff2 100644 --- a/testing/framework/TestSCons_time.py +++ b/testing/framework/TestSCons_time.py @@ -155,7 +155,7 @@ class TestSCons_time(TestCommon): initializations. """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialize an SCons_time testing object. If they're not overridden by keyword arguments, this @@ -205,10 +205,10 @@ class TestSCons_time(TestCommon): else: return os.path.splitext(path) - def fake_logfile(self, logfile_name, index=0): + def fake_logfile(self, logfile_name, index: int=0) -> None: self.write(self.workpath(logfile_name), logfile_contents % locals()) - def profile_data(self, profile_name, python_name, call, body): + def profile_data(self, profile_name, python_name, call, body) -> None: profile_name = self.workpath(profile_name) python_name = self.workpath(python_name) d = { @@ -244,7 +244,7 @@ class TestSCons_time(TestCommon): x = x.replace('time\\-', f'time\\-[^{sep}]*') return x - def write_fake_scons_py(self): + def write_fake_scons_py(self) -> None: self.subdir('scripts') self.write('scripts/scons.py', scons_py) diff --git a/testing/framework/TestSConsign.py b/testing/framework/TestSConsign.py index b0562bf..9f02b49 100644 --- a/testing/framework/TestSConsign.py +++ b/testing/framework/TestSConsign.py @@ -55,7 +55,7 @@ class TestSConsign(TestSCons): "scons" itself, since we need to run scons to generate the .sconsign files that we want the sconsign script to read. """ - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: try: script_dir = os.environ['SCONS_SCRIPT_DIR'] except KeyError: @@ -92,7 +92,7 @@ class TestSConsign(TestSCons): def script_path(self, script): return os.path.join(self.script_dir, script) - def set_sconsign(self, sconsign): + def set_sconsign(self, sconsign) -> None: self.my_kw['program'] = sconsign def run_sconsign(self, *args, **kw): diff --git a/testing/framework/TestUnit/cli.py b/testing/framework/TestUnit/cli.py index 6aec735..defe5a1 100644 --- a/testing/framework/TestUnit/cli.py +++ b/testing/framework/TestUnit/cli.py @@ -22,7 +22,7 @@ def get_runner(): return getattr(runnermod, fromsplit[1]) -def run(suite=None): +def run(suite=None) -> None: runner = get_runner() if suite: if not runner().run(suite).wasSuccessful(): diff --git a/testing/framework/TestUnit/taprunner.py b/testing/framework/TestUnit/taprunner.py index 001db5c..6f8cb00 100644 --- a/testing/framework/TestUnit/taprunner.py +++ b/testing/framework/TestUnit/taprunner.py @@ -24,7 +24,7 @@ except ImportError: class TAPTestResult(TextTestResult): - def _process(self, test, msg, failtype = None, directive = None): + def _process(self, test, msg, failtype = None, directive = None) -> None: """ increase the counter, format and output TAP info """ # counterhack: increase test counter test.suite.tap_counter += 1 @@ -42,29 +42,29 @@ class TAPTestResult(TextTestResult): # [ ] write test __doc__ (if exists) in comment self.stream.flush() - def addSuccess(self, test): + def addSuccess(self, test) -> None: super().addSuccess(test) self._process(test, "ok") - def addFailure(self, test, err): + def addFailure(self, test, err) -> None: super().addFailure(test, err) self._process(test, "not ok", "FAIL") # [ ] add structured data about assertion - def addError(self, test, err): + def addError(self, test, err) -> None: super().addError(test, err) self._process(test, "not ok", "ERROR") # [ ] add structured data about exception - def addSkip(self, test, reason): + def addSkip(self, test, reason) -> None: super().addSkip(test, reason) self._process(test, "ok", directive=(" # SKIP %s" % reason)) - def addExpectedFailure(self, test, err): + def addExpectedFailure(self, test, err) -> None: super().addExpectedFailure(test, err) self._process(test, "not ok", directive=" # TODO") - def addUnexpectedSuccess(self, test): + def addUnexpectedSuccess(self, test) -> None: super().addUnexpectedSuccess(test) self._process(test, "not ok", "FAIL (unexpected success)") @@ -98,22 +98,22 @@ if __name__ == "__main__": import unittest class Test(unittest.TestCase): - def test_ok(self): + def test_ok(self) -> None: pass - def test_fail(self): + def test_fail(self) -> None: self.assertTrue(False) - def test_error(self): + def test_error(self) -> None: bad_symbol @unittest.skip("skipin'") - def test_skip(self): + def test_skip(self) -> None: pass @unittest.expectedFailure - def test_not_ready(self): + def test_not_ready(self) -> None: self.fail() @unittest.expectedFailure - def test_invalid_fail_mark(self): + def test_invalid_fail_mark(self) -> None: pass - def test_another_ok(self): + def test_another_ok(self) -> None: pass -- cgit v0.12 From 8bb3d1b1d8966b451ed2f3d63a38b32e99e7bde9 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 2 May 2023 10:49:49 -0600 Subject: Eliminate pylint warning on direct use of __call__ C2801: Unnecessarily calls dunder method __call__. Invoke instance directly. These were all in the same file (docbook tool) Signed-off-by: Mats Wichmann --- CHANGES.txt | 2 ++ SCons/Tool/docbook/__init__.py | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c594979..d0b5836 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -15,6 +15,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER embedded in a sequence, or by itself. The conditional C scanner thus did not always properly apply the defines. The regular C scanner does not use these, so was not affected. [fixes #4193] + - Simplify some code due to pylint observation: "C2801: Unnecessarily + calls dunder method __call__. Invoke instance directly." RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Tool/docbook/__init__.py b/SCons/Tool/docbook/__init__.py index 52e2911..ea5bf03 100644 --- a/SCons/Tool/docbook/__init__.py +++ b/SCons/Tool/docbook/__init__.py @@ -244,7 +244,7 @@ def __xml_scan(node, env, path, arg): # for xi:includes... contents = node.get_text_contents() return include_re.findall(contents) - + from lxml import etree xsl_tree = etree.parse(xsl_file) @@ -490,7 +490,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): # Set the fixed base_dir kw['base_dir'] = 'OEBPS/' - tocncx = __builder.__call__(env, 'toc.ncx', source[0], **kw) + tocncx = __builder(env, 'toc.ncx', source[0], **kw) cxml = env.File('META-INF/container.xml') env.SideEffect(cxml, tocncx) @@ -524,7 +524,7 @@ def DocbookHtml(env, target, source=None, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - r = __builder.__call__(env, __ensure_suffix(t,'.html'), s, **kw) + r = __builder(env, __ensure_suffix(t,'.html'), s, **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) @@ -556,7 +556,7 @@ def DocbookHtmlChunked(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -591,7 +591,7 @@ def DocbookHtmlhelp(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -617,10 +617,10 @@ def DocbookPdf(env, target, source=None, *args, **kw): result = [] for t,s in zip(target,source): t, stem = __ensure_suffix_stem(t, '.pdf') - xsl = __builder.__call__(env, stem+'.fo', s, **kw) + xsl = __builder(env, stem+'.fo', s, **kw) result.extend(xsl) env.Depends(xsl, kw['DOCBOOK_XSL']) - result.extend(__fop_builder.__call__(env, t, xsl, **kw)) + result.extend(__fop_builder(env, t, xsl, **kw)) return result @@ -681,7 +681,7 @@ def DocbookMan(env, target, source=None, *args, **kw): # We have to completely rely on the given target name outfiles.append(t) - __builder.__call__(env, outfiles[0], s, **kw) + __builder(env, outfiles[0], s, **kw) env.Depends(outfiles[0], kw['DOCBOOK_XSL']) result.append(outfiles[0]) if len(outfiles) > 1: @@ -707,10 +707,10 @@ def DocbookSlidesPdf(env, target, source=None, *args, **kw): result = [] for t,s in zip(target,source): t, stem = __ensure_suffix_stem(t, '.pdf') - xsl = __builder.__call__(env, stem+'.fo', s, **kw) + xsl = __builder(env, stem+'.fo', s, **kw) env.Depends(xsl, kw['DOCBOOK_XSL']) result.extend(xsl) - result.extend(__fop_builder.__call__(env, t, xsl, **kw)) + result.extend(__fop_builder(env, t, xsl, **kw)) return result @@ -740,7 +740,7 @@ def DocbookSlidesHtml(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -762,7 +762,7 @@ def DocbookXInclude(env, target, source, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - result.extend(__builder.__call__(env, t, s, **kw)) + result.extend(__builder(env, t, s, **kw)) return result @@ -782,7 +782,7 @@ def DocbookXslt(env, target, source=None, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - r = __builder.__call__(env, t, s, **kw) + r = __builder(env, t, s, **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) -- cgit v0.12 From 1ee43f4691dc7ab651fd22f07748c237f0301675 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 2 May 2023 11:28:46 -0600 Subject: Change bas64 decodestring -> decodebytes The former was an alias in Python 3, deprecated since 3.1. Use the replacement. Signed-off-by: Mats Wichmann --- CHANGES.txt | 2 ++ SCons/Tool/msvs.py | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d0b5836..72d1aa6 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -17,6 +17,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER not use these, so was not affected. [fixes #4193] - 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. + Only used in msvs.py. Use base64.decodebytes instead. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 86df1ef..d218038 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -777,7 +777,7 @@ class _GenerateV6DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -798,7 +798,7 @@ class _GenerateV6DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. # it has a "# " in front of it, so we strip that. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1095,7 +1095,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1115,7 +1115,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1592,7 +1592,7 @@ class _GenerateV7DSW(_DSWGenerator): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise -- 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 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 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 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