From 46aae9c7906a8638d90488bdd2f3c6c964bd5e8d Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 22 Oct 2019 09:51:51 -0500 Subject: Add Python scanner and tests This change adds a python scanner that allows consumers to take dependencies upon any packages imported by scripts that are run. It also adds tests to verify proper functionality of the scanner. --- src/engine/SCons/Scanner/Python.py | 156 ++++++++++++++++++ src/engine/SCons/Scanner/PythonTests.py | 271 ++++++++++++++++++++++++++++++++ 2 files changed, 427 insertions(+) create mode 100644 src/engine/SCons/Scanner/Python.py create mode 100644 src/engine/SCons/Scanner/PythonTests.py diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py new file mode 100644 index 0000000..eddff0f --- /dev/null +++ b/src/engine/SCons/Scanner/Python.py @@ -0,0 +1,156 @@ +"""SCons.Scanner.Python + +This module implements the dependency scanner for Python code. + +One important note about the design is that this does not take any dependencies +upon packages or binaries in the Python installation unless they are listed in +PYTHONPATH. To do otherwise would have required code to determine where the +Python installation is, which is outside of the scope of a scanner like this. +If consumers want to pick up dependencies upon these packages, they must put +those directories in PYTHONPATH. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# 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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import itertools +import os +import re +import SCons.Scanner + +# Capture python "from a import b" and "import a" statements. +from_cre = re.compile('^\s*from\s+([^\s]+)\s+import\s+(.*)', re.M) +import_cre = re.compile('^\s*import\s+([^\s]+)', re.M) + + +def path_function(env, dir=None, target=None, source=None, argument=None): + """Retrieves a tuple with all search paths.""" + paths = env['ENV'].get('PYTHONPATH', '').split(os.pathsep) + if source: + paths.append(source[0].dir.abspath) + return tuple(paths) + + +def find_include_names(node): + """ + Scans the node for all imports. + + Returns a list of tuples. Each tuple has two elements: + 1. The main import (e.g. module, module.file, module.module2) + 2. Additional optional imports that could be functions or files + in the case of a "from X import Y" statement. In the case of a + normal "import" statement, this is None. + """ + text = node.get_text_contents() + all_matches = [] + matches = from_cre.findall(text) + if matches: + for match in matches: + imports = match[1].split(',') + all_matches.append((match[0], [i.strip() for i in imports])) + + matches = import_cre.findall(text) + if matches: + for match in matches: + all_matches.append((match, None)) + + return all_matches + + +def scan(node, env, path=()): + # cache the includes list in node so we only scan it once: + if node.includes is not None: + includes = node.includes + else: + includes = find_include_names(node) + # Intern the names of the include files. Saves some memory + # if the same header is included many times. + node.includes = list(map(SCons.Util.silent_intern, includes)) + + # XXX TODO: Sort? + nodes = [] + if callable(path): + path = path() + for module, imports in includes: + is_relative = module.startswith('.') + if is_relative: + # This is a relative include, so we must ignore PYTHONPATH. + module_lstripped = module.lstrip('.') + # One dot is current directory, two is parent, three is + # grandparent, etc. + num_parents = len(module) - len(module_lstripped) - 1 + current_dir = node.get_dir() + for i in itertools.repeat(None, num_parents): + current_dir = current_dir.up() + + search_paths = [current_dir.abspath] + search_string = module_lstripped + else: + search_paths = path + search_string = module + + module_components = search_string.split('.') + for search_path in search_paths: + candidate_path = os.path.join(search_path, *module_components) + # The import stored in "module" could refer to a directory or file. + import_dirs = [] + if os.path.isdir(candidate_path): + import_dirs = module_components + + # Because this resolved to a directory, there is a chance that + # additional imports (e.g. from module import A, B) could refer + # to files to import. + if imports: + for imp in imports: + file = os.path.join(candidate_path, imp + '.py') + if os.path.isfile(file): + nodes.append(file) + elif os.path.isfile(candidate_path + '.py'): + nodes.append(candidate_path + '.py') + import_dirs = module_components[:-1] + + # We can ignore imports because this resolved to a file. Any + # additional imports (e.g. from module.file import A, B) would + # only refer to functions in this file. + + # Take a dependency on all __init__.py files from all imported + # packages unless it's a relative import. If it's a relative + # import, we don't need to take the dependency because Python + # requires that all referenced packages have already been imported, + # which means that the dependency has already been established. + if import_dirs and not is_relative: + for i in range(len(import_dirs)): + init_components = module_components[:i+1] + ['__init__.py'] + init_path = os.path.join(search_path, *(init_components)) + if os.path.isfile(init_path): + nodes.append(init_path) + break + + return sorted(nodes) + + +PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', skeys=['.py'], + path_function=path_function, recursive=1) diff --git a/src/engine/SCons/Scanner/PythonTests.py b/src/engine/SCons/Scanner/PythonTests.py new file mode 100644 index 0000000..4db9215 --- /dev/null +++ b/src/engine/SCons/Scanner/PythonTests.py @@ -0,0 +1,271 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# 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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.compat + +import collections +import os +import unittest + +import TestCmd + +import SCons.Node.FS +import SCons.Scanner.Python + +test = TestCmd.TestCmd(workdir='') + +# This directory is a simple empty package. +test.subdir('simple_package') +test.write(['simple_package', '__init__.py'], '') +test.write(['simple_package', 'module.py'], '') + +# Two files that import from simple_package. +test.write('imports_simple_package.py', r""" +import simple_package +""") +test.write('import_simple_package_module.py', r""" +import simple_package.module +""") +test.write('from_import_simple_package_module.py', r""" +from simple_package import module +""") + +# This directory holds a script that imports another from the current dir. +test.subdir('curdir_reference') +test.write(['curdir_reference', 'script.py'], r""" +from . import helper +""") +test.write(['curdir_reference', 'helper.py'], r'') + +# Create the directory structure: +# imports_nested3.py +# nested1 +# |- __init__.py +# |- module.py +# |- nested2 +# | |- __init__.py +# | |- module.py +# | '- nested3 +# | |- __init__.py +# | |- imports_grandparent_module.py +# | |- imports_parent_module.py +# | |- imports_parent_then_submodule.py +# | '- module.py +# '- nested2a +# |- __init__.py +# '- module.py +# This is used for more advanced relative path test cases. +test.write('imports_nested3.py', r""" +import nested1.nested2.nested3 +""") +test.subdir('nested1', ['nested1', 'nested2'], ['nested1', 'nested2a'], + ['nested1', 'nested2', 'nested3']) +test.write(['nested1', '__init__.py'], r'') +test.write(['nested1', 'module.py'], r'') +test.write(['nested1', 'nested2', '__init__.py'], r'') +test.write(['nested1', 'nested2', 'module.py'], r'') +test.write(['nested1', 'nested2a', '__init__.py'], r'') +test.write(['nested1', 'nested2a', 'module.py'], r'') +test.write(['nested1', 'nested2', 'nested3', '__init__.py'], r'') +test.write(['nested1', 'nested2', 'nested3', + 'imports_grandparent_module.py'], r""" +from ... import module +""") +test.write(['nested1', 'nested2', 'nested3', 'imports_parent_module.py'], r""" +from .. import module +""") +test.write(['nested1', 'nested2', 'nested3', + 'imports_parent_then_submodule.py'], r""" +from ...nested2a import module +""") +test.write(['nested1', 'nested2', 'nested3', 'module.py'], r'') + +if os.path.normcase('foo') == os.path.normcase('FOO'): + my_normpath = os.path.normcase +else: + my_normpath = os.path.normpath + + +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)) + + +# Copied from LaTeXTests.py. +class DummyEnvironment(collections.UserDict): + def __init__(self, **kw): + collections.UserDict.__init__(self) + self.data.update(kw) + self.fs = SCons.Node.FS.FS(test.workpath('')) + self['ENV'] = {} + + def Dictionary(self, *args): + return self.data + + def subst(self, strSubst, target=None, source=None, conv=None): + if strSubst[0] == '$': + return self.data[strSubst[1:]] + return strSubst + + def subst_list(self, strSubst, target=None, source=None, conv=None): + if strSubst[0] == '$': + return [self.data[strSubst[1:]]] + return [[strSubst]] + + def subst_path(self, path, target=None, source=None, conv=None): + if not isinstance(path, list): + path = [path] + return list(map(self.subst, path)) + + def get_calculator(self): + return None + + def get_factory(self, factory): + return factory or self.fs.File + + def Dir(self, filename): + return self.fs.Dir(filename) + + def File(self, filename): + return self.fs.File(filename) + + +class PythonScannerTestPythonPath(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + path = s.path(env) + deps = s(env.File('imports_simple_package.py'), env, path) + files = ['simple_package/__init__.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportSimplePackage(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('imports_simple_package.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportSimplePackageModule(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('import_simple_package_module.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestFromImportSimplePackageModule(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('from_import_simple_package_module.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestCurdirReferenceScript(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.Dir('curdir_reference').File('script.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['curdir_reference/helper.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsNested3(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('imports_nested3.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['nested1/__init__.py', 'nested1/nested2/__init__.py', + 'nested1/nested2/nested3/__init__.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsGrandparentModule(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File( + 'nested1/nested2/nested3/imports_grandparent_module.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + # Note: there is some ambiguity here in what the scanner should return. + # Relative imports require that the referenced packages have already + # been imported. + files = ['nested1/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsParentModule(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File( + 'nested1/nested2/nested3/imports_parent_module.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['nested1/nested2/module.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File( + 'nested1/nested2/nested3/imports_parent_then_submodule.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['nested1/nested2a/module.py'] + deps_match(self, deps, files) + + +if __name__ == "__main__": + unittest.main() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 52f6c16a99633d6b226b7bfd36203425e9c5d53b Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 22 Oct 2019 10:20:35 -0500 Subject: Updated CHANGES.txt --- src/CHANGES.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index af448d5..c567f2b 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,10 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Adam Gross: + + - Added new module SCons.Scanner.PythonScanner to allow scanning .py files. + From Mathew Robinson: - Improved threading performance by ensuring NodeInfo is shared -- cgit v0.12 From 8be1911e74367a14dda42ba14baad03a774aa831 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 22 Oct 2019 10:22:15 -0500 Subject: Fixed typo in CHANGES.txt --- src/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index c567f2b..211f571 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -8,7 +8,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Adam Gross: - - Added new module SCons.Scanner.PythonScanner to allow scanning .py files. + - Added new module SCons.Scanner.Python to allow scanning .py files. From Mathew Robinson: -- cgit v0.12 From 702ec6e6ac1ea26546ed3ae9b7b5c597271c87a0 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Wed, 23 Oct 2019 11:22:24 -0500 Subject: Improvements to patch This change does the following: 1. Fixes bug related to "from a import b as c". 2. Adds test cases for "from a import b as c" and "import a as b". 3. Adds a few more tests to get to 100% coverage of Python.py. --- src/engine/SCons/Scanner/Python.py | 11 +++- src/engine/SCons/Scanner/PythonTests.py | 98 +++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 13 deletions(-) diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py index eddff0f..825928d 100644 --- a/src/engine/SCons/Scanner/Python.py +++ b/src/engine/SCons/Scanner/Python.py @@ -69,8 +69,15 @@ def find_include_names(node): matches = from_cre.findall(text) if matches: for match in matches: - imports = match[1].split(',') - all_matches.append((match[0], [i.strip() for i in imports])) + imports = [i.strip() for i in match[1].split(',')] + + # Add some custom logic to strip out "as" because the regex + # includes it. + last_import_split = imports[-1].split() + if len(last_import_split) > 1: + imports[-1] = last_import_split[0] + + all_matches.append((match[0], imports)) matches = import_cre.findall(text) if matches: diff --git a/src/engine/SCons/Scanner/PythonTests.py b/src/engine/SCons/Scanner/PythonTests.py index 4db9215..18f75e2 100644 --- a/src/engine/SCons/Scanner/PythonTests.py +++ b/src/engine/SCons/Scanner/PythonTests.py @@ -39,17 +39,30 @@ test = TestCmd.TestCmd(workdir='') # This directory is a simple empty package. test.subdir('simple_package') test.write(['simple_package', '__init__.py'], '') -test.write(['simple_package', 'module.py'], '') +test.write(['simple_package', 'module1.py'], '') +test.write(['simple_package', 'module2.py'], '') # Two files that import from simple_package. test.write('imports_simple_package.py', r""" import simple_package """) -test.write('import_simple_package_module.py', r""" -import simple_package.module +test.write('import_simple_package_module1.py', r""" +import simple_package.module1 """) -test.write('from_import_simple_package_module.py', r""" -from simple_package import module +test.write('import_simple_package_module1_as.py', r""" +import simple_package.module1 as m1 +""") +test.write('from_import_simple_package_module1.py', r""" +from simple_package import module1 +""") +test.write('from_import_simple_package_module1_as.py', r""" +from simple_package import module1 as m1 +""") +test.write('from_import_simple_package_modules_no_space.py', r""" +from simple_package import module1,module2 +""") +test.write('from_import_simple_package_modules_with_space.py', r""" +from simple_package import module1, module2 """) # This directory holds a script that imports another from the current dir. @@ -166,6 +179,17 @@ class PythonScannerTestPythonPath(unittest.TestCase): deps_match(self, deps, files) +class PythonScannerTestPythonCallablePath(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + env['ENV']['PYTHONPATH'] = test.workpath('') + path = lambda : s.path(env) + deps = s(env.File('imports_simple_package.py'), env, path) + files = ['simple_package/__init__.py'] + deps_match(self, deps, files) + + class PythonScannerTestImportSimplePackage(unittest.TestCase): def runTest(self): env = DummyEnvironment() @@ -176,26 +200,78 @@ class PythonScannerTestImportSimplePackage(unittest.TestCase): files = ['simple_package/__init__.py'] deps_match(self, deps, files) + # Repeat the test in case there are any issues caching includes. + deps = s(node, env, path) + deps_match(self, deps, files) + + +class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('import_simple_package_module1_as.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + + +class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('import_simple_package_module1.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + + +class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('from_import_simple_package_module1.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + + +class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase): + def runTest(self): + env = DummyEnvironment() + s = SCons.Scanner.Python.PythonScanner + node = env.File('from_import_simple_package_module1_as.py') + path = s.path(env, source=[node]) + deps = s(node, env, path) + files = ['simple_package/__init__.py', 'simple_package/module1.py'] + deps_match(self, deps, files) + -class PythonScannerTestImportSimplePackageModule(unittest.TestCase): +class PythonScannerTestFromImportSimplePackageModulesNoSpace( + unittest.TestCase): def runTest(self): env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner - node = env.File('import_simple_package_module.py') + node = env.File('from_import_simple_package_modules_no_space.py') path = s.path(env, source=[node]) deps = s(node, env, path) - files = ['simple_package/__init__.py', 'simple_package/module.py'] + files = ['simple_package/__init__.py', 'simple_package/module1.py', + 'simple_package/module2.py'] deps_match(self, deps, files) -class PythonScannerTestFromImportSimplePackageModule(unittest.TestCase): +class PythonScannerTestFromImportSimplePackageModulesWithSpace( + unittest.TestCase): def runTest(self): env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner - node = env.File('from_import_simple_package_module.py') + node = env.File('from_import_simple_package_modules_with_space.py') path = s.path(env, source=[node]) deps = s(node, env, path) - files = ['simple_package/__init__.py', 'simple_package/module.py'] + files = ['simple_package/__init__.py', 'simple_package/module1.py', + 'simple_package/module2.py'] deps_match(self, deps, files) -- cgit v0.12 From cdd4d0cc8f7c69b275860baa01293544c3bde40d Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Wed, 23 Oct 2019 11:26:23 -0500 Subject: Fix sider issue related to lambda usage --- src/engine/SCons/Scanner/PythonTests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Scanner/PythonTests.py b/src/engine/SCons/Scanner/PythonTests.py index 18f75e2..48f6cfc 100644 --- a/src/engine/SCons/Scanner/PythonTests.py +++ b/src/engine/SCons/Scanner/PythonTests.py @@ -184,8 +184,8 @@ class PythonScannerTestPythonCallablePath(unittest.TestCase): env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner env['ENV']['PYTHONPATH'] = test.workpath('') - path = lambda : s.path(env) - deps = s(env.File('imports_simple_package.py'), env, path) + deps = s(env.File('imports_simple_package.py'), env, + lambda : s.path(env)) files = ['simple_package/__init__.py'] deps_match(self, deps, files) -- cgit v0.12 From 5f3064a00556705cc5eebacab159091da29255b3 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Thu, 24 Oct 2019 14:12:40 -0400 Subject: Convert PythonTests to use directory fixture --- src/engine/SCons/Scanner/PythonTests.py | 80 +--------------------- .../python_scanner/curdir_reference/helper.py | 0 .../python_scanner/curdir_reference/script.py | 1 + .../from_import_simple_package_module1.py | 1 + .../from_import_simple_package_module1_as.py | 1 + .../from_import_simple_package_modules_no_space.py | 1 + ...rom_import_simple_package_modules_with_space.py | 1 + .../import_simple_package_module1.py | 1 + .../import_simple_package_module1_as.py | 1 + test/fixture/python_scanner/imports_nested3.py | 1 + .../python_scanner/imports_simple_package.py | 1 + test/fixture/python_scanner/nested1/__init__.py | 0 test/fixture/python_scanner/nested1/module.py | 0 .../python_scanner/nested1/nested2/__init__.py | 0 .../python_scanner/nested1/nested2/module.py | 0 .../nested1/nested2/nested3/__init__.py | 0 .../nested2/nested3/imports_grandparent_module.py | 1 + .../nested2/nested3/imports_parent_module.py | 1 + .../nested3/imports_parent_then_submodule.py | 1 + .../nested1/nested2/nested3/module.py | 0 .../python_scanner/nested1/nested2a/__init__.py | 0 .../python_scanner/nested1/nested2a/module.py | 0 .../python_scanner/simple_package/__init__.py | 0 .../python_scanner/simple_package/module1.py | 0 .../python_scanner/simple_package/module2.py | 0 25 files changed, 13 insertions(+), 79 deletions(-) create mode 100644 test/fixture/python_scanner/curdir_reference/helper.py create mode 100644 test/fixture/python_scanner/curdir_reference/script.py create mode 100644 test/fixture/python_scanner/from_import_simple_package_module1.py create mode 100644 test/fixture/python_scanner/from_import_simple_package_module1_as.py create mode 100644 test/fixture/python_scanner/from_import_simple_package_modules_no_space.py create mode 100644 test/fixture/python_scanner/from_import_simple_package_modules_with_space.py create mode 100644 test/fixture/python_scanner/import_simple_package_module1.py create mode 100644 test/fixture/python_scanner/import_simple_package_module1_as.py create mode 100644 test/fixture/python_scanner/imports_nested3.py create mode 100644 test/fixture/python_scanner/imports_simple_package.py create mode 100644 test/fixture/python_scanner/nested1/__init__.py create mode 100644 test/fixture/python_scanner/nested1/module.py create mode 100644 test/fixture/python_scanner/nested1/nested2/__init__.py create mode 100644 test/fixture/python_scanner/nested1/nested2/module.py create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/__init__.py create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/module.py create mode 100644 test/fixture/python_scanner/nested1/nested2a/__init__.py create mode 100644 test/fixture/python_scanner/nested1/nested2a/module.py create mode 100644 test/fixture/python_scanner/simple_package/__init__.py create mode 100644 test/fixture/python_scanner/simple_package/module1.py create mode 100644 test/fixture/python_scanner/simple_package/module2.py diff --git a/src/engine/SCons/Scanner/PythonTests.py b/src/engine/SCons/Scanner/PythonTests.py index 48f6cfc..0d4e628 100644 --- a/src/engine/SCons/Scanner/PythonTests.py +++ b/src/engine/SCons/Scanner/PythonTests.py @@ -35,85 +35,7 @@ import SCons.Node.FS import SCons.Scanner.Python test = TestCmd.TestCmd(workdir='') - -# This directory is a simple empty package. -test.subdir('simple_package') -test.write(['simple_package', '__init__.py'], '') -test.write(['simple_package', 'module1.py'], '') -test.write(['simple_package', 'module2.py'], '') - -# Two files that import from simple_package. -test.write('imports_simple_package.py', r""" -import simple_package -""") -test.write('import_simple_package_module1.py', r""" -import simple_package.module1 -""") -test.write('import_simple_package_module1_as.py', r""" -import simple_package.module1 as m1 -""") -test.write('from_import_simple_package_module1.py', r""" -from simple_package import module1 -""") -test.write('from_import_simple_package_module1_as.py', r""" -from simple_package import module1 as m1 -""") -test.write('from_import_simple_package_modules_no_space.py', r""" -from simple_package import module1,module2 -""") -test.write('from_import_simple_package_modules_with_space.py', r""" -from simple_package import module1, module2 -""") - -# This directory holds a script that imports another from the current dir. -test.subdir('curdir_reference') -test.write(['curdir_reference', 'script.py'], r""" -from . import helper -""") -test.write(['curdir_reference', 'helper.py'], r'') - -# Create the directory structure: -# imports_nested3.py -# nested1 -# |- __init__.py -# |- module.py -# |- nested2 -# | |- __init__.py -# | |- module.py -# | '- nested3 -# | |- __init__.py -# | |- imports_grandparent_module.py -# | |- imports_parent_module.py -# | |- imports_parent_then_submodule.py -# | '- module.py -# '- nested2a -# |- __init__.py -# '- module.py -# This is used for more advanced relative path test cases. -test.write('imports_nested3.py', r""" -import nested1.nested2.nested3 -""") -test.subdir('nested1', ['nested1', 'nested2'], ['nested1', 'nested2a'], - ['nested1', 'nested2', 'nested3']) -test.write(['nested1', '__init__.py'], r'') -test.write(['nested1', 'module.py'], r'') -test.write(['nested1', 'nested2', '__init__.py'], r'') -test.write(['nested1', 'nested2', 'module.py'], r'') -test.write(['nested1', 'nested2a', '__init__.py'], r'') -test.write(['nested1', 'nested2a', 'module.py'], r'') -test.write(['nested1', 'nested2', 'nested3', '__init__.py'], r'') -test.write(['nested1', 'nested2', 'nested3', - 'imports_grandparent_module.py'], r""" -from ... import module -""") -test.write(['nested1', 'nested2', 'nested3', 'imports_parent_module.py'], r""" -from .. import module -""") -test.write(['nested1', 'nested2', 'nested3', - 'imports_parent_then_submodule.py'], r""" -from ...nested2a import module -""") -test.write(['nested1', 'nested2', 'nested3', 'module.py'], r'') +test.dir_fixture('python_scanner') if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase diff --git a/test/fixture/python_scanner/curdir_reference/helper.py b/test/fixture/python_scanner/curdir_reference/helper.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/curdir_reference/script.py b/test/fixture/python_scanner/curdir_reference/script.py new file mode 100644 index 0000000..d533863 --- /dev/null +++ b/test/fixture/python_scanner/curdir_reference/script.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..dcc86de --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_module1.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..51061c6 --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_module1_as.py @@ -0,0 +1 @@ +from simple_package import module1 as m1 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 new file mode 100644 index 0000000..17b82f8 --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_modules_no_space.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..169e6f7 --- /dev/null +++ b/test/fixture/python_scanner/from_import_simple_package_modules_with_space.py @@ -0,0 +1 @@ +from simple_package import module1, module2 diff --git a/test/fixture/python_scanner/import_simple_package_module1.py b/test/fixture/python_scanner/import_simple_package_module1.py new file mode 100644 index 0000000..bd85010 --- /dev/null +++ b/test/fixture/python_scanner/import_simple_package_module1.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..a706672 --- /dev/null +++ b/test/fixture/python_scanner/import_simple_package_module1_as.py @@ -0,0 +1 @@ +import simple_package.module1 as m1 diff --git a/test/fixture/python_scanner/imports_nested3.py b/test/fixture/python_scanner/imports_nested3.py new file mode 100644 index 0000000..c2929d0 --- /dev/null +++ b/test/fixture/python_scanner/imports_nested3.py @@ -0,0 +1 @@ +import nested1.nested2.nested3 diff --git a/test/fixture/python_scanner/imports_simple_package.py b/test/fixture/python_scanner/imports_simple_package.py new file mode 100644 index 0000000..d974128 --- /dev/null +++ b/test/fixture/python_scanner/imports_simple_package.py @@ -0,0 +1 @@ +import simple_package diff --git a/test/fixture/python_scanner/nested1/__init__.py b/test/fixture/python_scanner/nested1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/module.py b/test/fixture/python_scanner/nested1/module.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2/__init__.py b/test/fixture/python_scanner/nested1/nested2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2/module.py b/test/fixture/python_scanner/nested1/nested2/module.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/__init__.py b/test/fixture/python_scanner/nested1/nested2/nested3/__init__.py new file mode 100644 index 0000000..e69de29 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 new file mode 100644 index 0000000..06bb7f5 --- /dev/null +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_grandparent_module.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..be10279 --- /dev/null +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_module.py @@ -0,0 +1 @@ +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 new file mode 100644 index 0000000..39f1a1a --- /dev/null +++ b/test/fixture/python_scanner/nested1/nested2/nested3/imports_parent_then_submodule.py @@ -0,0 +1 @@ +from ...nested2a import module diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/module.py b/test/fixture/python_scanner/nested1/nested2/nested3/module.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2a/__init__.py b/test/fixture/python_scanner/nested1/nested2a/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2a/module.py b/test/fixture/python_scanner/nested1/nested2a/module.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/simple_package/__init__.py b/test/fixture/python_scanner/simple_package/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/simple_package/module1.py b/test/fixture/python_scanner/simple_package/module1.py new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/simple_package/module2.py b/test/fixture/python_scanner/simple_package/module2.py new file mode 100644 index 0000000..e69de29 -- cgit v0.12 From 8c49f0a6748688f98b10f6bb9b3d244baa49b3e4 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 25 Oct 2019 08:44:11 -0400 Subject: Add sconstest.skip files and improve test-framework.rst docs in that area --- test/fixture/python_scanner/curdir_reference/sconstest.skip | 0 test/fixture/python_scanner/nested1/nested2/nested3/sconstest.skip | 0 test/fixture/python_scanner/nested1/nested2/sconstest.skip | 0 test/fixture/python_scanner/nested1/nested2a/sconstest.skip | 0 test/fixture/python_scanner/nested1/sconstest.skip | 0 test/fixture/python_scanner/sconstest.skip | 0 test/fixture/python_scanner/simple_package/sconstest.skip | 0 testing/framework/test-framework.rst | 3 +++ 8 files changed, 3 insertions(+) create mode 100644 test/fixture/python_scanner/curdir_reference/sconstest.skip create mode 100644 test/fixture/python_scanner/nested1/nested2/nested3/sconstest.skip create mode 100644 test/fixture/python_scanner/nested1/nested2/sconstest.skip create mode 100644 test/fixture/python_scanner/nested1/nested2a/sconstest.skip create mode 100644 test/fixture/python_scanner/nested1/sconstest.skip create mode 100644 test/fixture/python_scanner/sconstest.skip create mode 100644 test/fixture/python_scanner/simple_package/sconstest.skip diff --git a/test/fixture/python_scanner/curdir_reference/sconstest.skip b/test/fixture/python_scanner/curdir_reference/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2/nested3/sconstest.skip b/test/fixture/python_scanner/nested1/nested2/nested3/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2/sconstest.skip b/test/fixture/python_scanner/nested1/nested2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/nested2a/sconstest.skip b/test/fixture/python_scanner/nested1/nested2a/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/nested1/sconstest.skip b/test/fixture/python_scanner/nested1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/sconstest.skip b/test/fixture/python_scanner/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/python_scanner/simple_package/sconstest.skip b/test/fixture/python_scanner/simple_package/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/testing/framework/test-framework.rst b/testing/framework/test-framework.rst index cb6b8e1..dc6b2aa 100644 --- a/testing/framework/test-framework.rst +++ b/testing/framework/test-framework.rst @@ -308,6 +308,9 @@ 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". + Directory Fixtures ################## -- cgit v0.12 From e76e874f44824172d1118b0f028256124332a101 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 25 Nov 2019 14:05:19 -0500 Subject: Add support for Value objects being implicit dependencies As part of consolidating outside dependencies, the code I work on takes on Value objects as implicit dependencies. That allows us to take on a dependecy to an entire build (e.g. our compiler) rather than 500 files from it. This has worked fine in practice for months now, but it turns out to break when using caching, because Node.get_contents() expects all dependencies to have the "name" attribute. This change adds that attribute to the Value class and a test to confirm that Node.get_contents() works now. --- src/CHANGES.txt | 5 +++++ src/engine/SCons/Node/Python.py | 4 ++++ src/engine/SCons/Node/PythonTests.py | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index db0a5f2..36ab52c 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,11 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER + From Adam Gross: + + - Added support for taking instances of the Value class as implicit + dependencies. + From Philipp Maierhöfer: - Avoid crash with UnicodeDecodeError on Python 3 when a Latex log file in non-UTF-8 encoding (e.g. containing umlauts in Latin-1 encoding when diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 4a62f04..546769d 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -92,6 +92,10 @@ class Value(SCons.Node.Node): if built_value is not None: self.built_value = built_value + # Set a name so it can be a child of a node and not break + # its parent's implementation of Node.get_contents. + self.name = value + def str_for_display(self): return repr(self.value) diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 8a01503..4c15e96 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -110,6 +110,16 @@ class ValueBuildInfoTestCase(unittest.TestCase): vvv = SCons.Node.Python.Value('vvv') bi = SCons.Node.Python.ValueBuildInfo() + +class ValueChildTestCase(unittest.TestCase): + def test___init__(self): + """Test support for a Value() being an implicit dependency of a Node""" + value = SCons.Node.Python.Value('v') + node = SCons.Node.Node() + node._func_get_contents = 2 # Pretend to be a Dir. + node.add_to_implicit([value]) + contents = node.get_contents() + if __name__ == "__main__": unittest.main() -- cgit v0.12 From 9ac3a25ea28dae718c095a7b1909c42b817ec9b8 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 25 Nov 2019 14:12:42 -0500 Subject: Avoid a flake8 warning where "contents" is unused --- src/engine/SCons/Node/PythonTests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 4c15e96..9d3c6b5 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -119,6 +119,7 @@ class ValueChildTestCase(unittest.TestCase): node._func_get_contents = 2 # Pretend to be a Dir. node.add_to_implicit([value]) contents = node.get_contents() + assert len(contents) > 0 if __name__ == "__main__": unittest.main() -- cgit v0.12 From e6dc8216872085749db83e14c9545cabb1ed0483 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 2 Dec 2019 09:54:28 -0500 Subject: Add a functional test --- src/engine/SCons/Node/Python.py | 1 - src/engine/SCons/Node/__init__.py | 4 +-- test/CacheDir/value.py | 47 ++++++++++++++++++++++++++++++ test/fixture/cachedir_foo_value/SConstruct | 19 ++++++++++++ test/fixture/cachedir_foo_value/foo.c | 1 + 5 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 test/CacheDir/value.py create mode 100644 test/fixture/cachedir_foo_value/SConstruct create mode 100644 test/fixture/cachedir_foo_value/foo.c diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 546769d..83e38f0 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -152,7 +152,6 @@ class Value(SCons.Node.Node): # Already encoded as python2 str are bytes return text_contents - def changed_since_last_build(self, target, prev_ni): cur_csig = self.get_csig() try: diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index daf79ba..4200965 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -741,12 +741,12 @@ class Node(object, with_metaclass(NoSlotsPyPy)): if self.depends is not None: for d in self.depends: if d.missing(): - msg = "Explicit dependency `%s' not found, needed by target `%s'." + msg = "Explicit dependency '%s' not found, needed by target '%s'." raise SCons.Errors.StopError(msg % (d, self)) if self.implicit is not None: for i in self.implicit: if i.missing(): - msg = "Implicit dependency `%s' not found, needed by target `%s'." + msg = "Implicit dependency '%s' not found, needed by target '%s'." raise SCons.Errors.StopError(msg % (i, self)) self.binfo = self.get_binfo() diff --git a/test/CacheDir/value.py b/test/CacheDir/value.py new file mode 100644 index 0000000..fd89a9e --- /dev/null +++ b/test/CacheDir/value.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# 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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that bwuilds with caching work for an action with a Value as a child. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('cachedir_foo_value') +test.subdir('cache') + +# First build, populates the cache +test.run(arguments='.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/fixture/cachedir_foo_value/SConstruct b/test/fixture/cachedir_foo_value/SConstruct new file mode 100644 index 0000000..b144799 --- /dev/null +++ b/test/fixture/cachedir_foo_value/SConstruct @@ -0,0 +1,19 @@ +import SCons.Node + +CacheDir('cache') + +def b(target, source, env): + with open(target[0].abspath, 'w') as f: + pass + +def scan(node, env, path): + return [env.Value('a')] + +scanner = Scanner(function=scan, node_class=SCons.Node.Node) +builder = Builder(action=b, source_scanner=scanner) + +env = Environment() +env.Append(BUILDERS={'B': builder}) + +env.B(target='File1.out', source='foo.c') +#env.Program('foo', foo_c) diff --git a/test/fixture/cachedir_foo_value/foo.c b/test/fixture/cachedir_foo_value/foo.c new file mode 100644 index 0000000..5ab8d0f --- /dev/null +++ b/test/fixture/cachedir_foo_value/foo.c @@ -0,0 +1 @@ +int main(void){ return 0; } -- cgit v0.12 From 1098fdbdd9bba34baaf25266e4f4e7166d17ac68 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 17 Dec 2019 16:39:48 -0500 Subject: Separate out Python suffixes into another variable --- src/engine/SCons/Scanner/Python.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py index 825928d..bbe65ff 100644 --- a/src/engine/SCons/Scanner/Python.py +++ b/src/engine/SCons/Scanner/Python.py @@ -159,5 +159,6 @@ def scan(node, env, path=()): return sorted(nodes) -PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', skeys=['.py'], +PythonSuffixes = ['.py'] +PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', skeys=PythonSuffixes, path_function=path_function, recursive=1) -- cgit v0.12 From 99318498919eb5f7132bc1be239c8eba86e230d7 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 17 Dec 2019 18:32:24 -0500 Subject: Fix over-80-characters issue and add formatting block at bottom --- src/engine/SCons/Scanner/Python.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py index bbe65ff..0ab3111 100644 --- a/src/engine/SCons/Scanner/Python.py +++ b/src/engine/SCons/Scanner/Python.py @@ -160,5 +160,12 @@ def scan(node, env, path=()): PythonSuffixes = ['.py'] -PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', skeys=PythonSuffixes, +PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner', + skeys=PythonSuffixes, path_function=path_function, recursive=1) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 9cb4b26d0b22fadb5ffbe2f612890b0dc024de98 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Wed, 18 Dec 2019 19:12:08 -0500 Subject: Add Python.py to the manifest file --- src/engine/MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 3125824..7cd9928 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -40,6 +40,7 @@ SCons/Scanner/Fortran.py SCons/Scanner/IDL.py SCons/Scanner/LaTeX.py SCons/Scanner/Prog.py +SCons/Scanner/Python.py SCons/Scanner/RC.py SCons/Scanner/SWIG.py SCons/SConf.py -- cgit v0.12 From d252e54734cf5c0501a689f37a00a27c0ff1a39d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sat, 14 Dec 2019 07:40:27 -0700 Subject: Update manpage intro section [ci skip] Side effect: added an entry to scons.mod for the sconscript function (it didn't have one since the name itself was already in use). Change the type of a few entities. Those changes don't have a content effect, just a presentation effect. Signed-off-by: Mats Wichmann --- doc/generated/variables.gen | 11 -- doc/man/scons.xml | 307 ++++++++++++++++++++++---------------------- doc/scons.mod | 45 +++---- 3 files changed, 176 insertions(+), 187 deletions(-) diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 9050832..21e0b1f 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -3448,17 +3448,6 @@ If this is not set, then - LDMODULEEMITTER - - -Contains the emitter specification for the -LoadableModule builder. -The manpage section "Builder Objects" contains -general information on specifying emitters. - - - LDMODULEFLAGS diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 899669e..26370f6 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -93,72 +93,67 @@ -DESCRIPTION -The + +DESCRIPTION + scons -utility builds software (or other files) by determining which -component pieces must be rebuilt and executing the necessary commands to -rebuild them. +orchestrates the construction of software +(and other tangible products such as documentation files) +by determining which +component pieces must be built or rebuilt and invoking the necessary +commands to build them. + +You instruct +scons by writing a configuration file +which specifies the files to be built (targets), +and, if necessary, the rules to build those files. Premade +rules exist for building many common software components +(such as executable programs, object files, libraries), +so that for most software projects, +only the target and input files need be specified. -By default, -scons + +When invoked, scons searches for a file named -SConstruct, -Sconstruct, -sconstruct, -SConstruct.py -Sconstruct.py -or -sconstruct.py -(in that order) in the current directory and reads its -configuration from the first file found. +&SConstruct; +(going on to check alternative names +&Sconstruct;, &sconstruct;, &SConstruct.py; &Sconstruct.py; +and &sconstruct.py; +in that order) in the current directory and reads its +configuration from that file. An alternate file name may be specified via the -option. - -The -SConstruct +option. +The &SConstruct; file can specify subsidiary configuration files using the -SConscript() -function. +&SConscriptFunc; function. By convention, these subsidiary files are named -SConscript, +&SConscript;, although any name may be used. -(Because of this naming convention, -the term "SConscript files" -is sometimes used to refer -generically to all -scons -configuration files, -regardless of actual file name.) - -The configuration files -specify the target files to be built, and -(optionally) the rules to build those targets. Reasonable default -rules exist for building common software components (executable -programs, object files, libraries), so that for most software -projects, only the target and input files need be specified. - -Before reading the -SConstruct -file, +As a result of this naming convention, +the term SConscript files +is often used to refer +generically to the complete set of +configuration files for a project, +including the &SConstruct; file, +regardless of the actual file names or number of files. + +Before reading the SConscript files, scons looks for a directory named -site_scons -in various system directories (see below) and the directory containing the -SConstruct -file; for each of those dirs which exists, -site_scons -is prepended to sys.path, -the file -site_scons/site_init.py, -is evaluated if it exists, +site_scons +in various system directories and the directory containing the +&SConstruct; file: each such directory which exists +is prepended to sys.path; +the file site_init.py +is evaluated if it exists in that directory; and the directory -site_scons/site_tools -is prepended to the default toolpath if it exists. +site_tools +is prepended to the default toolpath +if it exists in that directory. See the and @@ -169,12 +164,14 @@ options for more details. reads and executes the SConscript files as Python scripts, so you may use normal Python scripting capabilities (such as flow control, data manipulation, and imported Python libraries) -to handle complicated build situations. -scons, -however, reads and executes all of the SConscript files +to handle complicated build situations. + + +scons +reads and executes all of the SConscript files before it begins building any targets. -To make this obvious, +To make this clear, scons prints the following messages about what it is doing: @@ -189,7 +186,7 @@ $ The status messages -(everything except the line that reads "cp foo.in foo.out") +(lines beginning with the scons: tag) may be suppressed using the option. @@ -209,34 +206,28 @@ that you want to use to build your target files are not in standard system locations, scons will not find them unless -you explicitly set the PATH +you explicitly set the scons +PATH in the internal environment to include those locations. -Whenever you create an -scons -construction environment, +Whenever you create a &consenv;, you can propagate the value of PATH from your external environment as follows: import os -env = Environment(ENV = {'PATH' : os.environ['PATH']}) +env = Environment(ENV={'PATH': os.environ['PATH']}) -Similarly, if the commands use external environment variables -like -PATH, -HOME, -JAVA_HOME, -LANG, -SHELL, -TERM, -etc., -these variables can also be explicitly propagated: +Similarly, if the commands use specific +external environment variables that scons +does not recognize, they can be propagated into +the internal environment: import os -env = Environment(ENV = {'PATH': os.environ['PATH'], - 'HOME': os.environ['HOME']}) +env = Environment(ENV={'PATH': os.environ['PATH'], + 'ANDROID_HOME': os.environ['ANDROID_HOME'], + 'ANDROID_NDK_HOME': os.environ['ANDROID_NDK_HOME']}) Or you may explicitly propagate the invoking user's @@ -244,17 +235,23 @@ complete external environment: import os -env = Environment(ENV = os.environ) +env = Environment(ENV=os.environ) This comes at the expense of making your build dependent on the user's environment being set correctly, -but it may be more convenient for many configurations. +but it may be more convenient for many configurations. +It should not cause problems if done in a build setup which tightly +controls how the environment is set up before invoking +scons, as in many continuous +integration setups. + scons can scan known input files automatically for dependency -information (for example, #include statements -in C or C++ files) and will rebuild dependent files appropriately +information (for example, #include +preprocessor directives in C or C++ files) +and will rebuild dependent files appropriately whenever any "included" input file changes. scons supports the @@ -266,41 +263,46 @@ SCCS or RCS subdirectories using SCCS, RCS or BitKeeper. scons -is normally executed in a top-level directory containing a -SConstruct -file, optionally specifying -as command-line arguments -the target file or files to be built. - -By default, the command - - -scons - +is normally executed in a top-level directory containing an +&SConstruct; file. +When scons is invoked, +the command line (including the contents +of the &SCONSFLAGS; environment variable, +if set) is processed. +The options are consumed (see ; +and also note that SConscript files may define additional options +for the project using the &AddOption; function). +Any variable argument assignments (see below) are also consumed. +Any remaining arguments are taken as the targets to build. +Targets on the command line may be files, directories, +or phony targets defined using the &Alias; function. +The command line targets are available in the +&COMMAND_LINE_TARGETS; list. + -will build all target files in or below the current directory. -Explicit default targets -(to be built when no targets are specified on the command line) -may be defined in the SConscript file(s) -using the -Default() -function, described below. +If no targets are specified on the command line, +scons +will build the default targets. The default targets +are those specified in the SConscript files via calls +to the &Default; function; if none, the default targets are +those target files in or below the current directory. +Targets specified via the &Default; function are available +in the &DEFAULT_TARGETS; list. + -Even when -Default() -targets are specified in the SConscript file(s), -all target files in or below the current directory -may be built by explicitly specifying -the current directory (.) +To ignore the default targets specified +through calls to &Default; and instead build all +target files in or below the current directory +specify the current directory (.) as a command-line target: scons . -Building all target files, +To build all target files, including any files outside of the current directory, -may be specified by supplying a command-line target +supply a command-line target of the root directory (on POSIX systems): @@ -314,15 +316,33 @@ should be built (on Windows systems): scons C:\ D:\ -To build only specific targets, -supply them as command-line arguments: +A subset of a hierarchical tree may be built by +remaining at the top-level directory (where the +&SConstruct; +file lives) and specifying the subdirectory as the target to +build: -scons foo bar +scons src/subdir + + +or by changing directory and invoking scons with the + +option, which traverses up the directory +hierarchy until it finds the +&SConstruct; +file, and then builds +targets relatively to the current subdirectory (see +also the related and options): + + +cd src/subdir +scons -u . -in which case only the specified targets will be built -(along with any derived files on which they depend). +In all cases, more files may be built than are +requested, as scons needs to make +sure any dependent files are built. Specifying "cleanup" targets in SConscript files is not usually necessary. The @@ -334,45 +354,22 @@ necessary to build the specified target: scons -c . -to remove all target files, or: +to remove all target files in or under the current directory, or: scons -c build export -to remove target files under build and export. +to remove target files under build +and export. + + Additional files or directories to remove can be specified using the -Clean() -function. +&Clean; function in the SConscript files. Conversely, targets that would normally be removed by the -invocation -can be prevented from being removed by using the -NoClean() -function. - -A subset of a hierarchical tree may be built by -remaining at the top-level directory (where the -SConstruct -file lives) and specifying the subdirectory as the target to be -built: - - -scons src/subdir - - -or by changing directory and invoking scons with the - -option, which traverses up the directory -hierarchy until it finds the -SConstruct -file, and then builds -targets relatively to the current subdirectory: - - -cd src/subdir -scons -u . - +invocation can be retained by calling the +&NoClean; function with those targets. scons supports building multiple targets in parallel via a @@ -405,16 +402,16 @@ command-line options. The option is useful to prevent multiple builds from trying to update the cache simultaneously. -Values of variables to be passed to the SConscript file(s) +Values of variables to be passed to the SConscript files may be specified on the command line: scons debug=1 . -These variables are available in SConscript files -through the ARGUMENTS dictionary, -and can be used in the SConscript file(s) to modify +These variables are available +through the &ARGUMENTS; dictionary, +and can be used in the SConscript files to modify the build in any way: @@ -425,13 +422,12 @@ else: The command-line variable arguments are also available -in the ARGLIST list, +in the &ARGLIST; list, indexed by their order on the command line. This allows you to process them in order rather than by name, -if necessary. -ARGLIST[0] returns a tuple -containing (argname, argvalue). -A Python exception is thrown if you +if necessary. Each &ARGLIST; entry is a tuple +containing (argname, argvalue). +A Python IndexError exception is raised if you try to access a list member that does not exist. @@ -443,24 +439,28 @@ There should be no other dependencies or requirements to run + By default, scons -knows how to search for available programming tools -on various systems. -On Windows systems, +searches for known programming tools +on various systems and initializes itself based on what is found. +On Windows systems which identify as win32, scons searches in order for the Microsoft Visual C++ tools, the MinGW tool chain, the Intel compiler tools, and the PharLap ETS compiler. +On Windows system which identify as cygwin +(that is, if scons is invoked from a cygwin shell), +the order changes to prefer the GCC toolchain over the MSVC tools. On OS/2 systems, scons searches in order for the OS/2 compiler, the GCC tool chain, and the Microsoft Visual C++ tools, -On SGI IRIX, IBM AIX, Hewlett Packard HP-UX, and Sun Solaris systems, +On SGI IRIX, IBM AIX, Hewlett Packard HP-UX, and Oracle Solaris systems, scons searches for the native compiler tools (MIPSpro, Visual Age, aCC, and Forte tools respectively) @@ -470,7 +470,6 @@ including POSIX (Linux and UNIX) platforms, scons searches in order for the GCC tool chain, -the Microsoft Visual C++ tools, and the Intel compiler tools. You may, of course, override these default values by appropriate configuration of diff --git a/doc/scons.mod b/doc/scons.mod index 3e843a0..024afab 100644 --- a/doc/scons.mod +++ b/doc/scons.mod @@ -225,6 +225,7 @@ NoCache"> Objects"> Options"> +SConscript"> Variables"> PackageOption"> PackageVariable"> @@ -418,27 +419,27 @@ --> -builder function"> -build action"> -build actions"> -builder method"> +builder function"> +build action"> +build actions"> +builder method"> -Configure Contexts"> -configure context"> +Configure Contexts"> +configure context"> -Construction Environment"> -Construction Environments"> -Construction environment"> -Construction environments"> -construction environment"> -construction environments"> +Construction Environment"> +Construction Environments"> +Construction environment"> +Construction environments"> +construction environment"> +construction environments"> -Construction Variable"> -Construction Variables"> -Construction variable"> -Construction variables"> -construction variable"> -construction variables"> +Construction Variable"> +Construction Variables"> +Construction variable"> +Construction variables"> +construction variable"> +construction variables"> CPPPATH"> @@ -529,14 +530,14 @@ --> -announce@scons.tigris.org"> -scons-dev@scons.org"> -scons-users@scons.org"> +announce@scons.tigris.org"> +scons-dev@scons.org"> +scons-users@scons.org"> -- cgit v0.12 From 7fed3fac34613ca78cddf7fc7279032eca6fd989 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 20 Dec 2019 15:41:34 -0700 Subject: [PR #3501] review - modify site_scons description [ci skip] Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 26370f6..7ec972e 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -145,20 +145,23 @@ regardless of the actual file names or number of files. scons looks for a directory named site_scons -in various system directories and the directory containing the -&SConstruct; file: each such directory which exists -is prepended to sys.path; -the file site_init.py -is evaluated if it exists in that directory; -and the directory -site_tools -is prepended to the default toolpath -if it exists in that directory. +in various system directories and in the directory containing the +&SConstruct; file and prepends the ones it +finds to the Python module search path (sys.path), +thus allowing modules in such directories to be imported in +the normal Python way in SConscript files. +For each found site directory, +if it contains a file site_init.py +it is evaluated, and if it contains a directory +site_tools the path to it +is prepended to the default toolpath. See the - -and -options for more details. +and + +options for details on default paths and +controlling the site directories. + scons reads and executes the SConscript files as Python scripts, -- cgit v0.12 From d88e0e7b976c2f9e261f03189441ab6af4c37de3 Mon Sep 17 00:00:00 2001 From: Mathew Robinson Date: Mon, 23 Dec 2019 10:05:36 -0500 Subject: Prevent unnecessary eval calls in Subst --- src/CHANGES.txt | 3 ++ src/engine/SCons/Subst.py | 70 +++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 87980a8..f8452c7 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -12,6 +12,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Improve performance of Subst by preventing unnecessary frame allocations by no longer defining the *Subber classes inside of their respective function calls. + - Improve performance of Subst in some cases by preventing + unnecessary calls to eval when a token is surrounded in braces + but is not a function call. From Mats Wichmann: - Remove deprecated SourceCode diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index f3693a1..2e469ce 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -375,23 +375,26 @@ class StringSubber(object): if key[0] == '{' or '.' in key: if key[0] == '{': key = key[1:-1] - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception as e: - if e.__class__ in AllowableExceptions: - return '' - raise_exception(e, lvars['TARGETS'], s) + + s = None + if key in lvars: + s = lvars[key] + elif key in self.gvars: + s = self.gvars[key] else: - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - elif NameError not in AllowableExceptions: - raise_exception(NameError(key), lvars['TARGETS'], s) - else: - return '' + try: + s = eval(key, self.gvars, lvars) + except KeyboardInterrupt: + raise + except Exception as e: + if e.__class__ in AllowableExceptions: + return '' + raise_exception(e, lvars['TARGETS'], s) + + if s is None and NameError not in AllowableExceptions: + raise_exception(NameError(key), lvars['TARGETS'], s) + elif s is None: + return '' # Before re-expanding the result, handle # recursive expansion by copying the local @@ -524,23 +527,26 @@ class ListSubber(collections.UserList): if key[0] == '{' or key.find('.') >= 0: if key[0] == '{': key = key[1:-1] - try: - s = eval(key, self.gvars, lvars) - except KeyboardInterrupt: - raise - except Exception as e: - if e.__class__ in AllowableExceptions: - return - raise_exception(e, lvars['TARGETS'], s) + + s = None + if key in lvars: + s = lvars[key] + elif key in self.gvars: + s = self.gvars[key] else: - if key in lvars: - s = lvars[key] - elif key in self.gvars: - s = self.gvars[key] - elif NameError not in AllowableExceptions: - raise_exception(NameError(), lvars['TARGETS'], s) - else: - return + try: + s = eval(key, self.gvars, lvars) + except KeyboardInterrupt: + raise + except Exception as e: + if e.__class__ in AllowableExceptions: + return + raise_exception(e, lvars['TARGETS'], s) + + if s is None and NameError not in AllowableExceptions: + raise_exception(NameError(), lvars['TARGETS'], s) + elif s is None: + return # Before re-expanding the result, handle # recursive expansion by copying the local -- cgit v0.12 From 0aaa5d29927629baa7025b26735e5169b6fba955 Mon Sep 17 00:00:00 2001 From: Mathew Robinson Date: Mon, 6 Jan 2020 14:14:22 -0500 Subject: Store unexpanded string for reporting in error messages --- src/engine/SCons/Subst.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 2e469ce..59b0fcb 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -376,6 +376,9 @@ class StringSubber(object): if key[0] == '{': key = key[1:-1] + # Store for error messages if we fail to expand the + # value + old_s = s s = None if key in lvars: s = lvars[key] @@ -389,10 +392,10 @@ class StringSubber(object): except Exception as e: if e.__class__ in AllowableExceptions: return '' - raise_exception(e, lvars['TARGETS'], s) + raise_exception(e, lvars['TARGETS'], old_s) if s is None and NameError not in AllowableExceptions: - raise_exception(NameError(key), lvars['TARGETS'], s) + raise_exception(NameError(key), lvars['TARGETS'], old_s) elif s is None: return '' @@ -528,6 +531,9 @@ class ListSubber(collections.UserList): if key[0] == '{': key = key[1:-1] + # Store for error messages if we fail to expand the + # value + old_s = s s = None if key in lvars: s = lvars[key] @@ -541,10 +547,10 @@ class ListSubber(collections.UserList): except Exception as e: if e.__class__ in AllowableExceptions: return - raise_exception(e, lvars['TARGETS'], s) + raise_exception(e, lvars['TARGETS'], old_s) if s is None and NameError not in AllowableExceptions: - raise_exception(NameError(), lvars['TARGETS'], s) + raise_exception(NameError(), lvars['TARGETS'], old_s) elif s is None: return -- cgit v0.12 From bcea663cf1b442354a13474cc744b172caef10ab Mon Sep 17 00:00:00 2001 From: Mathew Robinson Date: Mon, 23 Dec 2019 13:34:42 -0500 Subject: Prevent unnecessary recursion when value is already expanded --- src/CHANGES.txt | 1 + src/engine/SCons/Subst.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 81664aa..a9417c7 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -24,6 +24,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Improve performance of Subst in some cases by preventing unnecessary calls to eval when a token is surrounded in braces but is not a function call. + - Improve performance of subst by removing unnecessary recursion. From Mats Wichmann: - Remove deprecated SourceCode diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 92aa52c..e81131d 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -499,6 +499,9 @@ class ListSubber(collections.UserList): self.in_strip = None self.next_line() + def expanded(self, s): + return is_String(s) and _separate_args.findall(s) is None + def expand(self, s, lvars, within_list): """Expand a single "token" as necessary, appending the expansion to the current result. @@ -554,6 +557,10 @@ class ListSubber(collections.UserList): elif s is None: return + if self.expanded(s): + self.append(s) + return + # Before re-expanding the result, handle # recursive expansion by copying the local # variable dictionary and overwriting a null -- cgit v0.12 From 9ac66132c5189274c130182d1bc2a3c8c526aa47 Mon Sep 17 00:00:00 2001 From: Mathew Robinson Date: Mon, 6 Jan 2020 14:21:09 -0500 Subject: Handle UserString in ListSubber.expanded --- src/engine/SCons/Subst.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index e81131d..eec4adf 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -500,7 +500,11 @@ class ListSubber(collections.UserList): self.next_line() def expanded(self, s): - return is_String(s) and _separate_args.findall(s) is None + if not is_String(s) or isinstance(s, CmdStringHolder): + return False + + s = str(s) # in case it's a UserString + return _separate_args.findall(s) is None def expand(self, s, lvars, within_list): """Expand a single "token" as necessary, appending the -- cgit v0.12 From 2ff7ea17b28e6962c48238550d77ec9cdd96c02c Mon Sep 17 00:00:00 2001 From: Mathew Robinson Date: Mon, 6 Jan 2020 17:42:41 -0500 Subject: [ci skip] Document ListSubber.expanded and usage --- src/engine/SCons/Subst.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index eec4adf..a1ef053 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -500,6 +500,14 @@ class ListSubber(collections.UserList): self.next_line() def expanded(self, s): + """Determines if the string s requires further expansion. + + Due to the implementation of ListSubber expand will call + itself 2 additional times for an already expanded string. This + method is used to determine if a string is already fully + expanded and if so exit the loop early to prevent these + recursive calls. + """ if not is_String(s) or isinstance(s, CmdStringHolder): return False @@ -561,6 +569,8 @@ class ListSubber(collections.UserList): elif s is None: return + # If the string is already full expanded there's no + # need to continue recursion. if self.expanded(s): self.append(s) return -- cgit v0.12 From ae5461ca714ea06e135899a8b08d615008aab4ee Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 7 Jan 2020 09:51:46 -0700 Subject: Fixup some doc inconsistencies. [CI skip] PR #3464 removed SourceSignatures, TargetSignatures but left a dangling reference in the User Guide (referred to the existence of the functions but did not give their names, which is how they were missed). [Fixes #3519] PR #3506 removed SourceCode, and accidentally removed the documentation of the Split function as well. In the PR history is a note that it was discovered and restored, but somehow it is still missing from master so restoring (again) with small markup changes. Signed-off-by: Mats Wichmann --- doc/user/depends.xml | 37 +++++++++++++++++----------------- src/engine/SCons/Environment.xml | 32 +++++++++++++++++++++++++++++ src/engine/SCons/Script/SConscript.xml | 12 +++++------ 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/doc/user/depends.xml b/doc/user/depends.xml index cd5094a..3cba64c 100644 --- a/doc/user/depends.xml +++ b/doc/user/depends.xml @@ -2,7 +2,7 @@ %scons; - + %builders-mod; @@ -372,7 +372,7 @@ int main() { printf("Hello, world!\n"); } instead of timestamp-match, would be if you have some specific reason - to require this &Make;-like behavior of + to require this &Make;-like behavior of not rebuilding a target when an otherwise-modified source file is older. @@ -747,25 +747,24 @@ int main() { printf("Hello, world!\n"); }
- Older Functions for Deciding When an Input File Has Changed + Obsolete Functions for Deciding When an Input File Has Changed - &SCons; still supports two functions that used to be the - primary methods for configuring the - decision about whether or not an input file has changed. - These functions have been officially deprecated - as &SCons; version 2.0, - and their use is discouraged, - mainly because they rely on a somewhat - confusing distinction between how - source files and target files are handled. - These functions are documented here mainly in case you - encounter them in older &SConscript; files. + In the past, &SCons; supported two functions + (SourceSignatures and + TargetSignatures) + that once were the primary methods for configuring the + decision about whether or not an input file had changed. + These functions were deprecated since &SCons; version 2.0, + and removed in &SCons; version 3.1 and + are mentioned here solely for identification purposes, + as there are a number of very old examples that may turn up + in web searches and in the SCons Wiki that may reference them.
- +
Implicit Dependencies: The &cv-CPPPATH; Construction Variable @@ -1426,11 +1425,11 @@ Ignore(hello, '/usr/include/stdio.h') - &Ignore; can also be used to prevent a generated file from being built - by default. This is due to the fact that directories depend on - their contents. So to ignore a generated file from the default build, + &Ignore; can also be used to prevent a generated file from being built + by default. This is due to the fact that directories depend on + their contents. So to ignore a generated file from the default build, you specify that the directory should ignore the generated file. - Note that the file will still be built if the user specifically + Note that the file will still be built if the user specifically requests the target on scons command line, or if the file is a dependency of another file which is requested and/or is built by default. diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index b1c2039..35e4bd8 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -2879,6 +2879,38 @@ function. + +(arg) + + +Returns a list of file names or other objects. +If arg is a string, +it will be split on strings of white-space characters +within the string, +making it easier to write long lists of file names. +If arg is already a list, +the list will be returned untouched. +If arg is any other type of object, +it will be returned as a list +containing just the object. + + + +Example: + + + +files = Split("f1.c f2.c f3.c") +files = env.Split("f4.c f5.c f6.c") +files = Split(""" + f7.c + f8.c + f9.c +""") + + + + (input, [raw, target, source, conv]) diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml index 874c110..a1e0129 100644 --- a/src/engine/SCons/Script/SConscript.xml +++ b/src/engine/SCons/Script/SConscript.xml @@ -252,16 +252,16 @@ This specifies help text to be printed if the argument is given to &scons;. -If +If &f-Help; -is called multiple times, the text is appended together in the order that +is called multiple times, the text is appended together in the order that &f-Help; -is called. With append set to False, any +is called. With append set to False, any &f-Help; -text generated with +text generated with &f-AddOption; is clobbered. If append is True, the AddOption help is prepended to the help -string, thus preserving the +string, thus preserving the message. @@ -393,7 +393,7 @@ A single script may be specified as a string; multiple scripts must be specified as a list (either explicitly or as created by a function like -&f-Split;). +&f-link-Split;). Examples: -- cgit v0.12 From fa3aa9e79912faa7673587d7d461d9c016f133d2 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 7 Jan 2020 10:48:31 -0700 Subject: [PR #3520] just drop the userguide section Pre review comment, drop the section which referenced the *Signatures functions, rather than trying to fix it up. The functions were previously dropped. Signed-off-by: Mats Wichmann --- doc/user/depends.xml | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/doc/user/depends.xml b/doc/user/depends.xml index 3cba64c..703855d 100644 --- a/doc/user/depends.xml +++ b/doc/user/depends.xml @@ -747,25 +747,6 @@ int main() { printf("Hello, world!\n"); }
- Obsolete Functions for Deciding When an Input File Has Changed - - - - In the past, &SCons; supported two functions - (SourceSignatures and - TargetSignatures) - that once were the primary methods for configuring the - decision about whether or not an input file had changed. - These functions were deprecated since &SCons; version 2.0, - and removed in &SCons; version 3.1 and - are mentioned here solely for identification purposes, - as there are a number of very old examples that may turn up - in web searches and in the SCons Wiki that may reference them. - - -
- -
Implicit Dependencies: The &cv-CPPPATH; Construction Variable -- cgit v0.12 From c5531583f832b59c7d5ec0af682e33e04ef7ff4a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 9 Jan 2020 16:33:06 -0800 Subject: Remove UnicodeType as py35+ has unicode strings. Remove some py27 imports. Mainly cleanup of Util.py and tests depending on these changes --- src/engine/SCons/Taskmaster.py | 2 +- src/engine/SCons/Tool/xgettext.py | 2 +- src/engine/SCons/Util.py | 27 ++++++--------------------- src/engine/SCons/UtilTests.py | 31 ++----------------------------- 4 files changed, 10 insertions(+), 52 deletions(-) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 06fc94c..7363915 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -792,7 +792,7 @@ class Taskmaster(object): self.ready_exc = None T = self.trace - if T: T.write(SCons.Util.UnicodeType('\n') + self.trace_message('Looking for a node to evaluate')) + if T: T.write(str('\n') + self.trace_message('Looking for a node to evaluate')) while True: node = self.next_candidate() diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index 11ca32f..7aba08d 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -70,7 +70,7 @@ class _CmdRunner(object): self.out, self.err = proc.communicate() self.status = proc.wait() if self.err: - sys.stderr.write(SCons.Util.UnicodeType(self.err)) + sys.stderr.write(str(self.err)) return self.status def strfunction(self, target, source, env): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index d930dde..8ff7b4f 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -39,18 +39,8 @@ PY3 = sys.version_info[0] == 3 PYPY = hasattr(sys, 'pypy_translation_info') -try: - from collections import UserDict, UserList, UserString -except ImportError: - from UserDict import UserDict - from UserList import UserList - from UserString import UserString - -try: - from collections.abc import Iterable, MappingView -except ImportError: - from collections import Iterable - +from collections import UserDict, UserList, UserString +from collections.abc import Iterable, MappingView from collections import OrderedDict # Don't "from types import ..." these because we need to get at the @@ -62,13 +52,6 @@ from collections import OrderedDict MethodType = types.MethodType FunctionType = types.FunctionType -try: - _ = type(unicode) -except NameError: - UnicodeType = str -else: - UnicodeType = unicode - def dictify(keys, values, result={}): for k, v in zip(keys, values): result[k] = v @@ -210,14 +193,16 @@ def get_environment_var(varstr): else: return None + class DisplayEngine(object): print_it = True + def __call__(self, text, append_newline=1): if not self.print_it: return if append_newline: text = text + '\n' try: - sys.stdout.write(UnicodeType(text)) + sys.stdout.write(str(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed @@ -1582,7 +1567,7 @@ del __revision__ def to_bytes(s): if s is None: return b'None' - if not PY3 and isinstance(s, UnicodeType): + if not PY3 and isinstance(s, str): # PY2, must encode unicode return bytearray(s, 'utf-8') if isinstance (s, (bytes, bytearray)) or bytes is str: diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index e2dd57f..870e79f 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -37,14 +37,6 @@ import SCons.Errors from SCons.Util import * -try: - eval('unicode') -except NameError: - HasUnicode = False -else: - HasUnicode = True - - class OutBuffer(object): def __init__(self): self.buffer = "" @@ -274,8 +266,7 @@ class UtilTestCase(unittest.TestCase): assert not is_Dict([]) assert not is_Dict(()) assert not is_Dict("") - if HasUnicode: - exec ("assert not is_Dict(u'')") + def test_is_List(self): assert is_List([]) @@ -290,13 +281,9 @@ class UtilTestCase(unittest.TestCase): assert not is_List(()) assert not is_List({}) assert not is_List("") - if HasUnicode: - exec ("assert not is_List(u'')") def test_is_String(self): assert is_String("") - if HasUnicode: - exec ("assert is_String(u'')") assert is_String(UserString('')) try: class mystr(str): @@ -321,13 +308,11 @@ class UtilTestCase(unittest.TestCase): assert not is_Tuple([]) assert not is_Tuple({}) assert not is_Tuple("") - if HasUnicode: - exec ("assert not is_Tuple(u'')") def test_to_Bytes(self): """ Test the to_Bytes method""" if not PY3: - self.assertEqual(to_bytes(UnicodeType('Hello')), + self.assertEqual(to_bytes(str('Hello')), bytearray(u'Hello', 'utf-8'), "Check that to_bytes creates byte array when presented with unicode string. PY2 only") @@ -352,18 +337,6 @@ class UtilTestCase(unittest.TestCase): assert to_String(s2) == s2, s2 assert to_String(s2) == 'foo', s2 - if HasUnicode: - s3 = UserString(unicode('bar')) - assert to_String(s3) == s3, s3 - assert to_String(s3) == unicode('bar'), s3 - assert isinstance(to_String(s3), unicode), \ - type(to_String(s3)) - - if HasUnicode: - s4 = unicode('baz') - assert to_String(s4) == unicode('baz'), to_String(s4) - assert isinstance(to_String(s4), unicode), \ - type(to_String(s4)) def test_WhereIs(self): test = TestCmd.TestCmd(workdir='') -- cgit v0.12 From 3b10a27fab8a646c499c38630b1d27d64ae8b1c3 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 9 Jan 2020 16:42:20 -0800 Subject: Remove if PY3 code. --- src/engine/SCons/CacheDir.py | 6 +----- src/engine/SCons/CacheDirTests.py | 6 +----- src/engine/SCons/Tool/suncxx.py | 18 +++++------------- src/engine/SCons/Tool/textfile.py | 12 +++--------- src/engine/SCons/Util.py | 11 ++++------- src/engine/SCons/UtilTests.py | 7 +++---- 6 files changed, 17 insertions(+), 43 deletions(-) diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py index 10c088d..9bb7ef3 100644 --- a/src/engine/SCons/CacheDir.py +++ b/src/engine/SCons/CacheDir.py @@ -36,7 +36,6 @@ import sys import SCons import SCons.Action import SCons.Warnings -from SCons.Util import PY3 cache_enabled = True cache_debug = False @@ -160,10 +159,7 @@ class CacheDir(object): if path is None: return - if PY3: - self._readconfig3(path) - else: - self._readconfig2(path) + self._readconfig3(path) def _readconfig3(self, path): diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py index 0e242c4..ff22d01 100644 --- a/src/engine/SCons/CacheDirTests.py +++ b/src/engine/SCons/CacheDirTests.py @@ -33,7 +33,6 @@ import stat from TestCmd import TestCmd import SCons.CacheDir -from SCons.Util import PY3 built_it = None @@ -169,10 +168,7 @@ class ExceptionTestCase(unittest.TestCase): os.remove(old_config) try: - if PY3: - self._CacheDir._readconfig3(self._CacheDir.path) - else: - self._CacheDir._readconfig2(self._CacheDir.path) + self._CacheDir._readconfig3(self._CacheDir.path) assert False, "Should have raised exception and did not" except SCons.Errors.SConsEnvironmentError as e: assert str(e) == "Failed to write cache configuration for {}".format(self._CacheDir.path) diff --git a/src/engine/SCons/Tool/suncxx.py b/src/engine/SCons/Tool/suncxx.py index c155484..1c35612 100644 --- a/src/engine/SCons/Tool/suncxx.py +++ b/src/engine/SCons/Tool/suncxx.py @@ -39,7 +39,6 @@ import os import re import subprocess -from SCons.Util import PY3 import SCons.Tool.cxx cplusplus = SCons.Tool.cxx # cplusplus = __import__('c++', globals(), locals(), []) @@ -53,10 +52,7 @@ def get_package_info(package_name, pkginfo, pkgchk): except KeyError: version = None pathname = None - try: - from subprocess import DEVNULL # py3k - except ImportError: - DEVNULL = open(os.devnull, 'wb') + from subprocess import DEVNULL try: with open('/var/sadm/install/contents', 'r') as f: @@ -72,16 +68,14 @@ def get_package_info(package_name, pkginfo, pkgchk): try: popen_args = {'stdout': subprocess.PIPE, 'stderr': DEVNULL} - if PY3: - popen_args['universal_newlines'] = True + popen_args['universal_newlines'] = True p = subprocess.Popen([pkginfo, '-l', package_name], **popen_args) except EnvironmentError: pass else: pkginfo_contents = p.communicate()[0] - if not PY3: - pkginfo_contents.decode() + pkginfo_contents.decode() version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M) version_match = version_re.search(pkginfo_contents) if version_match: @@ -91,16 +85,14 @@ def get_package_info(package_name, pkginfo, pkgchk): try: popen_args = {'stdout': subprocess.PIPE, 'stderr': DEVNULL} - if PY3: - popen_args['universal_newlines'] = True + popen_args['universal_newlines'] = True p = subprocess.Popen([pkgchk, '-l', package_name], **popen_args) except EnvironmentError: pass else: pkgchk_contents = p.communicate()[0] - if not PY3: - pkgchk_contents.decode() + pkgchk_contents.decode() pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M) pathname_match = pathname_re.search(pkgchk_contents) if pathname_match: diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py index 9e2327a..48a2904 100644 --- a/src/engine/SCons/Tool/textfile.py +++ b/src/engine/SCons/Tool/textfile.py @@ -53,13 +53,10 @@ import re from SCons.Node import Node from SCons.Node.Python import Value -from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes, PY3 +from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes -if PY3: - TEXTFILE_FILE_WRITE_MODE = 'w' -else: - TEXTFILE_FILE_WRITE_MODE = 'wb' +TEXTFILE_FILE_WRITE_MODE = 'w' LINESEP = '\n' @@ -126,10 +123,7 @@ def _action(target, source, env): # write the file try: - if SCons.Util.PY3: - target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE, newline='') - else: - target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE) + target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE, newline='') except (OSError, IOError): raise SCons.Errors.UserError("Can't write target file %s" % target[0]) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 8ff7b4f..130cc5e 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -1567,11 +1567,8 @@ del __revision__ def to_bytes(s): if s is None: return b'None' - if not PY3 and isinstance(s, str): - # PY2, must encode unicode - return bytearray(s, 'utf-8') - if isinstance (s, (bytes, bytearray)) or bytes is str: - # Above case not covered here as py2 bytes and strings are the same + if isinstance(s, (bytes, bytearray)): + # if already bytes return. return s return bytes(s, 'utf-8') @@ -1579,9 +1576,9 @@ def to_bytes(s): def to_str(s): if s is None: return 'None' - if bytes is str or is_String(s): + if is_String(s): return s - return str (s, 'utf-8') + return str(s, 'utf-8') def cmp(a, b): diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 870e79f..3e700c9 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -311,10 +311,9 @@ class UtilTestCase(unittest.TestCase): def test_to_Bytes(self): """ Test the to_Bytes method""" - if not PY3: - self.assertEqual(to_bytes(str('Hello')), - bytearray(u'Hello', 'utf-8'), - "Check that to_bytes creates byte array when presented with unicode string. PY2 only") + self.assertEqual(to_bytes(str('Hello')), + bytearray(u'Hello', 'utf-8'), + "Check that to_bytes creates byte array when presented with unicode string.") def test_to_String(self): """Test the to_String() method.""" -- cgit v0.12 From ef41a6e48ba1f29daf762e5a8624a6b44fe97fa8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 9 Jan 2020 17:00:52 -0800 Subject: Resolve mwichmann's commments on PR removing extraneous code --- src/engine/SCons/Taskmaster.py | 2 +- src/engine/SCons/UtilTests.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 7363915..1e5776c 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -792,7 +792,7 @@ class Taskmaster(object): self.ready_exc = None T = self.trace - if T: T.write(str('\n') + self.trace_message('Looking for a node to evaluate')) + if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) while True: node = self.next_candidate() diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 3e700c9..ee07e61 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -311,8 +311,8 @@ class UtilTestCase(unittest.TestCase): def test_to_Bytes(self): """ Test the to_Bytes method""" - self.assertEqual(to_bytes(str('Hello')), - bytearray(u'Hello', 'utf-8'), + self.assertEqual(to_bytes('Hello'), + bytearray('Hello', 'utf-8'), "Check that to_bytes creates byte array when presented with unicode string.") def test_to_String(self): -- cgit v0.12 From 589b0a4a29353df1d1fe4177eae578fc6754f7ac Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 10 Jan 2020 10:26:46 -0500 Subject: Update and improve tests This change integrates various review feedback, including: 1. Validates the result of Dir.get_contents() in PythonTests.py. 2. Adds a functional test for having value as a dependency. --- src/engine/SCons/Node/PythonTests.py | 3 +- test/CacheDir/value.py | 47 -------------------------- test/CacheDir/value_dependencies.py | 52 +++++++++++++++++++++++++++++ test/CacheDir/value_dependencies/SConstruct | 30 +++++++++++++++++ test/CacheDir/value_dependencies/testfile | 0 test/fixture/cachedir_foo_value/SConstruct | 19 ----------- test/fixture/cachedir_foo_value/foo.c | 1 - 7 files changed, 84 insertions(+), 68 deletions(-) delete mode 100644 test/CacheDir/value.py create mode 100644 test/CacheDir/value_dependencies.py create mode 100644 test/CacheDir/value_dependencies/SConstruct create mode 100644 test/CacheDir/value_dependencies/testfile delete mode 100644 test/fixture/cachedir_foo_value/SConstruct delete mode 100644 test/fixture/cachedir_foo_value/foo.c diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 45248d3..da71074 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -120,7 +120,8 @@ class ValueChildTestCase(unittest.TestCase): node._func_get_contents = 2 # Pretend to be a Dir. node.add_to_implicit([value]) contents = node.get_contents() - assert len(contents) > 0 + expected_contents = '%s %s\n' % (value.get_csig(), value.name) + assert contents == expected_contents class ValueMemoTestCase(unittest.TestCase): diff --git a/test/CacheDir/value.py b/test/CacheDir/value.py deleted file mode 100644 index fd89a9e..0000000 --- a/test/CacheDir/value.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# 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. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Verify that bwuilds with caching work for an action with a Value as a child. -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.dir_fixture('cachedir_foo_value') -test.subdir('cache') - -# First build, populates the cache -test.run(arguments='.') - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/CacheDir/value_dependencies.py b/test/CacheDir/value_dependencies.py new file mode 100644 index 0000000..7992bef --- /dev/null +++ b/test/CacheDir/value_dependencies.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# 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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify that bwuilds with caching work for an action with a Value as a child +in a variety of cases. Specifically: + +1. A source file that depends on a Value. +2. A source directory that depends on a Value. +3. A scanner that returns a Value and a directory that depends on a Value. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('value_dependencies') +test.subdir('cache') + +# First build, populates the cache +test.run(arguments='.') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/CacheDir/value_dependencies/SConstruct b/test/CacheDir/value_dependencies/SConstruct new file mode 100644 index 0000000..649648b --- /dev/null +++ b/test/CacheDir/value_dependencies/SConstruct @@ -0,0 +1,30 @@ +import SCons.Node + +CacheDir('cache') + +def b(target, source, env): + with open(target[0].abspath, 'w') as f: + pass + +def scan(node, env, path): + # Have the node depend on a directory, which depends on an instance of + # SCons.Node.Python.Value. + sample_dir = env.fs.Dir('dir2') + env.Depends(sample_dir, env.Value('c')) + return [sample_dir, env.Value('d')] + +scanner = Scanner(function=scan, node_class=SCons.Node.Node) +builder = Builder(action=b, source_scanner=scanner) + +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')) + +sample_file = env.fs.File('testfile') +env.Depends(sample_file, env.Value('b')) + +env.B(target='File1.out', source=[sample_dir, sample_file]) diff --git a/test/CacheDir/value_dependencies/testfile b/test/CacheDir/value_dependencies/testfile new file mode 100644 index 0000000..e69de29 diff --git a/test/fixture/cachedir_foo_value/SConstruct b/test/fixture/cachedir_foo_value/SConstruct deleted file mode 100644 index b144799..0000000 --- a/test/fixture/cachedir_foo_value/SConstruct +++ /dev/null @@ -1,19 +0,0 @@ -import SCons.Node - -CacheDir('cache') - -def b(target, source, env): - with open(target[0].abspath, 'w') as f: - pass - -def scan(node, env, path): - return [env.Value('a')] - -scanner = Scanner(function=scan, node_class=SCons.Node.Node) -builder = Builder(action=b, source_scanner=scanner) - -env = Environment() -env.Append(BUILDERS={'B': builder}) - -env.B(target='File1.out', source='foo.c') -#env.Program('foo', foo_c) diff --git a/test/fixture/cachedir_foo_value/foo.c b/test/fixture/cachedir_foo_value/foo.c deleted file mode 100644 index 5ab8d0f..0000000 --- a/test/fixture/cachedir_foo_value/foo.c +++ /dev/null @@ -1 +0,0 @@ -int main(void){ return 0; } -- cgit v0.12 From 5c708ef1fbc6767582ccb71f2dffc28e6efd11c8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 10 Jan 2020 07:49:48 -0700 Subject: Clean up some manpage duplication, File, Dir Removed some dupes in the Construction Variables section - the JAR entries plus File, Dir. Tweaked the File and Dir function entries, and the File and Directory Nodes section. The end-to-end tests for File and Dir didn't test the case of supplying a list-of-strings (thus returning a list-of-nodes) to those two functions, added a primitive one. Signed-off-by: Mats Wichmann --- doc/man/scons.xml | 145 ++++++++++++++++-------------------- src/engine/SCons/Environment.xml | 46 +++++------- src/engine/SCons/Tool/packaging.xml | 66 +--------------- test/Dir/Dir.py | 18 +++-- test/File.py | 14 +++- 5 files changed, 107 insertions(+), 182 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index bd8d5f0..289d840 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -4383,20 +4383,17 @@ vars.AddVariables( -File and Directory Nodes + +File and Directory Nodes -The -File() -and -Dir() -functions return -File -and -Dir -Nodes, respectively. -Python objects, respectively. -Those objects have several user-visible attributes -and methods that are often useful: + +The &f-link-File; and &f-link-Dir; +functions/methods return +File and Directory Nodes, respectively. +Such nodes are Python objects with +several user-visible attributes +and methods that are often useful to access +in SConscript files: @@ -4412,33 +4409,31 @@ file is found). The build path is the same as the source path if variant_dir is not being used. - + abspath The absolute build path of the given file or directory. - + srcnode() The srcnode() method -returns another -File -or -Dir -object representing the -source -path of the given -File -or -Dir. -The +returns another File or Directory Node +representing the source path of the given +File or Directory Node. + + + + + +For example: # Get the current build dir's path, relative to top. @@ -4451,98 +4446,90 @@ File('foo.c').srcnode().path # source path of the given source file. # Builders also return File objects: foo = env.Program('foo.c') -print("foo will be built in %s"%foo.path) +print("foo will be built in", foo.path) -A -Dir -Node or -File -Node can also be used to create -file and subdirectory Nodes relative to the generating Node. -A -Dir -Node will place the new Nodes within the directory it represents. -A -File -node will place the new Nodes within its parent directory -(that is, "beside" the file in question). -If -d -is a -Dir -(directory) Node and -f -is a -File -(file) Node, -then these methods are available: + +Node objects have methods to create +File and Directory Nodes relative to the orignal Node. + + + +If the object is a Directory Node, +these methods will place the the new Node within the directory +the Node represents: + - - - - d.Dir(name) + d.Dir(name) Returns a directory Node for a subdirectory of -d +d named -name. - +name. + - d.File(name) + d.File(name) Returns a file Node for a file within -d +d named -name. - +name. + - d.Entry(name) + d.Entry(name) Returns an unresolved Node within -d +d named -name. - +name. + + + +If the object is a File Node, +these methods will place the the new Node in the same +directory as the one the Node represents: + + + - f.Dir(name) + d.Dir(name) Returns a directory named -name +name within the parent directory of -f. - +f. + - f.File(name) + d.File(name) Returns a file named -name +name within the parent directory of -f. - +f. + - f.Entry(name) + d.Entry(name) Returns an unresolved Node named -name +name within the parent directory of -f. - +f. + For example: @@ -5923,7 +5910,7 @@ action='$CC -c -o $TARGET $SOURCES' cc -c -o foo foo.c bar.c -Variable names may be surrounded by curly braces +Variable names may be surrounded by curly braces { } to separate the name from surrounding characters which are not part of the name. @@ -7200,7 +7187,7 @@ in addition to those passed on the command line. (Windows only). If set, save the shell environment variables generated when setting up the Microsoft Visual C++ compiler -(and/or Build Tools) to a file to give these settings, +(and/or Build Tools) to a file to give these settings, which are expensive to generate, persistence across &scons; invocations. Use of this option is primarily intended to aid performance diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 35e4bd8..286e882 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -65,15 +65,6 @@ env['BUILDERS']['NewBuilder'] = foo - - - -A function that converts a string -into a Dir instance relative to the target being built. - - - - @@ -130,15 +121,6 @@ env = Environment(ENV = {'PATH' : os.environ['PATH']}) - - - -A function that converts a string into a File instance relative to the -target being built. - - - - @@ -1351,11 +1333,10 @@ cc_values = env.Dictionary('CC', 'CCFLAGS', 'CCCOM') -This returns a Directory Node, -an object that represents the specified directory -name. +Returns Directory Node(s). +A Directory Node is an object that represents a directory. name -can be a relative or absolute path. +can be a relative or absolute path or a list of such paths. directory is an optional directory that will be used as the parent directory. If no @@ -1366,7 +1347,10 @@ is specified, the current script's directory is used as the parent. If name -is a list, SCons returns a list of Dir nodes. +is a single pathname, the corresponding node is returned. +If +name +is a list, SCons returns a list of nodes. Construction variables are expanded in name. @@ -1511,20 +1495,24 @@ if Execute("mkdir sub/dir/ectory"): -This returns a -File Node, -an object that represents the specified file -name. +Returns File Node(s). +A File Node is an object that represents a file. name -can be a relative or absolute path. +can be a relative or absolute path or a list of such paths. directory is an optional directory that will be used as the parent directory. +If no +directory +is specified, the current script's directory is used as the parent. If name -is a list, SCons returns a list of File nodes. +is a single pathname, the corresponding node is returned. +If +name +is a list, SCons returns a list of nodes. Construction variables are expanded in name. diff --git a/src/engine/SCons/Tool/packaging.xml b/src/engine/SCons/Tool/packaging.xml index 8ab4912..55fecec 100644 --- a/src/engine/SCons/Tool/packaging.xml +++ b/src/engine/SCons/Tool/packaging.xml @@ -34,7 +34,7 @@ A framework for building binary and source packages. -Builds a Binary Package of the given source files. +Builds a Binary Package of the given source files. @@ -43,68 +43,4 @@ env.Package(source = FindInstalledFiles()) - - - -The Java archive tool. - - - - - - - -The directory to which the Java archive tool should change -(using the - -option). - - - - - - - -The command line used to call the Java archive tool. - - - - - - - -The string displayed when the Java archive tool -is called -If this is not set, then &cv-JARCOM; (the command line) is displayed. - - - -env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET") - - - - - - - -General options passed to the Java archive tool. -By default this is set to - -to create the necessary -jar -file. - - - - - - - -The suffix for Java archives: -.jar -by default. - - - - diff --git a/test/Dir/Dir.py b/test/Dir/Dir.py index e726b94..42a48f3 100644 --- a/test/Dir/Dir.py +++ b/test/Dir/Dir.py @@ -36,28 +36,34 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ DefaultEnvironment(tools=[]) -env = Environment(tools=[], FOO = 'fff', BAR = 'bbb') +env = Environment(tools=[], FOO='fff', BAR='bbb') print(Dir('ddd')) print(Dir('$FOO')) print(Dir('${BAR}_$BAR')) +rv = Dir(['mmm', 'nnn']) +rv_msg = [node.path for node in rv] +print(rv_msg) print(env.Dir('eee')) print(env.Dir('$FOO')) print(env.Dir('${BAR}_$BAR')) +rv = env.Dir(['ooo', 'ppp']) +rv_msg = [node.path for node in rv] +print(rv_msg) """) -test.run(stdout = test.wrap_stdout(read_str = """\ +test.run(stdout=test.wrap_stdout(read_str="""\ ddd $FOO ${BAR}_$BAR +['mmm', 'nnn'] eee fff bbb_bbb -""", build_str = """\ +['ooo', 'ppp'] +""", build_str="""\ scons: `.' is up to date. """)) - - test.write('SConstruct', """\ DefaultEnvironment(tools=[]) import os @@ -66,7 +72,7 @@ def my_mkdir(target=None, source=None, env=None): MDBuilder = Builder(action=my_mkdir, target_factory=Dir) env = Environment(tools=[]) -env.Append(BUILDERS = {'MD':MDBuilder}) +env.Append(BUILDERS={'MD': MDBuilder}) env.MD(target='sub1', source=['SConstruct']) env.MD(target='sub2', source=['SConstruct'], OVERRIDE='foo') """) diff --git a/test/File.py b/test/File.py index ec148b2..bde4449 100644 --- a/test/File.py +++ b/test/File.py @@ -37,13 +37,19 @@ import TestSCons test = TestSCons.TestSCons() test.write('SConstruct', """ -env = Environment(FOO = 'fff', BAR = 'bbb') +env = Environment(FOO='fff', BAR='bbb') print(File('ddd')) print(File('$FOO')) print(File('${BAR}_$BAR')) +rv = File(['mmm', 'nnn']) +rv_msg = [node.path for node in rv] +print(rv_msg) print(env.File('eee')) print(env.File('$FOO')) print(env.File('${BAR}_$BAR')) +rv = env.File(['ooo', 'ppp']) +rv_msg = [node.path for node in rv] +print(rv_msg) f1 = env.File('f1') print(f1) f2 = f1.File('f2') @@ -54,16 +60,18 @@ expect = test.wrap_stdout(read_str = """\ ddd $FOO ${BAR}_$BAR +['mmm', 'nnn'] eee fff bbb_bbb +['ooo', 'ppp'] f1 f2 -""", build_str = """\ +""", build_str="""\ scons: `.' is up to date. """) -test.run(stdout = expect) +test.run(stdout=expect) test.pass_test() -- cgit v0.12 From 16a7153d8564fe9f14bac7e6ec4136dbbef6df5a Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Fri, 10 Jan 2020 12:49:12 -0500 Subject: Add a Tool that hooks up the python scanner --- src/engine/SCons/Tool/__init__.py | 2 ++ src/engine/SCons/Tool/python.py | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 src/engine/SCons/Tool/python.py diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 14306ab..99a958c 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -1312,6 +1312,8 @@ def tool_list(platform, env): 'tar', 'zip', # File builders (text) 'textfile', + # Python scanner tool + 'python', ], env) tools = ([linker, c_compiler, cxx_compiler, diff --git a/src/engine/SCons/Tool/python.py b/src/engine/SCons/Tool/python.py new file mode 100644 index 0000000..c61fc8d --- /dev/null +++ b/src/engine/SCons/Tool/python.py @@ -0,0 +1,49 @@ +"""SCons.Tool.python + +Registers the Python scanner for the supported Python source file suffixes. + +""" + +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# 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. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Tool +from SCons.Scanner.Python import PythonScanner, PythonSuffixes + + +def generate(env): + """Hook the python builder and scanner into the environment.""" + for suffix in PythonSuffixes: + SCons.Tool.SourceFileScanner.add_scanner(suffix, PythonScanner) + + +def exists(env): + return True + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: -- cgit v0.12 From 3247b7e825c78eae110651d363d0bfd36d0e1081 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 23 Jan 2019 18:26:46 -0700 Subject: Align way TeX and related tool names reported by tests Two concrete changes: DVIPS/DVIPS test ran only if dvips tool is found, but did not leave any message if not. Print a skip message if tool not found, which also lets us dedent the rest of the test for the case where we continue due to having found it. TEX/variant_dir test did not check for dvipdf tool, but then calls the tool. Add a check so we get a skip message instead of a fail (the fail had lots of lines but it hard to see actual reason). Fix one test which failed for me due to not checking for its tool. For the rest, align "Could not find" messages to quote the tool name, which most of the tests do - so this is just stylistic, has no functional effect. Also stylistic: use any/all for checking multiple tools' existence. Signed-off-by: Mats Wichmann --- test/DVIPDF/makeindex.py | 6 ++-- test/DVIPS/DVIPS.py | 40 +++++++++++------------ test/TEX/TEX.py | 2 +- test/TEX/auxiliaries.py | 4 +-- test/TEX/bibliography.py | 6 ++-- test/TEX/bibtex-latex-rerun.py | 2 +- test/TEX/clean.py | 2 +- test/TEX/configure.py | 4 +-- test/TEX/dryrun.py | 2 +- test/TEX/glossaries.py | 2 +- test/TEX/glossary.py | 2 +- test/TEX/lstinputlisting.py | 2 +- test/TEX/makeindex.py | 4 +-- test/TEX/multi-line_include_options.py | 2 +- test/TEX/multi-run.py | 7 ++-- test/TEX/newglossary.py | 2 +- test/TEX/nomencl.py | 2 +- test/TEX/recursive_scanner_dependencies_import.py | 2 +- test/TEX/recursive_scanner_dependencies_input.py | 2 +- test/TEX/rename_result.py | 2 +- test/TEX/synctex.py | 2 +- test/TEX/usepackage.py | 2 +- test/TEX/variant_dir.py | 5 +-- test/TEX/variant_dir_bibunit.py | 4 +-- test/TEX/variant_dir_dup0.py | 4 +-- test/TEX/variant_dir_newglossary.py | 2 +- test/TEX/variant_dir_style_dup0.py | 4 +-- 27 files changed, 59 insertions(+), 61 deletions(-) diff --git a/test/DVIPDF/makeindex.py b/test/DVIPDF/makeindex.py index b4ac2d0..bb44d27 100644 --- a/test/DVIPDF/makeindex.py +++ b/test/DVIPDF/makeindex.py @@ -32,15 +32,15 @@ test = TestSCons.TestSCons() dvipdf = test.where_is('dvipdf') if not dvipdf: - test.skip_test('Could not find dvipdf; skipping test(s).\n') + test.skip_test("Could not find 'dvipdf'; skipping test(s).\n") tex = test.where_is('tex') if not tex: - test.skip_test('Could not find tex; skipping test(s).\n') + test.skip_test("Could not find 'tex'; skipping test(s).\n") latex = test.where_is('latex') if not latex: - test.skip_test('Could not find latex; skipping test(s).\n') + test.skip_test("Could not find 'latex'; skipping test(s).\n") diff --git a/test/DVIPS/DVIPS.py b/test/DVIPS/DVIPS.py index 27e89ba..df7811a 100644 --- a/test/DVIPS/DVIPS.py +++ b/test/DVIPS/DVIPS.py @@ -116,13 +116,13 @@ test.must_match('test4.ps', "This is a .latex test.\n", mode='r') have_latex = test.where_is('latex') if not have_latex: - test.skip_test('Could not find latex; skipping test(s).\n') + test.skip_test("Could not find 'latex'; skipping test(s).\n") dvips = test.where_is('dvips') +if not dvips: + test.skip_test("Could not find 'dvips'; skipping test(s).\n") -if dvips: - - test.write("wrapper.py", """ +test.write("wrapper.py", """ import os import sys cmd = " ".join(sys.argv[1:]) @@ -130,7 +130,7 @@ open('%s', 'a').write("%%s\\n" %% cmd) os.system(cmd) """ % test.workpath('wrapper.out').replace('\\', '\\\\')) - test.write('SConstruct', """ +test.write('SConstruct', """ import os ENV = { 'PATH' : os.environ['PATH'] } foo = Environment(ENV = ENV) @@ -142,41 +142,41 @@ bar.PostScript(target = 'bar2', source = 'bar2.ltx') bar.PostScript(target = 'bar3', source = 'bar3.latex') """ % locals()) - tex = r""" +tex = r""" This is the %s TeX file. \end """ - latex = r""" +latex = r""" \documentclass{letter} \begin{document} This is the %s LaTeX file. \end{document} """ - test.write('foo.tex', tex % 'foo.tex') - test.write('bar1.tex', tex % 'bar1.tex') - test.write('bar2.ltx', latex % 'bar2.ltx') - test.write('bar3.latex', latex % 'bar3.latex') +test.write('foo.tex', tex % 'foo.tex') +test.write('bar1.tex', tex % 'bar1.tex') +test.write('bar2.ltx', latex % 'bar2.ltx') +test.write('bar3.latex', latex % 'bar3.latex') - test.run(arguments = 'foo.dvi', stderr = None) +test.run(arguments = 'foo.dvi', stderr = None) - test.must_not_exist(test.workpath('wrapper.out')) +test.must_not_exist(test.workpath('wrapper.out')) - test.must_exist(test.workpath('foo.dvi')) +test.must_exist(test.workpath('foo.dvi')) - test.run(arguments = 'bar1.ps bar2.ps bar3.ps', stderr = None) +test.run(arguments = 'bar1.ps bar2.ps bar3.ps', stderr = None) - expect = """dvips -o bar1.ps bar1.dvi +expect = """dvips -o bar1.ps bar1.dvi dvips -o bar2.ps bar2.dvi dvips -o bar3.ps bar3.dvi """ - test.must_match('wrapper.out', expect, mode='r') +test.must_match('wrapper.out', expect, mode='r') - test.must_exist(test.workpath('bar1.ps')) - test.must_exist(test.workpath('bar2.ps')) - test.must_exist(test.workpath('bar3.ps')) +test.must_exist(test.workpath('bar1.ps')) +test.must_exist(test.workpath('bar2.ps')) +test.must_exist(test.workpath('bar3.ps')) test.pass_test() diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 3964eb8..f0d4043 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -38,7 +38,7 @@ test = TestSCons.TestSCons() have_latex = test.where_is('latex') if not have_latex: - test.skip_test('Could not find latex; skipping test(s).\n') + test.skip_test("Could not find 'latex'; skipping test(s).\n") test.write('mytex.py', r""" diff --git a/test/TEX/auxiliaries.py b/test/TEX/auxiliaries.py index e28c212..1e37e7a 100644 --- a/test/TEX/auxiliaries.py +++ b/test/TEX/auxiliaries.py @@ -45,8 +45,8 @@ test = TestSCons.TestSCons() dvips = test.where_is('dvips') latex = test.where_is('latex') -if not dvips or not latex: - test.skip_test("Could not find dvips or latex; skipping test(s).\n") +if not all((dvips, latex)): + test.skip_test("Could not find 'dvips' and/or 'latex'; skipping test(s).\n") test.subdir(['docs']) diff --git a/test/TEX/bibliography.py b/test/TEX/bibliography.py index a8032db..afccf8f 100644 --- a/test/TEX/bibliography.py +++ b/test/TEX/bibliography.py @@ -38,15 +38,15 @@ test = TestSCons.TestSCons() dvips = test.where_is('dvips') if not dvips: - test.skip_test("Could not find dvips; skipping test(s).\n") + test.skip_test("Could not find 'dvips'; skipping test(s).\n") bibtex = test.where_is('bibtex') if not bibtex: - test.skip_test("Could not find bibtex; skipping test(s).\n") + test.skip_test("Could not find 'bibtex'; skipping test(s).\n") have_latex = test.where_is('latex') if not have_latex: - test.skip_test('Could not find latex; skipping test(s).\n') + test.skip_test("Could not find 'latex'; skipping test(s).\n") test.write('SConstruct', """\ diff --git a/test/TEX/bibtex-latex-rerun.py b/test/TEX/bibtex-latex-rerun.py index 300f03b..f0f8c34 100644 --- a/test/TEX/bibtex-latex-rerun.py +++ b/test/TEX/bibtex-latex-rerun.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() pdflatex = test.where_is('pdflatex') if not pdflatex: - test.skip_test("Could not find pdflatex; skipping test(s).\n") + test.skip_test("Could not find 'pdflatex'; skipping test(s).\n") test.write(['SConstruct'], """\ import os diff --git a/test/TEX/clean.py b/test/TEX/clean.py index ad828d2..781caa1 100644 --- a/test/TEX/clean.py +++ b/test/TEX/clean.py @@ -36,7 +36,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find tex or latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") comment = os.system('kpsewhich comment.sty') if not comment==0: diff --git a/test/TEX/configure.py b/test/TEX/configure.py index 763f86f..9fb4b3e 100644 --- a/test/TEX/configure.py +++ b/test/TEX/configure.py @@ -40,8 +40,8 @@ test = TestSCons.TestSCons() dvips = test.where_is('dvips') latex = test.where_is('latex') -if not dvips or not latex: - test.skip_test("Could not find dvips or latex; skipping test(s).\n") +if not all((dvips, latex)): + test.skip_test("Could not find 'dvips' and/or 'latex'; skipping test(s).\n") NCR = test.NCR # non-cached rebuild diff --git a/test/TEX/dryrun.py b/test/TEX/dryrun.py index 4265791..90357fc 100644 --- a/test/TEX/dryrun.py +++ b/test/TEX/dryrun.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test('could not find latex; skipping test\n') + test.skip_test("could not find 'latex'; skipping test\n") test.write('SConstruct', """ import os diff --git a/test/TEX/glossaries.py b/test/TEX/glossaries.py index 21180a0..cbb6964 100644 --- a/test/TEX/glossaries.py +++ b/test/TEX/glossaries.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") gloss = os.system('kpsewhich glossaries.sty') if not gloss==0: diff --git a/test/TEX/glossary.py b/test/TEX/glossary.py index 0becb40..ef13ca1 100644 --- a/test/TEX/glossary.py +++ b/test/TEX/glossary.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") gloss = os.system('kpsewhich glossary.sty') if not gloss==0: diff --git a/test/TEX/lstinputlisting.py b/test/TEX/lstinputlisting.py index 1d60df7..1f5020b 100644 --- a/test/TEX/lstinputlisting.py +++ b/test/TEX/lstinputlisting.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() pdflatex = test.where_is('pdflatex') if not pdflatex: - test.skip_test("Could not find pdflatex; skipping test(s).\n") + test.skip_test("Could not find 'pdflatex'; skipping test(s).\n") listings = os.system('kpsewhich listings.sty') if not listings==0: diff --git a/test/TEX/makeindex.py b/test/TEX/makeindex.py index 960ed68..0b81f31 100644 --- a/test/TEX/makeindex.py +++ b/test/TEX/makeindex.py @@ -38,8 +38,8 @@ test = TestSCons.TestSCons() pdflatex = test.where_is('pdflatex') makeindex = test.where_is('makeindex') -if not pdflatex or not makeindex: - test.skip_test("Could not find pdflatex or makeindex; skipping test(s).\n") +if not all((pdflatex, makeindex)): + test.skip_test("Could not find 'pdflatex' and/or 'makeindex'; skipping test(s).\n") test.write('SConstruct', """\ import os diff --git a/test/TEX/multi-line_include_options.py b/test/TEX/multi-line_include_options.py index bb8a5f2..94466b6 100644 --- a/test/TEX/multi-line_include_options.py +++ b/test/TEX/multi-line_include_options.py @@ -44,7 +44,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") test.write('SConstruct', """\ import os diff --git a/test/TEX/multi-run.py b/test/TEX/multi-run.py index 9de0da4..3c4e901 100644 --- a/test/TEX/multi-run.py +++ b/test/TEX/multi-run.py @@ -38,11 +38,8 @@ test = TestSCons.TestSCons() tex = test.where_is('tex') latex = test.where_is('latex') - -if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") -if not tex and not latex: - test.skip_test("Could not find tex or latex; skipping test(s).\n") +if not all((tex, latex)): + test.skip_test("Could not find 'tex' and/or 'latex'; skipping test(s).\n") test.subdir('work1', 'work2', 'work3', 'work4') diff --git a/test/TEX/newglossary.py b/test/TEX/newglossary.py index faae7d3..5d868a8 100644 --- a/test/TEX/newglossary.py +++ b/test/TEX/newglossary.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") gloss = os.system('kpsewhich glossaries.sty') if not gloss==0: diff --git a/test/TEX/nomencl.py b/test/TEX/nomencl.py index 7afb84b..0eb0b84 100644 --- a/test/TEX/nomencl.py +++ b/test/TEX/nomencl.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") nomencl = os.system('kpsewhich nomencl.sty') if not nomencl==0: diff --git a/test/TEX/recursive_scanner_dependencies_import.py b/test/TEX/recursive_scanner_dependencies_import.py index c8c6569..a7b5e4a 100644 --- a/test/TEX/recursive_scanner_dependencies_import.py +++ b/test/TEX/recursive_scanner_dependencies_import.py @@ -42,7 +42,7 @@ test = TestSCons.TestSCons() pdflatex = test.where_is('pdflatex') if not pdflatex: - test.skip_test("Could not find pdflatex; skipping test(s).\n") + test.skip_test("Could not find 'pdflatex'; skipping test(s).\n") latex_import = os.system('kpsewhich import.sty') if latex_import != 0: diff --git a/test/TEX/recursive_scanner_dependencies_input.py b/test/TEX/recursive_scanner_dependencies_input.py index 5f37bf1..5afcbc2 100644 --- a/test/TEX/recursive_scanner_dependencies_input.py +++ b/test/TEX/recursive_scanner_dependencies_input.py @@ -36,7 +36,7 @@ test = TestSCons.TestSCons() pdflatex = test.where_is('pdflatex') if not pdflatex: - test.skip_test("Could not find pdflatex; skipping test(s).\n") + test.skip_test("Could not find 'pdflatex'; skipping test(s).\n") test.write(['SConstruct'], """\ env = Environment(tools=['pdftex', 'tex']) diff --git a/test/TEX/rename_result.py b/test/TEX/rename_result.py index b06d388..f67e569 100644 --- a/test/TEX/rename_result.py +++ b/test/TEX/rename_result.py @@ -38,7 +38,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test('could not find latex; skipping test\n') + test.skip_test("could not find 'latex'; skipping test\n") test.write('SConstruct', """ import os diff --git a/test/TEX/synctex.py b/test/TEX/synctex.py index f07db78..385a173 100644 --- a/test/TEX/synctex.py +++ b/test/TEX/synctex.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") test.write('SConstruct', """\ import os diff --git a/test/TEX/usepackage.py b/test/TEX/usepackage.py index 0bb8c22..66510c2 100644 --- a/test/TEX/usepackage.py +++ b/test/TEX/usepackage.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test('could not find latex; skipping test\n') + test.skip_test("could not find 'latex'; skipping test\n") test.write('SConstruct', """ import os diff --git a/test/TEX/variant_dir.py b/test/TEX/variant_dir.py index d81f542..9d05863 100644 --- a/test/TEX/variant_dir.py +++ b/test/TEX/variant_dir.py @@ -36,8 +36,9 @@ import TestSCons test = TestSCons.TestSCons() latex = test.where_is('latex') -if not latex: - test.skip_test("Could not find 'latex'; skipping test.\n") +dvipdf = test.where_is('dvipdf') +if not all((latex, dvipdf)): + test.skip_test("Could not find 'latex' and/or 'dvipdf'; skipping test(s).\n") test.subdir(['docs']) diff --git a/test/TEX/variant_dir_bibunit.py b/test/TEX/variant_dir_bibunit.py index cd3409e..e127a76 100644 --- a/test/TEX/variant_dir_bibunit.py +++ b/test/TEX/variant_dir_bibunit.py @@ -41,8 +41,8 @@ test = TestSCons.TestSCons() latex = test.where_is('pdflatex') bibtex = test.where_is('bibtex') -if not latex or not bibtex: - test.skip_test("Could not find 'latex' or 'bibtex'; skipping test.\n") +if not all((latex, bibtex)): + test.skip_test("Could not find 'latex' and/or 'bibtex'; skipping test.\n") bibunits = os.system('kpsewhich bibunits.sty') if not bibunits==0: diff --git a/test/TEX/variant_dir_dup0.py b/test/TEX/variant_dir_dup0.py index 8f4334f..ea6b51e 100644 --- a/test/TEX/variant_dir_dup0.py +++ b/test/TEX/variant_dir_dup0.py @@ -42,8 +42,8 @@ latex = test.where_is('latex') dvipdf = test.where_is('dvipdf') makeindex = test.where_is('makeindex') bibtex = test.where_is('bibtex') -if not latex or not makeindex or not bibtex or not dvipdf: - test.skip_test("Could not find 'latex', 'makeindex', 'bibtex', or dvipdf; skipping test.\n") +if not all((latex, makeindex, bibtex, dvipdf)): + test.skip_test("Could not find one or more of 'latex', 'makeindex', 'bibtex', or 'dvipdf'; skipping test.\n") test.subdir(['docs']) diff --git a/test/TEX/variant_dir_newglossary.py b/test/TEX/variant_dir_newglossary.py index 1e6ab43..5e4d10d 100644 --- a/test/TEX/variant_dir_newglossary.py +++ b/test/TEX/variant_dir_newglossary.py @@ -39,7 +39,7 @@ test = TestSCons.TestSCons() latex = test.where_is('latex') if not latex: - test.skip_test("Could not find latex; skipping test(s).\n") + test.skip_test("Could not find 'latex'; skipping test(s).\n") gloss = os.system('kpsewhich glossaries.sty') if gloss!=0: diff --git a/test/TEX/variant_dir_style_dup0.py b/test/TEX/variant_dir_style_dup0.py index a9649b0..430b792 100644 --- a/test/TEX/variant_dir_style_dup0.py +++ b/test/TEX/variant_dir_style_dup0.py @@ -45,8 +45,8 @@ latex = test.where_is('latex') dvipdf = test.where_is('dvipdf') makeindex = test.where_is('makeindex') bibtex = test.where_is('bibtex') -if not latex or not makeindex or not bibtex or not dvipdf: - test.skip_test("Could not find 'latex', 'makeindex', 'bibtex', or 'dvipdf'; skipping test.\n") +if not all((latex, makeindex, bibtex, dvipdf)): + test.skip_test("Could not find one or more of 'latex', 'makeindex', 'bibtex', or 'dvipdf'; skipping test.\n") test.subdir(['docs']) -- cgit v0.12 From 1ba8e04976c39dc68b17ef0d40f34b423028923e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sat, 11 Jan 2020 15:57:58 -0800 Subject: [ci skip] minor fixups on PR #3522 --- doc/man/scons.xml | 4 ++-- src/CHANGES.txt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index 289d840..00df1a7 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -4450,8 +4450,8 @@ print("foo will be built in", foo.path) -Node objects have methods to create -File and Directory Nodes relative to the orignal Node. +File and Directory Node objects have methods to create +File and Directory Nodes relative to the original Node. diff --git a/src/CHANGES.txt b/src/CHANGES.txt index a9417c7..37aead1 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -31,6 +31,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - str.format syntax errors fixed - a bunch of linter/checker syntax fixups - Convert remaining uses of insecure/deprecated mktemp method. + - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000 -- cgit v0.12 From c45ad100d6b940bce7be57619e3eaf61c43d5a95 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Mon, 13 Jan 2020 13:57:41 -0500 Subject: [ci skip] Add documentation for the python tool --- src/engine/SCons/Tool/python.xml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/engine/SCons/Tool/python.xml diff --git a/src/engine/SCons/Tool/python.xml b/src/engine/SCons/Tool/python.xml new file mode 100644 index 0000000..e3f7da3 --- /dev/null +++ b/src/engine/SCons/Tool/python.xml @@ -0,0 +1,36 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Loads the Python scanner scanner into the invoking environment. When loaded, the scanner will +attempt to find implicit dependencies for any Python source files in the list of sources +provided to an actual that uses this environment. + + + + + -- cgit v0.12 From 0ab03698067fe6e6fc0a3e245a0a5d42f20960c6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 13 Jan 2020 14:36:51 -0800 Subject: [ci skip] add new python tool module to manifest --- src/engine/MANIFEST.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 7cd9928..3c2c0c2 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -141,6 +141,7 @@ SCons/Tool/pdf.py SCons/Tool/pdflatex.py SCons/Tool/pdftex.py SCons/Tool/PharLapCommon.py +SCons/Tool/python.py SCons/Tool/qt.py SCons/Tool/rmic.py SCons/Tool/rpcgen.py -- cgit v0.12 From 44e28045d9a4a0ee64b40ce4b469fd461df885bb Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 7 Jan 2020 09:36:47 -0700 Subject: docs: refer *COM* and SH*COM* to each other [ci skip] [fixes #2565] Object code intended for use in a shared library may need different compilation options than object code not intended for such use. When SCons tools recognize this need they define parallel sets of variables, such that for FOO there is both FOOCOM and SHFOOCOM, FOOCOMSTR and SHFOOCOMSTR, etc. Refer such pairs to each other. Issue 2565 described a case where a user did not realize they needed to use SHCXXCOMSTR to affect the output for certain C++-compiled objects. The discussion concluded this was just a doc fix. Some examination turned up cases of this in docs for the C compiler, C++ compiler, D compiler, Fortran compiler and linker modules, seemed better to just hit all of those. I would have preferred to move the pairs together into a single entry but it seems the scons doc markup doesn't support this kind of usage - a can take only a single name attribute, and uses it to generate tags, etc. so there would have been a ton of surgery needed to implement that way. Signed-off-by: Mats Wichmann --- doc/generated/variables.mod | 4 ++++ doc/user/output.xml | 13 ++++++++++++- src/engine/SCons/Tool/DCommon.xml | 24 ++++++++++++++++++++++++ src/engine/SCons/Tool/c++.xml | 17 +++++++++++++---- src/engine/SCons/Tool/cc.xml | 22 ++++++++++++++++------ src/engine/SCons/Tool/link.xml | 12 +++++++----- 6 files changed, 76 insertions(+), 16 deletions(-) diff --git a/doc/generated/variables.mod b/doc/generated/variables.mod index ba92aa9..ff44a23 100644 --- a/doc/generated/variables.mod +++ b/doc/generated/variables.mod @@ -65,6 +65,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $CXXVERSION"> $DC"> $DCOM"> +$DCOMSTR"> $DDEBUG"> $DDEBUGPREFIX"> $DDEBUGSUFFIX"> @@ -457,6 +458,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $SHCXXFLAGS"> $SHDC"> $SHDCOM"> +$SHDCOMSTR"> $SHDLIBVERSION"> $SHDLIBVERSIONFLAGS"> $SHDLINK"> @@ -706,6 +708,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $CXXVERSION"> $DC"> $DCOM"> +$DCOMSTR"> $DDEBUG"> $DDEBUGPREFIX"> $DDEBUGSUFFIX"> @@ -1098,6 +1101,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT. $SHCXXFLAGS"> $SHDC"> $SHDCOM"> +$SHDCOMSTR"> $SHDLIBVERSION"> $SHDLIBVERSIONFLAGS"> $SHDLINK"> diff --git a/doc/user/output.xml b/doc/user/output.xml index f9e1a98..d1082a9 100644 --- a/doc/user/output.xml +++ b/doc/user/output.xml @@ -47,7 +47,7 @@ A key aspect of creating a usable build configuration - is providing good output from the build + is providing useful output from the build so its users can readily understand what the build is doing and get information about how to control the build. @@ -355,6 +355,17 @@ cc -o foo.o -c foo.c cc -o foo foo.o + + + A gentle reminder here: many of the commands for building come in + pairs, depending on whether the intent is to build an object for + use in a shared library or not. The command strings mirror this, + so it may be necessary to set, for example, both + CCCOMSTR and SHCCCOMSTR + to get the desired results. + + +
diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml index 7cc47da..6ff08da 100644 --- a/src/engine/SCons/Tool/DCommon.xml +++ b/src/engine/SCons/Tool/DCommon.xml @@ -27,6 +27,7 @@ See its __doc__ string for a discussion of the format. The D compiler to use. +See also &cv-link-SHDC;. @@ -37,6 +38,18 @@ The D compiler to use. The command line used to compile a D file to an object file. Any options specified in the &cv-link-DFLAGS; construction variable is included on this command line. +See also &cv-link-SHDCOM;. + + + + + + + +If set, the string displayed when a D source file +is compiled to a (static) object file. +If not set, then &cv-link-DCOM; (the command line) is displayed. +See also &cv-link-SHDCOMSTR;. @@ -290,6 +303,17 @@ The command line to use when compiling code to be part of shared objects. + + + +If set, the string displayed when a D source file +is compiled to a (shared) object file. +If not set, then &cv-link-SHDCOM; (the command line) is displayed. +See also &cv-link-DCOMSTR;. + + + + diff --git a/src/engine/SCons/Tool/c++.xml b/src/engine/SCons/Tool/c++.xml index b59816b..0918b5f 100644 --- a/src/engine/SCons/Tool/c++.xml +++ b/src/engine/SCons/Tool/c++.xml @@ -47,6 +47,7 @@ Sets construction variables for generic POSIX C++ compilers. CXXCOMSTR +SHCXXCOMSTR @@ -54,6 +55,7 @@ Sets construction variables for generic POSIX C++ compilers. The C++ compiler. +See also &cv-link-SHCXX;. @@ -65,6 +67,7 @@ The command line used to compile a C++ source file to an object file. Any options specified in the &cv-link-CXXFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. +See also &cv-link-SHCXXCOM;. @@ -72,9 +75,10 @@ are included on this command line. -The string displayed when a C++ source file +If set, the string displayed when a C++ source file is compiled to a (static) object file. -If this is not set, then &cv-link-CXXCOM; (the command line) is displayed. +If not set, then &cv-link-CXXCOM; (the command line) is displayed. +See also &cv-link-SHCXXCOMSTR;. @@ -91,6 +95,7 @@ By default, this includes the value of &cv-link-CCFLAGS;, so that setting &cv-CCFLAGS; affects both C and C++ compilation. If you want to add C++-specific flags, you must set or override the value of &cv-link-CXXFLAGS;. +See also &cv-link-SHCXXFLAGS;. @@ -99,6 +104,7 @@ you must set or override the value of &cv-link-CXXFLAGS;. The C++ compiler used for generating shared-library objects. +See also &cv-link-CXX;. @@ -111,6 +117,7 @@ to a shared-library object file. Any options specified in the &cv-link-SHCXXFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. +See also &cv-link-CXXCOM;. @@ -118,9 +125,10 @@ are included on this command line. -The string displayed when a C++ source file +If set, the string displayed when a C++ source file is compiled to a shared object file. -If this is not set, then &cv-link-SHCXXCOM; (the command line) is displayed. +If not set, then &cv-link-SHCXXCOM; (the command line) is displayed. +See also &cv-link-CXXCOMSTR;. @@ -134,6 +142,7 @@ env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET") Options that are passed to the C++ compiler to generate shared-library objects. +See also &cv-link-CXXFLAGS;. diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml index 06e73ff..4150e23 100644 --- a/src/engine/SCons/Tool/cc.xml +++ b/src/engine/SCons/Tool/cc.xml @@ -51,6 +51,8 @@ Sets construction variables for generic POSIX C compilers. PLATFORM +CCCOMSTR +SHCCCOMSTR @@ -67,8 +69,8 @@ The C compiler. The command line used to compile a C source file to a (static) object file. Any options specified in the &cv-link-CFLAGS;, &cv-link-CCFLAGS; and -&cv-link-CPPFLAGS; construction variables are included on this command -line. +&cv-link-CPPFLAGS; construction variables are included on this command line. +See also &cv-link-SHCCCOM;. @@ -76,9 +78,10 @@ line. -The string displayed when a C source file +If set, the string displayed when a C source file is compiled to a (static) object file. -If this is not set, then &cv-link-CCCOM; (the command line) is displayed. +If not set, then &cv-link-CCCOM; (the command line) is displayed. +See also &cv-link-SHCCCOMSTR;. @@ -91,6 +94,7 @@ env = Environment(CCCOMSTR = "Compiling static object $TARGET") General options that are passed to the C and C++ compilers. +See also &cv-link-SHCCFLAGS;. @@ -99,6 +103,7 @@ General options that are passed to the C and C++ compilers. General options that are passed to the C compiler (C only; not C++). +See also &cv-link-SHCFLAGS;. @@ -156,6 +161,7 @@ The default list is: The C compiler used for generating shared-library objects. +See also &cv-link-CC;. @@ -169,6 +175,7 @@ Any options specified in the &cv-link-SHCFLAGS;, &cv-link-SHCCFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. +See also &cv-link-CCCOM;. @@ -176,9 +183,10 @@ are included on this command line. -The string displayed when a C source file +If set, the string displayed when a C source file is compiled to a shared object file. -If this is not set, then &cv-link-SHCCCOM; (the command line) is displayed. +If not set, then &cv-link-SHCCCOM; (the command line) is displayed. +See also &cv-link-CCCOMSTR;. @@ -192,6 +200,7 @@ env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET") Options that are passed to the C and C++ compilers to generate shared-library objects. +See also &cv-link-CCFLAGS;. @@ -201,6 +210,7 @@ to generate shared-library objects. Options that are passed to the C compiler (only; not C++) to generate shared-library objects. +See also &cv-link-CFLAGS;. diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index 654dafc..7a84e1a 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -55,8 +55,8 @@ based on the types of source files. __LDMODULEVERSIONFLAGS -SHLINKCOMSTR LINKCOMSTR +SHLINKCOMSTR LDMODULECOMSTR @@ -184,8 +184,8 @@ On other systems, this is the same as &cv-link-SHLINK;. -The string displayed when building loadable modules. -If this is not set, then &cv-link-LDMODULECOM; (the command line) is displayed. +If set, the string displayed when building loadable modules. +If not set, then &cv-link-LDMODULECOM; (the command line) is displayed. @@ -258,9 +258,10 @@ The command line used to link object files into an executable. -The string displayed when object files +If set, the string displayed when object files are linked into an executable. -If this is not set, then &cv-link-LINKCOM; (the command line) is displayed. +If not set, then &cv-link-LINKCOM; (the command line) is displayed. +See also &cv-link-SHLINKCOMSTR;. @@ -334,6 +335,7 @@ The command line used to link programs using shared libraries. The string displayed when programs using shared libraries are linked. If this is not set, then &cv-link-SHLINKCOM; (the command line) is displayed. +See also &cv-link-LINKCOMSTR;. -- cgit v0.12 From e76236cde61b5e38b4a86ec83533533e4263eec2 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 14 Jan 2020 09:26:46 -0700 Subject: [PR #3524] add two more xrefs in D vars [ci skip] Signed-off-by: Mats Wichmann --- src/engine/SCons/Tool/DCommon.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml index 6ff08da..da496fc 100644 --- a/src/engine/SCons/Tool/DCommon.xml +++ b/src/engine/SCons/Tool/DCommon.xml @@ -291,6 +291,7 @@ DVERSUFFIX. The name of the compiler to use when compiling D source destined to be in a shared objects. +See also &cv-link-DC;. @@ -299,6 +300,7 @@ destined to be in a shared objects. The command line to use when compiling code to be part of shared objects. +See also &cv-link-DCOM;. -- cgit v0.12 From ac8b6c8c4ca2ca15ab1c04ce759faecf8372b654 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 13 Jan 2020 13:43:09 -0700 Subject: Tweak docs a bit [ci skip] * Some clarification on Aliases. * Markup improvements. * Custom decider manpage entry didn't mention fourth arg. While fixing that, noticed an ordering problem in matching User Guide section, and converted example there to use hasttr instead of depending on mainly-for-REPL dir() function. * Call it "empty string" instead of "null string" (more common Python terminology) * Fix the table of installers (again, seems old fixes got lost) * Added a note on installation to try to forestall common confusion. Signed-off-by: Mats Wichmann --- doc/user/depends.xml | 52 ++++++++-------- src/engine/SCons/Environment.xml | 26 ++++---- src/engine/SCons/Script/Main.xml | 88 +++++++++++++++------------- src/engine/SCons/Subst.xml | 2 +- src/engine/SCons/Tool/install.xml | 37 +++++++++--- src/engine/SCons/Tool/javac.xml | 12 ++-- src/engine/SCons/Tool/packaging/__init__.xml | 56 +++++++++--------- src/engine/SCons/Tool/textfile.xml | 10 ++-- 8 files changed, 163 insertions(+), 120 deletions(-) diff --git a/doc/user/depends.xml b/doc/user/depends.xml index 703855d..24bede6 100644 --- a/doc/user/depends.xml +++ b/doc/user/depends.xml @@ -561,13 +561,6 @@ int main() { printf("Hello, world!\n"); } - - The fourth argument repo_node, - is the &Node; to use if it is not None when comparing &BuildInfo;. - This is typically only set when the target node only exists in a - &Repository; - - @@ -612,22 +605,33 @@ int main() { printf("Hello, world!\n"); } - Note that ignoring some of the arguments - in your custom &Decider; function - is a perfectly normal thing to do, - if they don't impact the way you want to - decide if the dependency file has changed. + These attributes may not be present at the time of the + first run. Without any prior build, no targets have been + created and no .sconsign DB file exists yet. + So you should always check whether the + prev_ni attribute in question is available + (use the Python hasattr method or a + try-except block). + + + + + + + The fourth argument repo_node + is the &Node; to use if it is not None when comparing &BuildInfo;. + This is typically only set when the target node only exists in a + &Repository; - Another thing to look out for is the fact that the three - attributes above may not be present at the time of the first run. - Without any prior build, no targets have been created and no - .sconsign DB file exists yet. - So, you should always check whether the - prev_ni attribute in question is available. + Note that ignoring some of the arguments + in your custom &Decider; function + is a perfectly normal thing to do, + if they don't impact the way you want to + decide if the dependency file has changed. @@ -644,13 +648,14 @@ int main() { printf("Hello, world!\n"); } env = Environment() + def config_file_decider(dependency, target, prev_ni, repo_node=None): import os.path # We always have to init the .csig value... dep_csig = dependency.get_csig() # .csig may not exist, because no target was built yet... - if 'csig' not in dir(prev_ni): + if not prev_ni.hasattr("csig"): return True # Target file may not exist yet if not os.path.exists(str(target.abspath)): @@ -660,17 +665,18 @@ def config_file_decider(dependency, target, prev_ni, repo_node=None): return True return False + def update_file(): - f = open("test.txt","a") - f.write("some line\n") - f.close() + with open("test.txt", "a") as f: + f.write("some line\n") + update_file() # Activate our own decider function env.Decider(config_file_decider) -env.Install("install","test.txt") +env.Install("install", "test.txt")
diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 286e882..502e434 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -442,6 +442,8 @@ including another alias. can be called multiple times for the same alias to add additional targets to the alias, or additional actions to the list for this alias. +Aliases are global even if set through +the construction environment method.
@@ -1145,17 +1147,16 @@ env.Decider('content') -In addition to the above already-available functions, -the +In addition to the above already-available functions, the function -argument may be an actual Python function -that takes the following three arguments: +argument may be a Python function you supply. +Such a function must accept the following four arguments: -dependency +dependency The Node (file) which @@ -1169,7 +1170,7 @@ was built. -target +target The Node (file) being built. @@ -1182,7 +1183,7 @@ has "changed." -prev_ni +prev_ni Stored information about the state of the @@ -1198,12 +1199,17 @@ size, or content signature. -repo_node +repo_node -Use this node instead of the one specified by +If set, use this Node instead of the one specified by dependency - to determine if the dependency has changed. +to determine if the dependency has changed. +This argument is optional so should be written +as a default argument (typically it would be +written as repo_node=None). +A caller will normally only set this if the +target only exists in a Repository. diff --git a/src/engine/SCons/Script/Main.xml b/src/engine/SCons/Script/Main.xml index 5c68dee..b54df0e 100644 --- a/src/engine/SCons/Script/Main.xml +++ b/src/engine/SCons/Script/Main.xml @@ -312,7 +312,7 @@ The options supported are: cache_debug -which corresponds to --cache-debug; +which corresponds to ;
@@ -320,7 +320,7 @@ which corresponds to --cache-debug; cache_disable -which corresponds to --cache-disable; +which corresponds to ; @@ -328,7 +328,7 @@ which corresponds to --cache-disable; cache_force -which corresponds to --cache-force; +which corresponds to ; @@ -336,7 +336,7 @@ which corresponds to --cache-force; cache_show -which corresponds to --cache-show; +which corresponds to ; @@ -344,7 +344,8 @@ which corresponds to --cache-show; clean -which corresponds to -c, --clean and --remove; +which corresponds to , +and ; @@ -352,7 +353,7 @@ which corresponds to -c, --clean and --remove; config -which corresponds to --config; +which corresponds to ; @@ -360,7 +361,7 @@ which corresponds to --config; directory -which corresponds to -C and --directory; +which corresponds to and ; @@ -368,7 +369,7 @@ which corresponds to -C and --directory; diskcheck -which corresponds to --diskcheck +which corresponds to ; @@ -376,7 +377,7 @@ which corresponds to --diskcheck duplicate -which corresponds to --duplicate; +which corresponds to ; @@ -384,7 +385,7 @@ which corresponds to --duplicate; file -which corresponds to -f, --file, --makefile and --sconstruct; +which corresponds to , , and ; @@ -392,7 +393,7 @@ which corresponds to -f, --file, --makefile and --sconstruct; help -which corresponds to -h and --help; +which corresponds to and ; @@ -400,7 +401,7 @@ which corresponds to -h and --help; ignore_errors -which corresponds to --ignore-errors; +which corresponds to ; @@ -408,7 +409,7 @@ which corresponds to --ignore-errors; implicit_cache -which corresponds to --implicit-cache; +which corresponds to ; @@ -416,7 +417,7 @@ which corresponds to --implicit-cache; implicit_deps_changed -which corresponds to --implicit-deps-changed; +which corresponds to ; @@ -424,7 +425,7 @@ which corresponds to --implicit-deps-changed; implicit_deps_unchanged -which corresponds to --implicit-deps-unchanged; +which corresponds to ; @@ -432,7 +433,7 @@ which corresponds to --implicit-deps-unchanged; interactive -which corresponds to --interact and --interactive; +which corresponds to and ; @@ -440,7 +441,7 @@ which corresponds to --interact and --interactive; keep_going -which corresponds to -k and --keep-going; +which corresponds to and ; @@ -448,7 +449,7 @@ which corresponds to -k and --keep-going; max_drift -which corresponds to --max-drift; +which corresponds to ; @@ -456,7 +457,9 @@ which corresponds to --max-drift; no_exec -which corresponds to -n, --no-exec, --just-print, --dry-run and --recon; +which corresponds to , +, , + and ; @@ -464,7 +467,7 @@ which corresponds to -n, --no-exec, --just-print, --dry-run and --recon; no_site_dir -which corresponds to --no-site-dir; +which corresponds to ; @@ -472,7 +475,7 @@ which corresponds to --no-site-dir; num_jobs -which corresponds to -j and --jobs; +which corresponds to and ; @@ -480,7 +483,7 @@ which corresponds to -j and --jobs; profile_file -which corresponds to --profile; +which corresponds to ; @@ -488,7 +491,7 @@ which corresponds to --profile; question -which corresponds to -q and --question; +which corresponds to and ; @@ -496,7 +499,7 @@ which corresponds to -q and --question; random -which corresponds to --random; +which corresponds to ; @@ -504,7 +507,7 @@ which corresponds to --random; repository -which corresponds to -Y, --repository and --srcdir; +which corresponds to , and ; @@ -512,7 +515,7 @@ which corresponds to -Y, --repository and --srcdir; silent -which corresponds to -s, --silent and --quiet; +which corresponds to , and ; @@ -520,7 +523,7 @@ which corresponds to -s, --silent and --quiet; site_dir -which corresponds to --site-dir; +which corresponds to ; @@ -528,7 +531,7 @@ which corresponds to --site-dir; stack_size -which corresponds to --stack-size; +which corresponds to ; @@ -536,7 +539,7 @@ which corresponds to --stack-size; taskmastertrace_file -which corresponds to --taskmastertrace; and +which corresponds to ; and @@ -544,7 +547,7 @@ which corresponds to --taskmastertrace; and warn -which corresponds to --warn and --warning. +which corresponds to and . @@ -553,7 +556,7 @@ which corresponds to --warn and --warning. See the documentation for the -corresponding command line object for information about each specific +corresponding command line option for information about each specific option. @@ -749,7 +752,8 @@ line options from a SConscript file. The options supported are: clean -which corresponds to -c, --clean and --remove; +which corresponds to , +and ; @@ -757,7 +761,7 @@ which corresponds to -c, --clean and --remove; duplicate -which corresponds to --duplicate; +which corresponds to ; @@ -765,7 +769,7 @@ which corresponds to --duplicate; help -which corresponds to -h and --help; +which corresponds to and ; @@ -773,7 +777,7 @@ which corresponds to -h and --help; implicit_cache -which corresponds to --implicit-cache; +which corresponds to ; @@ -781,7 +785,7 @@ which corresponds to --implicit-cache; max_drift -which corresponds to --max-drift; +which corresponds to ; @@ -789,7 +793,9 @@ which corresponds to --max-drift; no_exec -which corresponds to -n, --no-exec, --just-print, --dry-run and --recon; +which corresponds to , , +, +and ; @@ -797,7 +803,7 @@ which corresponds to -n, --no-exec, --just-print, --dry-run and --recon; num_jobs -which corresponds to -j and --jobs; +which corresponds to and ; @@ -805,7 +811,7 @@ which corresponds to -j and --jobs; random -which corresponds to --random; and +which corresponds to ; and @@ -813,7 +819,7 @@ which corresponds to --random; and silent -which corresponds to --silent. +which corresponds to . @@ -830,7 +836,7 @@ which corresponds to --stack-size. See the documentation for the -corresponding command line object for information about each specific +corresponding command line option for information about each specific option. diff --git a/src/engine/SCons/Subst.xml b/src/engine/SCons/Subst.xml index 980a9ad..77372ce 100644 --- a/src/engine/SCons/Subst.xml +++ b/src/engine/SCons/Subst.xml @@ -39,7 +39,7 @@ or IndexError exception will expand to a '' -(a null string) and not cause scons to fail. +(an empty string) and not cause scons to fail. All exceptions not in the specified list will generate an error message and terminate processing. diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index 150308b..ce70d91 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -50,10 +50,24 @@ a builder. -env.Install('/usr/local/bin', source = ['foo', 'bar']) +env.Install(target='/usr/local/bin', source=['foo', 'bar']) +Note that if target paths chosen for the +&Install; builder (and the related &InstallAs; and +&InstallVersionedLib; builders) are outside the +project tree, such as in the example above, +they may not be selected for "building" by default, +since in the absence of other instructions +&scons; builds targets that are underneath the top directory +(the directory that contains the &SConstruct; file, +usually the current directory). +Use command line targets or the &Default; function +in this case. + + + If the command line option is given, the target directory will be prefixed by the directory path specified. @@ -86,12 +100,16 @@ arguments list different numbers of files or directories. -env.InstallAs(target = '/usr/local/bin/foo', - source = 'foo_debug') -env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'], - source = ['libFOO.a', 'libBAR.a']) +env.InstallAs(target='/usr/local/bin/foo', + source='foo_debug') +env.InstallAs(target=['../lib/libfoo.a', '../lib/libbar.a'], + source=['libFOO.a', 'libBAR.a']) + +See the note under &Install;. + + @@ -103,9 +121,14 @@ architecture will be generated based on symlinks of the source library. -env.InstallVersionedLib(target = '/usr/local/bin/foo', - source = 'libxyz.1.5.2.so') +env.InstallVersionedLib(target='/usr/local/bin/foo', + source='libxyz.1.5.2.so') + + +See the note under &Install;. + + diff --git a/src/engine/SCons/Tool/javac.xml b/src/engine/SCons/Tool/javac.xml index bc89342..893130b 100644 --- a/src/engine/SCons/Tool/javac.xml +++ b/src/engine/SCons/Tool/javac.xml @@ -95,9 +95,9 @@ See its __doc__ string for a discussion of the format. - env.Java(target = 'classes', source = 'src') - env.Java(target = 'classes', source = ['src1', 'src2']) - env.Java(target = 'classes', source = ['File1.java', 'File2.java']) +env.Java(target = 'classes', source = 'src') +env.Java(target = 'classes', source = ['src1', 'src2']) +env.Java(target = 'classes', source = ['File1.java', 'File2.java']) @@ -114,8 +114,8 @@ See its __doc__ string for a discussion of the format. - env = Environment() - env['ENV']['LANG'] = 'en_GB.UTF-8' +env = Environment() +env['ENV']['LANG'] = 'en_GB.UTF-8' @@ -174,7 +174,7 @@ See its __doc__ string for a discussion of the format. - env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES") +env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES") diff --git a/src/engine/SCons/Tool/packaging/__init__.xml b/src/engine/SCons/Tool/packaging/__init__.xml index 31c6eed..66a7aa0 100644 --- a/src/engine/SCons/Tool/packaging/__init__.xml +++ b/src/engine/SCons/Tool/packaging/__init__.xml @@ -62,24 +62,25 @@ option or with the &cv-PACKAGETYPE; construction variable. Currently the following packagers available: - - * msi - Microsoft Installer - * rpm - RPM Package Manger - * ipkg - Itsy Package Management System - * tarbz2 - bzip2 compressed tar - * targz - gzip compressed tar - * tarxz - xz compressed tar - * zip - zip file - * src_tarbz2 - bzip2 compressed tar source - * src_targz - gzip compressed tar source - * src_tarxz - xz compressed tar source - * src_zip - zip file source - +msi - Microsoft Installer +rpm - RPM Package Manger +ipkg - Itsy Package Management System +tarbz2 - bzip2 compressed tar +targz - gzip compressed tar +tarxz - xz compressed tar +zip - zip file +src_tarbz2 - bzip2 compressed tar source +src_targz - gzip compressed tar source +src_tarxz - xz compressed tar source +src_zip - zip file source -An updated list is always available under the "package_type" option when -running "scons --help" on a project that has packaging activated. +An updated list is always available under the +package_type option when +running scons --help +on a project that has packaging activated. + env = Environment(tools=['default', 'packaging']) env.Install('/bin/', 'my_program') @@ -198,20 +199,21 @@ placed if applicable. The default value is "$NAME-$VERSION". Selects the package type to build. Currently these are available: - - * msi - Microsoft Installer - * rpm - Redhat Package Manger - * ipkg - Itsy Package Management System - * tarbz2 - compressed tar - * targz - compressed tar - * zip - zip file - * src_tarbz2 - compressed tar source - * src_targz - compressed tar source - * src_zip - zip file source - +msi - Microsoft Installer +rpm - RPM Package Manger +ipkg - Itsy Package Management System +tarbz2 - bzip2 compressed tar +targz - gzip compressed tar +tarxz - xz compressed tar +zip - zip file +src_tarbz2 - bzip2 compressed tar source +src_targz - gzip compressed tar source +src_tarxz - xz compressed tar source +src_zip - zip file source -This may be overridden with the "package_type" command line option. +This may be overridden with the +command line option. diff --git a/src/engine/SCons/Tool/textfile.xml b/src/engine/SCons/Tool/textfile.xml index 957e18c..878eb9f 100644 --- a/src/engine/SCons/Tool/textfile.xml +++ b/src/engine/SCons/Tool/textfile.xml @@ -59,7 +59,7 @@ see the &b-Substfile; description for details. The prefix and suffix specified by the &cv-TEXTFILEPREFIX; and &cv-TEXTFILESUFFIX; construction variables -(the null string and .txt by default, respectively) +(an empty string and .txt by default, respectively) are automatically added to the target if they are not already present. Examples: @@ -124,7 +124,7 @@ the suffix is stripped and the remainder is used as the default target name. The prefix and suffix specified by the &cv-SUBSTFILEPREFIX; and &cv-SUBSTFILESUFFIX; construction variables -(the null string by default in both cases) +(an empty string by default in both cases) are automatically added to the target if they are not already present. @@ -218,7 +218,7 @@ lists of tuples are also acceptable. The prefix used for &b-Substfile; file names, -the null string by default. +an empty string by default. @@ -227,7 +227,7 @@ the null string by default. The suffix used for &b-Substfile; file names, -the null string by default. +an empty string by default. @@ -236,7 +236,7 @@ the null string by default. The prefix used for &b-Textfile; file names, -the null string by default. +an empty string by default. -- cgit v0.12 From a7da390bcfa5ba07b1f780db54dce30e3ba7857e Mon Sep 17 00:00:00 2001 From: Jeremy Elson Date: Tue, 14 Jan 2020 13:42:28 -0800 Subject: Change 'Dependency' to 'Depends' in documentation, to match implementation --- doc/design/engine.xml | 14 +++++++------- src/CHANGES.txt | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/design/engine.xml b/doc/design/engine.xml index 39289f9..6b8b2a6 100644 --- a/doc/design/engine.xml +++ b/doc/design/engine.xml @@ -1104,13 +1104,13 @@ you set it up with another environment... - env.Dependency(target = 'output1', dependency = 'input_1 input_2') - env.Dependency(target = 'output2', dependency = ['input_1', 'input_2']) - env.Dependency(target = 'output3', dependency = ['white space input']) + env.Depends(target = 'output1', dependency = 'input_1 input_2') + env.Depends(target = 'output2', dependency = ['input_1', 'input_2']) + env.Depends(target = 'output3', dependency = ['white space input']) - env.Dependency(target = 'output_a output_b', dependency = 'input_3') - env.Dependency(target = ['output_c', 'output_d'], dependency = 'input_4') - env.Dependency(target = ['white space output'], dependency = 'input_5') + env.Depends(target = 'output_a output_b', dependency = 'input_3') + env.Depends(target = ['output_c', 'output_d'], dependency = 'input_4') + env.Depends(target = ['white space output'], dependency = 'input_5') @@ -1129,7 +1129,7 @@ you set it up with another environment... - env.Dependency(target = 'archive.tar.gz', dependency = 'SConstruct') + env.Depends(target = 'archive.tar.gz', dependency = 'SConstruct') diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 7a2144d..694aca0 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -8,7 +8,6 @@ NOTE: The 4.0.0 Release of SCons will drop Python 2.7 Support RELEASE VERSION/DATE TO BE FILLED IN LATER - From William Deegan: - Fix broken clang + MSVC 2019 combination by using MSVC configuration logic to propagate'VCINSTALLDIR' and 'VCToolsInstallDir' which clang tools use to locate @@ -37,6 +36,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Convert remaining uses of insecure/deprecated mktemp method. - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. + From Jeremy Elson: + - Updated design doc to use the correct syntax for Depends() RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000 -- cgit v0.12 From 50154d0eb7afc564cb13e47c7524fcf2f6ff0450 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Tue, 14 Jan 2020 19:44:24 -0500 Subject: Add name parameter as requested in PR --- src/engine/SCons/Environment.py | 4 ++-- src/engine/SCons/Node/Python.py | 9 ++++++--- src/engine/SCons/Node/PythonTests.py | 5 +++++ test/CacheDir/value_dependencies/SConstruct | 8 +++++--- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 3e23196..099d143 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -2220,10 +2220,10 @@ class Base(SubstitutionEnvironment): else: return [self.subst(arg)] - def Value(self, value, built_value=None): + def Value(self, value, built_value=None, name=None): """ """ - return SCons.Node.Python.ValueWithMemo(value, built_value) + return SCons.Node.Python.ValueWithMemo(value, built_value, name) def VariantDir(self, variant_dir, src_dir, duplicate=1): variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 385a645..8437385 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -88,7 +88,7 @@ class Value(SCons.Node.Node): NodeInfo = ValueNodeInfo BuildInfo = ValueBuildInfo - def __init__(self, value, built_value=None): + def __init__(self, value, built_value=None, name=None): SCons.Node.Node.__init__(self) self.value = value self.changed_since_last_build = 6 @@ -98,7 +98,10 @@ class Value(SCons.Node.Node): # Set a name so it can be a child of a node and not break # its parent's implementation of Node.get_contents. - self.name = value + if name: + self.name = name + else: + self.name = str(value) def str_for_display(self): return repr(self.value) @@ -181,7 +184,7 @@ class Value(SCons.Node.Node): return contents -def ValueWithMemo(value, built_value=None): +def ValueWithMemo(value, built_value=None, name=None): global _memo_lookup_map # No current support for memoizing a value that needs to be built. diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index da71074..302bb59 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -64,6 +64,11 @@ class ValueTestCase(unittest.TestCase): v2.build() assert v2.built_value == 'faked', v2.built_value + v3 = SCons.Node.Python.Value(b'\x00\x0F', name='name') + v3.executor = fake_executor() + v3.build() + assert v3.built_value == 'faked', v3.built_value + def test_read(self): """Test the Value.read() method """ diff --git a/test/CacheDir/value_dependencies/SConstruct b/test/CacheDir/value_dependencies/SConstruct index 649648b..7b7e596 100644 --- a/test/CacheDir/value_dependencies/SConstruct +++ b/test/CacheDir/value_dependencies/SConstruct @@ -11,7 +11,7 @@ def scan(node, env, path): # SCons.Node.Python.Value. sample_dir = env.fs.Dir('dir2') env.Depends(sample_dir, env.Value('c')) - return [sample_dir, env.Value('d')] + return [sample_dir, env.Value('d'), env.Value(b'\x03\x0F', name='name3')] scanner = Scanner(function=scan, node_class=SCons.Node.Node) builder = Builder(action=b, source_scanner=scanner) @@ -22,9 +22,11 @@ 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.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.Depends(sample_file, + [env.Value('b'), env.Value(b'\x02\x0F', name='name2')]) env.B(target='File1.out', source=[sample_dir, sample_file]) -- cgit v0.12 From 1f0cd4eac841791d9c0f16f111e627779e566f40 Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Wed, 15 Jan 2020 09:35:14 -0500 Subject: Plumb through name in ValueWithMemo --- src/engine/SCons/EnvironmentTests.py | 4 ++++ src/engine/SCons/Node/Python.py | 2 +- src/engine/SCons/Node/PythonTests.py | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index f3779c7..0cb8418 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -3289,6 +3289,10 @@ def generate(env): v3 = env.Value('c', 'build-c') assert v3.value == 'c', v3.value + v4 = env.Value(b'\x00\x0F', name='name') + assert v4.value == b'\x00\x0F', v4.value + assert v4.name == 'name', v4.name + def test_Environment_global_variable(self): """Test setting Environment variable to an Environment.Base subclass""" diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 8437385..d26c185 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -200,7 +200,7 @@ def ValueWithMemo(value, built_value=None, name=None): try: return _memo_lookup_map[memo_lookup_key] except KeyError: - v = Value(value) + v = Value(value, built_value, name) _memo_lookup_map[memo_lookup_key] = v return v diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 302bb59..6db07ab 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -67,6 +67,7 @@ class ValueTestCase(unittest.TestCase): v3 = SCons.Node.Python.Value(b'\x00\x0F', name='name') v3.executor = fake_executor() v3.build() + assert v3.name == 'name', v3.name assert v3.built_value == 'faked', v3.built_value def test_read(self): -- cgit v0.12 From 73fa5cc34dbe44fc4f1a95ececc9cb7e578215df Mon Sep 17 00:00:00 2001 From: Adam Gross Date: Wed, 15 Jan 2020 09:55:29 -0500 Subject: [ci skip] Update Environment.xml based on the change to env.Value() --- src/engine/SCons/Environment.xml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 35e4bd8..601436e 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -3087,7 +3087,7 @@ env.Tool('opengl', toolpath = ['build/tools']) -(value, [built_value]) +(value, [built_value], [name]) @@ -3102,6 +3102,10 @@ will be rebuilt. files are up-to-date.) When using timestamp source signatures, Value Nodes' timestamps are equal to the system time when the Node is created. +name can be provided as an alternative name +for the resulting Value node; this is advised +if the value parameter can't be converted to +a string. -- cgit v0.12 From ad1c42372bffff3327d1ebc3feb9ca4009430ea7 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 15 Jan 2020 07:25:58 -0700 Subject: [PR #3524] add _why_ you should follow xref [ci skip] per review, note a reason for referring a static/shared construction variable to its shared/static analogue. added a few more xrefs. Signed-off-by: Mats Wichmann --- src/engine/SCons/Tool/DCommon.xml | 18 ++++++++++++------ src/engine/SCons/Tool/c++.xml | 16 ++++++++-------- src/engine/SCons/Tool/cc.xml | 18 +++++++++--------- src/engine/SCons/Tool/f03.xml | 16 ++++++++-------- src/engine/SCons/Tool/f08.xml | 16 ++++++++-------- src/engine/SCons/Tool/f77.xml | 16 ++++++++-------- src/engine/SCons/Tool/f90.xml | 16 ++++++++-------- src/engine/SCons/Tool/f95.xml | 16 ++++++++-------- src/engine/SCons/Tool/fortran.xml | 16 ++++++++-------- src/engine/SCons/Tool/link.xml | 16 +++++++++++----- 10 files changed, 88 insertions(+), 76 deletions(-) diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml index da496fc..6d907c6 100644 --- a/src/engine/SCons/Tool/DCommon.xml +++ b/src/engine/SCons/Tool/DCommon.xml @@ -27,7 +27,7 @@ See its __doc__ string for a discussion of the format. The D compiler to use. -See also &cv-link-SHDC;. +See also &cv-link-SHDC; for compiling to shared objects. @@ -38,7 +38,7 @@ See also &cv-link-SHDC;. The command line used to compile a D file to an object file. Any options specified in the &cv-link-DFLAGS; construction variable is included on this command line. -See also &cv-link-SHDCOM;. +See also &cv-link-SHDCOM; for compiling to shared objects. @@ -49,7 +49,7 @@ See also &cv-link-SHDCOM;. If set, the string displayed when a D source file is compiled to a (static) object file. If not set, then &cv-link-DCOM; (the command line) is displayed. -See also &cv-link-SHDCOMSTR;. +See also &cv-link-SHDCOMSTR; for compiling to shared objects. @@ -194,6 +194,7 @@ DLIBLINKSUFFIX. Name of the linker to use for linking systems including D sources. +See also &cv-link-SHDLINK; for linking shared objects. @@ -202,6 +203,7 @@ Name of the linker to use for linking systems including D sources. The command line to use when linking systems including D sources. +See also &cv-link-SHDLINKCOM; for linking shared objects. @@ -210,6 +212,7 @@ The command line to use when linking systems including D sources. List of linker flags. +See also &cv-link-SHDLINKFLAGS; for linking shared objects. @@ -291,7 +294,7 @@ DVERSUFFIX. The name of the compiler to use when compiling D source destined to be in a shared objects. -See also &cv-link-DC;. +See also &cv-link-DC; for compiling to static objects. @@ -300,7 +303,7 @@ See also &cv-link-DC;. The command line to use when compiling code to be part of shared objects. -See also &cv-link-DCOM;. +See also &cv-link-DCOM; for compiling to static objects. @@ -311,7 +314,7 @@ See also &cv-link-DCOM;. If set, the string displayed when a D source file is compiled to a (shared) object file. If not set, then &cv-link-SHDCOM; (the command line) is displayed. -See also &cv-link-DCOMSTR;. +See also &cv-link-DCOMSTR; for compiling to static objects. @@ -337,6 +340,7 @@ SHDLIBVERSIONFLAGS. The linker to use when creating shared objects for code bases include D sources. +See also &cv-link-DLINK; for linking static objects. @@ -345,6 +349,7 @@ include D sources. The command line to use when generating shared objects. +See also &cv-link-DLINKCOM; for linking static objects. @@ -353,6 +358,7 @@ The command line to use when generating shared objects. The list of flags to use when generating a shared object. +See also &cv-link-DLINKFLAGS; for linking static objects. diff --git a/src/engine/SCons/Tool/c++.xml b/src/engine/SCons/Tool/c++.xml index 0918b5f..019821c 100644 --- a/src/engine/SCons/Tool/c++.xml +++ b/src/engine/SCons/Tool/c++.xml @@ -55,7 +55,7 @@ Sets construction variables for generic POSIX C++ compilers. The C++ compiler. -See also &cv-link-SHCXX;. +See also &cv-link-SHCXX; for compiling to shared objects.. @@ -67,7 +67,7 @@ The command line used to compile a C++ source file to an object file. Any options specified in the &cv-link-CXXFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. -See also &cv-link-SHCXXCOM;. +See also &cv-link-SHCXXCOM; for compiling to shared objects.. @@ -78,7 +78,7 @@ See also &cv-link-SHCXXCOM;. If set, the string displayed when a C++ source file is compiled to a (static) object file. If not set, then &cv-link-CXXCOM; (the command line) is displayed. -See also &cv-link-SHCXXCOMSTR;. +See also &cv-link-SHCXXCOMSTR; for compiling to shared objects.. @@ -95,7 +95,7 @@ By default, this includes the value of &cv-link-CCFLAGS;, so that setting &cv-CCFLAGS; affects both C and C++ compilation. If you want to add C++-specific flags, you must set or override the value of &cv-link-CXXFLAGS;. -See also &cv-link-SHCXXFLAGS;. +See also &cv-link-SHCXXFLAGS; for compiling to shared objects.. @@ -104,7 +104,7 @@ See also &cv-link-SHCXXFLAGS;. The C++ compiler used for generating shared-library objects. -See also &cv-link-CXX;. +See also &cv-link-CXX; for compiling to static objects. @@ -117,7 +117,7 @@ to a shared-library object file. Any options specified in the &cv-link-SHCXXFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. -See also &cv-link-CXXCOM;. +See also &cv-link-CXXCOM; for compiling to static objects. @@ -128,7 +128,7 @@ See also &cv-link-CXXCOM;. If set, the string displayed when a C++ source file is compiled to a shared object file. If not set, then &cv-link-SHCXXCOM; (the command line) is displayed. -See also &cv-link-CXXCOMSTR;. +See also &cv-link-CXXCOMSTR; for compiling to static objects. @@ -142,7 +142,7 @@ env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET") Options that are passed to the C++ compiler to generate shared-library objects. -See also &cv-link-CXXFLAGS;. +See also &cv-link-CXXFLAGS; for compiling to static objects. diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml index 4150e23..e47cf2d 100644 --- a/src/engine/SCons/Tool/cc.xml +++ b/src/engine/SCons/Tool/cc.xml @@ -70,7 +70,7 @@ The C compiler. The command line used to compile a C source file to a (static) object file. Any options specified in the &cv-link-CFLAGS;, &cv-link-CCFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. -See also &cv-link-SHCCCOM;. +See also &cv-link-SHCCCOM; for compiling to shared objects. @@ -81,7 +81,7 @@ See also &cv-link-SHCCCOM;. If set, the string displayed when a C source file is compiled to a (static) object file. If not set, then &cv-link-CCCOM; (the command line) is displayed. -See also &cv-link-SHCCCOMSTR;. +See also &cv-link-SHCCCOMSTR; for compiling to shared objects. @@ -94,7 +94,7 @@ env = Environment(CCCOMSTR = "Compiling static object $TARGET") General options that are passed to the C and C++ compilers. -See also &cv-link-SHCCFLAGS;. +See also &cv-link-SHCCFLAGS; for compiling to shared objects. @@ -103,7 +103,7 @@ See also &cv-link-SHCCFLAGS;. General options that are passed to the C compiler (C only; not C++). -See also &cv-link-SHCFLAGS;. +See also &cv-link-SHCFLAGS; for compiling to shared objects. @@ -161,7 +161,7 @@ The default list is: The C compiler used for generating shared-library objects. -See also &cv-link-CC;. +See also &cv-link-CC; for compiling to static objects. @@ -175,7 +175,7 @@ Any options specified in the &cv-link-SHCFLAGS;, &cv-link-SHCCFLAGS; and &cv-link-CPPFLAGS; construction variables are included on this command line. -See also &cv-link-CCCOM;. +See also &cv-link-CCCOM; for compiling to static objects. @@ -186,7 +186,7 @@ See also &cv-link-CCCOM;. If set, the string displayed when a C source file is compiled to a shared object file. If not set, then &cv-link-SHCCCOM; (the command line) is displayed. -See also &cv-link-CCCOMSTR;. +See also &cv-link-CCCOMSTR; for compiling to static objects. @@ -200,7 +200,7 @@ env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET") Options that are passed to the C and C++ compilers to generate shared-library objects. -See also &cv-link-CCFLAGS;. +See also &cv-link-CCFLAGS; for compiling to static objects. @@ -210,7 +210,7 @@ See also &cv-link-CCFLAGS;. Options that are passed to the C compiler (only; not C++) to generate shared-library objects. -See also &cv-link-CFLAGS;. +See also &cv-link-CFLAGS; for compiling to static objects. diff --git a/src/engine/SCons/Tool/f03.xml b/src/engine/SCons/Tool/f03.xml index c020b81..61c02ef 100644 --- a/src/engine/SCons/Tool/f03.xml +++ b/src/engine/SCons/Tool/f03.xml @@ -77,9 +77,9 @@ for all Fortran versions. -The string displayed when a Fortran 03 source file +If set, the string displayed when a Fortran 03 source file is compiled to an object file. -If this is not set, then &cv-link-F03COM; or &cv-link-FORTRANCOM; +If not set, then &cv-link-F03COM; or &cv-link-FORTRANCOM; (the command line) is displayed. @@ -217,10 +217,10 @@ for all Fortran versions. -The string displayed when a Fortran 03 source file +If set, the string displayed when a Fortran 03 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-F03PPCOM; or &cv-link-FORTRANPPCOM; +If not set, then &cv-link-F03PPCOM; or &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -256,9 +256,9 @@ for all Fortran versions. -The string displayed when a Fortran 03 source file +If set, the string displayed when a Fortran 03 source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHF03COM; or &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHF03COM; or &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -299,10 +299,10 @@ for all Fortran versions. -The string displayed when a Fortran 03 source file +If set, the string displayed when a Fortran 03 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHF03PPCOM; or &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHF03PPCOM; or &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/f08.xml b/src/engine/SCons/Tool/f08.xml index 802e4cc..a56d60b 100644 --- a/src/engine/SCons/Tool/f08.xml +++ b/src/engine/SCons/Tool/f08.xml @@ -77,9 +77,9 @@ for all Fortran versions. -The string displayed when a Fortran 08 source file +If set, the string displayed when a Fortran 08 source file is compiled to an object file. -If this is not set, then &cv-link-F08COM; or &cv-link-FORTRANCOM; +If not set, then &cv-link-F08COM; or &cv-link-FORTRANCOM; (the command line) is displayed. @@ -217,10 +217,10 @@ for all Fortran versions. -The string displayed when a Fortran 08 source file +If set, the string displayed when a Fortran 08 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-F08PPCOM; or &cv-link-FORTRANPPCOM; +If not set, then &cv-link-F08PPCOM; or &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -256,9 +256,9 @@ for all Fortran versions. -The string displayed when a Fortran 08 source file +If set, the string displayed when a Fortran 08 source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHF08COM; or &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHF08COM; or &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -299,10 +299,10 @@ for all Fortran versions. -The string displayed when a Fortran 08 source file +If set, the string displayed when a Fortran 08 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHF08PPCOM; or &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHF08PPCOM; or &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/f77.xml b/src/engine/SCons/Tool/f77.xml index abfc4a2..70ec721 100644 --- a/src/engine/SCons/Tool/f77.xml +++ b/src/engine/SCons/Tool/f77.xml @@ -108,9 +108,9 @@ F77 dialect will be used. By default, this is empty -The string displayed when a Fortran 77 source file +If set, the string displayed when a Fortran 77 source file is compiled to an object file. -If this is not set, then &cv-link-F77COM; or &cv-link-FORTRANCOM; +If not set, then &cv-link-F77COM; or &cv-link-FORTRANCOM; (the command line) is displayed. @@ -230,10 +230,10 @@ for all Fortran versions. -The string displayed when a Fortran 77 source file +If set, the string displayed when a Fortran 77 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-F77PPCOM; or &cv-link-FORTRANPPCOM; +If not set, then &cv-link-F77PPCOM; or &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -269,9 +269,9 @@ for all Fortran versions. -The string displayed when a Fortran 77 source file +If set, the string displayed when a Fortran 77 source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHF77COM; or &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHF77COM; or &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -312,10 +312,10 @@ for all Fortran versions. -The string displayed when a Fortran 77 source file +If set, the string displayed when a Fortran 77 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHF77PPCOM; or &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHF77PPCOM; or &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/f90.xml b/src/engine/SCons/Tool/f90.xml index 94249a3..64dc6e1 100644 --- a/src/engine/SCons/Tool/f90.xml +++ b/src/engine/SCons/Tool/f90.xml @@ -77,9 +77,9 @@ for all Fortran versions. -The string displayed when a Fortran 90 source file +If set, the string displayed when a Fortran 90 source file is compiled to an object file. -If this is not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM; +If not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM; (the command line) is displayed. @@ -217,9 +217,9 @@ for all Fortran versions. -The string displayed when a Fortran 90 source file +If set, the string displayed when a Fortran 90 source file is compiled after first running the file through the C preprocessor. -If this is not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM; +If not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -255,9 +255,9 @@ for all Fortran versions. -The string displayed when a Fortran 90 source file +If set, the string displayed when a Fortran 90 source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -298,10 +298,10 @@ for all Fortran versions. -The string displayed when a Fortran 90 source file +If set, the string displayed when a Fortran 90 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/f95.xml b/src/engine/SCons/Tool/f95.xml index 4a4db46..4bda653 100644 --- a/src/engine/SCons/Tool/f95.xml +++ b/src/engine/SCons/Tool/f95.xml @@ -77,9 +77,9 @@ for all Fortran versions. -The string displayed when a Fortran 95 source file +If set, the string displayed when a Fortran 95 source file is compiled to an object file. -If this is not set, then &cv-link-F95COM; or &cv-link-FORTRANCOM; +If not set, then &cv-link-F95COM; or &cv-link-FORTRANCOM; (the command line) is displayed. @@ -217,10 +217,10 @@ for all Fortran versions. -The string displayed when a Fortran 95 source file +If set, the string displayed when a Fortran 95 source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-F95PPCOM; or &cv-link-FORTRANPPCOM; +If not set, then &cv-link-F95PPCOM; or &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -256,9 +256,9 @@ for all Fortran versions. -The string displayed when a Fortran 95 source file +If set, the string displayed when a Fortran 95 source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHF95COM; or &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHF95COM; or &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -299,10 +299,10 @@ for all Fortran versions. -The string displayed when a Fortran 95 source file +If set, the string displayed when a Fortran 95 source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHF95PPCOM; or &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHF95PPCOM; or &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/fortran.xml b/src/engine/SCons/Tool/fortran.xml index 53bcfb1..7b3c51f 100644 --- a/src/engine/SCons/Tool/fortran.xml +++ b/src/engine/SCons/Tool/fortran.xml @@ -73,9 +73,9 @@ are included on this command line. -The string displayed when a Fortran source file +If set, the string displayed when a Fortran source file is compiled to an object file. -If this is not set, then &cv-link-FORTRANCOM; +If not set, then &cv-link-FORTRANCOM; (the command line) is displayed. @@ -285,10 +285,10 @@ construction variables are included on this command line. -The string displayed when a Fortran source file +If set, the string displayed when a Fortran source file is compiled to an object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-FORTRANPPCOM; +If not set, then &cv-link-FORTRANPPCOM; (the command line) is displayed. @@ -330,9 +330,9 @@ to a shared-library object file. -The string displayed when a Fortran source file +If set, the string displayed when a Fortran source file is compiled to a shared-library object file. -If this is not set, then &cv-link-SHFORTRANCOM; +If not set, then &cv-link-SHFORTRANCOM; (the command line) is displayed. @@ -364,10 +364,10 @@ are included on this command line. -The string displayed when a Fortran source file +If set, the string displayed when a Fortran source file is compiled to a shared-library object file after first running the file through the C preprocessor. -If this is not set, then &cv-link-SHFORTRANPPCOM; +If not set, then &cv-link-SHFORTRANPPCOM; (the command line) is displayed. diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index 7a84e1a..281e147 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -32,9 +32,6 @@ based on the types of source files. -SHLINK -SHLINKFLAGS -SHLINKCOM LINK LINKFLAGS LINKCOM @@ -42,6 +39,9 @@ based on the types of source files. LIBDIRSUFFIX LIBLINKPREFIX LIBLINKSUFFIX +SHLINK +SHLINKFLAGS +SHLINKCOM SHLIBSUFFIX __SHLIBVERSIONFLAGS LDMODULE @@ -243,6 +243,7 @@ set. The linker. +See also &cv-link-SHLINK; for linking shared objects. @@ -251,6 +252,7 @@ The linker. The command line used to link object files into an executable. +See also &cv-link-SHLINKCOM; for linking shared objects. @@ -261,7 +263,7 @@ The command line used to link object files into an executable. If set, the string displayed when object files are linked into an executable. If not set, then &cv-link-LINKCOM; (the command line) is displayed. -See also &cv-link-SHLINKCOMSTR;. +See also &cv-link-SHLINKCOMSTR;. for linking shared objects. @@ -291,6 +293,7 @@ and &cv-link-_LIBDIRFLAGS; above, for the variable that expands to library search path options. +See also &cv-link-SHLINKFLAGS;. for linking shared objects. @@ -318,6 +321,7 @@ set. The linker for programs that use shared libraries. +See also &cv-link-LINK; for linking static objects. @@ -326,6 +330,7 @@ The linker for programs that use shared libraries. The command line used to link programs using shared libraries. +See also &cv-link-LINKCOM; for linking static objects. @@ -335,7 +340,7 @@ The command line used to link programs using shared libraries. The string displayed when programs using shared libraries are linked. If this is not set, then &cv-link-SHLINKCOM; (the command line) is displayed. -See also &cv-link-LINKCOMSTR;. +See also &cv-link-LINKCOMSTR; for linking static objects. @@ -365,6 +370,7 @@ and &cv-link-_LIBDIRFLAGS; above, for the variable that expands to library search path options. +See also &cv-link-LINKFLAGS; for linking static objects. -- cgit v0.12 From e5c71f8a819fba93047d17966bfb85835637ea6a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 15 Jan 2020 21:06:57 -0500 Subject: Change ValueWithMemo() to take into account any name passed when memoizing Value()'s --- src/CHANGES.txt | 3 +-- src/engine/SCons/Node/Python.py | 9 ++++++--- src/engine/SCons/Node/PythonTests.py | 16 ++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 97934ff..fd9eba5 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -19,10 +19,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Adam Gross: - Added support for taking instances of the Value class as implicit dependencies. - - From Adam Gross: - Added new module SCons.Scanner.Python to allow scanning .py files. + From Mathew Robinson: - Improve performance of Subst by preventing unnecessary frame allocations by no longer defining the *Subber classes inside of their diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index d26c185..68c6ee8 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -185,17 +185,20 @@ class Value(SCons.Node.Node): def ValueWithMemo(value, built_value=None, name=None): + """ + Memoized Value() node factory. + """ global _memo_lookup_map # No current support for memoizing a value that needs to be built. if built_value: - return Value(value, built_value) + return Value(value, built_value, name=name) try: - memo_lookup_key = hash(value) + memo_lookup_key = hash((value, name)) except TypeError: # Non-primitive types will hit this codepath. - return Value(value) + return Value(value, name=name) try: return _memo_lookup_map[memo_lookup_key] diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 6db07ab..51a49c0 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -104,6 +104,9 @@ class ValueTestCase(unittest.TestCase): assert csig == 'None', csig + + + class ValueNodeInfoTestCase(unittest.TestCase): def test___init__(self): """Test ValueNodeInfo initialization""" @@ -162,6 +165,19 @@ class ValueMemoTestCase(unittest.TestCase): v4 = SCons.Node.Python.ValueWithMemo(a) assert v3 is not v4 + def test_value_set_name(self): + """ Confirm setting name and caching takes the name into account """ + + v1 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name') + v2 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name2') + v3 = SCons.Node.Python.ValueWithMemo('Jibberish') + + self.assertEqual(v1.name,'name', msg=v1.name) + self.assertEqual(v2.name,'name2', msg=v2.name) + self.assertEqual(v3.name,'Jibberish', msg=v3.name) + self.assertTrue(v1 is not v2, msg="v1 and v2 should be different as they have different names but same values") + + if __name__ == "__main__": unittest.main() -- cgit v0.12 From f0ed0de157ab13e6a8767b1aae66ce3deaa6066e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 15 Jan 2020 21:46:54 -0500 Subject: updated CHANGES.txt --- src/CHANGES.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index fd9eba5..d2b5110 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,12 +15,17 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Added C:\msys64\mingw64\bin to default mingw and clang windows PATH's. This is a reasonable default and also aligns with changes in Appveyor's VS2019 image. - Drop support for Python 2.7. SCons will be Python 3.5+ going forward. + - Change SCons.Node.ValueWithMemo to consider any name passed when memoizing Value() nodes + + From Jeremy Elson: + - Updated design doc to use the correct syntax for Depends() From Adam Gross: - Added support for taking instances of the Value class as implicit dependencies. - Added new module SCons.Scanner.Python to allow scanning .py files. - + - Added support for explicitly passing a name when creating Value() nodes. This may be useful + when the value can't be converted to a string or if having a name is otherwise desirable. From Mathew Robinson: - Improve performance of Subst by preventing unnecessary frame @@ -38,8 +43,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Convert remaining uses of insecure/deprecated mktemp method. - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. - From Jeremy Elson: - - Updated design doc to use the correct syntax for Depends() + RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000 -- cgit v0.12 From 407dda1715776a962119cbf8442286af7cae79b9 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 12 Aug 2019 09:33:24 -0600 Subject: Stop converting to list where not needed Python 3 returns a special object, which is iterable, rather than a list when you ask for dictionary keys(), values(), items(). if you then proceed to iterate over it it's being used as expected and doesn't have to be forced to a list first. This occurs a number of places in this form: for k in list(something.keys()): Also there are several places where the code loops over the result of dict.keys() and then uses the key to index into the dictionary, this can be replaced by: for k, v in something.items(): Signed-off-by: Mats Wichmann --- src/CHANGES.txt | 1 + src/engine/SCons/Builder.py | 2 +- src/engine/SCons/Environment.py | 4 ++-- src/engine/SCons/Node/FS.py | 4 ++-- src/engine/SCons/SConf.py | 6 +++--- src/engine/SCons/Script/Interactive.py | 2 +- src/engine/SCons/Script/Main.py | 4 ++-- src/engine/SCons/Tool/MSCommon/common.py | 4 ++-- src/engine/SCons/Tool/__init__.py | 2 +- src/engine/SCons/Tool/intelc.py | 8 ++++---- src/engine/SCons/Tool/msvs.py | 21 +++++++-------------- src/engine/SCons/Tool/msvsTests.py | 4 ++-- src/engine/SCons/Tool/packaging/ipk.py | 2 +- src/engine/SCons/Tool/packaging/rpm.py | 2 +- src/engine/SCons/cpp.py | 4 ++-- src/test_interrupts.py | 2 +- 16 files changed, 33 insertions(+), 39 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 694aca0..2f85fe6 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -35,6 +35,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - a bunch of linter/checker syntax fixups - Convert remaining uses of insecure/deprecated mktemp method. - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. + - Reduce needless list conversions. From Jeremy Elson: - Updated design doc to use the correct syntax for Depends() diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index e3fb396..caa0568 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -230,7 +230,7 @@ class OverrideWarner(collections.UserDict): def warn(self): if self.already_warned: return - for k in list(self.keys()): + for k in self.keys(): if k in misleading_keywords: alt = misleading_keywords[k] msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 3e23196..18badc0 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1854,7 +1854,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in list(uniq.keys()): + for executor in uniq.keys(): executor.add_pre_action(action) return nodes @@ -1864,7 +1864,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in list(uniq.keys()): + for executor in uniq.keys(): executor.add_post_action(action) return nodes diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index e1d6f68..6f16256 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1612,7 +1612,7 @@ class Dir(Base): This clears any cached information that is invalidated by changing the repository.""" - for node in list(self.entries.values()): + for node in self.entries.values(): if node != self.dir: if node != self and isinstance(node, Dir): node.__clearRepositoryCache(duplicate) @@ -1623,7 +1623,7 @@ class Dir(Base): except AttributeError: pass if duplicate is not None: - node.duplicate=duplicate + node.duplicate = duplicate def __resetDuplicate(self, node): if node != self: diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index e706dae..988362e 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -132,8 +132,8 @@ def CreateConfigHBuilder(env): _stringConfigH) sconfigHBld = SCons.Builder.Builder(action=action) env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} ) - for k in list(_ac_config_hs.keys()): - env.SConfigHBuilder(k, env.Value(_ac_config_hs[k])) + for k, v in _ac_config_hs.items(): + env.SConfigHBuilder(k, env.Value(v)) class SConfWarning(SCons.Warnings.Warning): @@ -703,7 +703,7 @@ class SConfBase(object): """Adds all the tests given in the tests dictionary to this SConf instance """ - for name in list(tests.keys()): + for name in tests.keys(): self.AddTest(name, tests[name]) def _createDir( self, node ): diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index cc4f23c..59299f1 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -247,7 +247,7 @@ version Prints SCons version information. while n: n = walker.get_next() - for node in list(seen_nodes.keys()): + for node in seen_nodes.keys(): # Call node.clear() to clear most of the state node.clear() # node.clear() doesn't reset node.state, so call diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index f9c8384..a0d7f4c 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -743,9 +743,9 @@ def _load_site_scons_dir(topdir, site_dir_name=None): modname = os.path.basename(pathname)[:-len(sfx)] site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} re_special = re.compile("__[^_]+__") - for k in list(m.__dict__.keys()): + for k, v in m.__dict__.items(): if not re_special.match(k): - site_m[k] = m.__dict__[k] + site_m[k] = v # This is the magic. exec(compile(fp.read(), fp.name, 'exec'), site_m) diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index 386f445..4ce605b 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -152,8 +152,8 @@ def normalize_env(env, keys, force=False): Note: the environment is copied.""" normenv = {} if env: - for k in list(env.keys()): - normenv[k] = copy.deepcopy(env[k]) + for k, v in env.items(): + normenv[k] = copy.deepcopy(v) for k in keys: if k in os.environ and (force or k not in normenv): diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 99a958c..76a0913 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -1130,7 +1130,7 @@ class ToolInitializer(object): so we no longer copy and re-bind them when the construction environment gets cloned. """ - for method in list(self.methods.values()): + for method in self.methods.values(): env.RemoveMethod(method) def apply_tools(self, env): diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index 5a101b4..778cba1 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -495,15 +495,15 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in list(paths.keys()): - env.PrependENVPath(p, os.path.join(topdir, paths[p])) + for p, v in paths.items(): + env.PrependENVPath(p, os.path.join(topdir, v)) if is_mac: paths={'INCLUDE' : 'include', 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in list(paths.keys()): - env.PrependENVPath(p, os.path.join(topdir, paths[p])) + for p, v in paths.items(): + env.PrependENVPath(p, os.path.join(topdir, v)) if is_windows: # env key reg valname default subdir of top paths=(('INCLUDE', 'IncludeDir', 'Include'), diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 929e558..d923d3d 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -220,7 +220,7 @@ class _UserGenerator(object): for var, src in dbg_settings.items(): # Update only expected keys trg = {} - for key in [k for k in list(self.usrdebg.keys()) if k in src]: + for key in [k for k in self.usrdebg.keys() if k in src]: trg[key] = str(src[key]) self.configs[var].debug = trg @@ -578,11 +578,8 @@ class _DSPGenerator(object): for i in range(len(variants)): AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i], cppdefines[i], cpppaths[i]) - self.platforms = [] - for key in list(self.configs.keys()): - platform = self.configs[key].platform - if platform not in self.platforms: - self.platforms.append(platform) + self.platforms = {p.platform for p in self.configs.values()} + def Build(self): pass @@ -702,7 +699,7 @@ class _GenerateV6DSP(_DSPGenerator): 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', 'Other Files': ''} - for kind in sorted(list(categories.keys()), key=lambda a: a.lower()): + for kind in sorted(categories.keys(), key=lambda a: a.lower()): if not self.sources[kind]: continue # skip empty groups @@ -1003,7 +1000,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.file.write('\t\n') - cats = sorted([k for k in list(categories.keys()) if self.sources[k]], + cats = sorted([k for k in categories.keys() if self.sources[k]], key=lambda a: a.lower()) for kind in cats: if len(cats) > 1: @@ -1348,7 +1345,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', 'Other Files': ''} - cats = sorted([k for k in list(categories.keys()) if self.sources[k]], + cats = sorted([k for k in categories.keys() if self.sources[k]], key = lambda a: a.lower()) # print vcxproj.filters file first @@ -1505,11 +1502,7 @@ class _GenerateV7DSW(_DSWGenerator): for variant in env['variant']: AddConfig(self, variant) - self.platforms = [] - for key in list(self.configs.keys()): - platform = self.configs[key].platform - if platform not in self.platforms: - self.platforms.append(platform) + self.platforms = {p.platform for p in self.configs.values()} def GenerateProjectFilesInfo(self): for dspfile in self.dspfiles: diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index cc4f717..c2b5f0e 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -771,8 +771,8 @@ class msvsTestCase(unittest.TestCase): # Check expected result self.assertListEqual(list(genDSP.configs.keys()), list(expected_configs.keys())) - for key in list(genDSP.configs.keys()): - self.assertDictEqual(genDSP.configs[key].__dict__, expected_configs[key]) + for key, v in genDSP.configs.items(): + self.assertDictEqual(v.__dict__, expected_configs[key]) genDSP.Build() diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index fe3f49b..ac8b992 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -173,7 +173,7 @@ Description: $X_IPK_DESCRIPTION # # close all opened files - for f in list(opened_files.values()): + for f in opened_files.values(): f.close() # call a user specified function diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index ebaa701..db8ae24 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -284,7 +284,7 @@ def build_specfile_filesection(spec, files): for file in files: # build the tagset tags = {} - for k in list(supported_tags.keys()): + for k in supported_tags.keys(): try: v = file.GetTag(k) if v: diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index 5b35390..0c20c94 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -89,7 +89,7 @@ del op_list override = { 'if' : 'if(?!n?def)', } -l = [override.get(x, x) for x in list(Table.keys())] +l = [override.get(x, x) for x in Table.keys()] # Turn the list of expressions into one big honkin' regular expression @@ -268,7 +268,7 @@ class PreProcessor(object): d = { 'scons_current_file' : self.scons_current_file } - for op in list(Table.keys()): + for op in Table.keys(): d[op] = getattr(self, 'do_' + op) self.default_table = d diff --git a/src/test_interrupts.py b/src/test_interrupts.py index de18a54..8e1b379 100644 --- a/src/test_interrupts.py +++ b/src/test_interrupts.py @@ -105,7 +105,7 @@ for f in files: indent_list.append( (line_num, match.group('try_or_except') ) ) try_except_lines[match.group('indent')] = indent_list uncaught_this_file = [] - for indent in list(try_except_lines.keys()): + for indent in try_except_lines.keys(): exc_keyboardint_seen = 0 exc_all_seen = 0 for (l,statement) in try_except_lines[indent] + [(-1,indent + 'try')]: -- cgit v0.12 From ec2af8b9bb82bcdea24bbe966675db900ce71223 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 16 Jan 2020 13:24:43 -0700 Subject: [PR #3528] preserve order on two changes Per review comment - with extra caution, use an order-preserving technique rather than a non-preserving one, in case it matters. Signed-off-by: Mats Wichmann --- src/engine/SCons/Tool/msvs.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index d923d3d..0ef4a97 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -578,7 +578,9 @@ class _DSPGenerator(object): for i in range(len(variants)): AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i], cppdefines[i], cpppaths[i]) - self.platforms = {p.platform for p in self.configs.values()} + seen = set() + self.platforms = [p.platform for p in self.configs.values() + if not (p.platform in seen or seen.add(p.platform))] def Build(self): @@ -1502,7 +1504,9 @@ class _GenerateV7DSW(_DSWGenerator): for variant in env['variant']: AddConfig(self, variant) - self.platforms = {p.platform for p in self.configs.values()} + seen = set() + self.platforms = [p.platform for p in self.configs.values() + if not (p.platform in seen or seen.add(p.platform))] def GenerateProjectFilesInfo(self): for dspfile in self.dspfiles: -- cgit v0.12 From c35a2cdf0306e0cbc6a5215f9d77ac49debb1ece Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 23 Jan 2020 12:19:46 -0700 Subject: Fix some pyflakes warnings These are of the kind that would not be fixed by a code reformat (Black). These should all be trivial. They're nearly all in unit tests (all but two), since I haven't cleaned up as many there in the past. Signed-off-by: Mats Wichmann --- src/engine/SCons/BuilderTests.py | 14 +++++++------- src/engine/SCons/EnvironmentTests.py | 8 ++++---- src/engine/SCons/Node/AliasTests.py | 2 +- src/engine/SCons/Node/FSTests.py | 20 ++++++++++---------- src/engine/SCons/Node/NodeTests.py | 2 +- src/engine/SCons/PathListTests.py | 2 +- src/engine/SCons/Platform/__init__.py | 2 +- src/engine/SCons/SConsignTests.py | 2 +- src/engine/SCons/Scanner/RCTests.py | 2 +- src/engine/SCons/TaskmasterTests.py | 10 +++++----- src/engine/SCons/Tool/msvs.py | 2 +- src/engine/SCons/Tool/msvsTests.py | 10 +++++----- src/engine/SCons/Variables/ListVariableTests.py | 2 +- src/engine/SCons/Variables/PackageVariableTests.py | 4 ++-- 14 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index f28e201..b4286fd 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -173,7 +173,7 @@ class MyNode_without_target_from_source(object): def builder_set(self, builder): self.builder = builder def has_builder(self): - return not self.builder is None + return self.builder is not None def set_explicit(self, is_explicit): self.is_explicit = is_explicit def has_explicit_builder(self): @@ -205,7 +205,7 @@ class BuilderTestCase(unittest.TestCase): """Test simple Builder creation """ builder = SCons.Builder.Builder(action="foo") - assert not builder is None, builder + assert builder is not None, builder builder = SCons.Builder.Builder(action="foo", OVERRIDE='x') x = builder.overrides['OVERRIDE'] assert x == 'x', x @@ -429,7 +429,7 @@ class BuilderTestCase(unittest.TestCase): return Foo(target) builder = SCons.Builder.Builder(target_factory = FooFactory) assert builder.target_factory is FooFactory - assert not builder.source_factory is FooFactory + assert builder.source_factory is not FooFactory def test_source_factory(self): """Test a Builder that creates source nodes of a specified class @@ -440,7 +440,7 @@ class BuilderTestCase(unittest.TestCase): global Foo return Foo(source) builder = SCons.Builder.Builder(source_factory = FooFactory) - assert not builder.target_factory is FooFactory + assert builder.target_factory is not FooFactory assert builder.source_factory is FooFactory def test_splitext(self): @@ -737,7 +737,7 @@ class BuilderTestCase(unittest.TestCase): with open(str(t), 'w') as f: f.write("function2\n") for t in tlist: - if not t in list(map(str, target)): + if t not in list(map(str, target)): with open(t, 'w') as f: f.write("function2\n") return 1 @@ -768,7 +768,7 @@ class BuilderTestCase(unittest.TestCase): with open(str(t), 'w') as f: f.write("function3\n") for t in tlist: - if not t in list(map(str, target)): + if t not in list(map(str, target)): with open(t, 'w') as f: f.write("function3\n") return 1 @@ -821,7 +821,7 @@ class BuilderTestCase(unittest.TestCase): assert s == ['aaa.bar'], s builder3 = SCons.Builder.Builder(action='bld3') - assert not builder3.src_builder is builder1.src_builder + assert builder3.src_builder is not builder1.src_builder builder4 = SCons.Builder.Builder(action='bld4', src_suffix='.i', diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0cb8418..01baba3 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -236,7 +236,7 @@ class SubstitutionTestCase(unittest.TestCase): """ env = SubstitutionEnvironment(XXX = 'x') assert 'XXX' in env - assert not 'YYY' in env + assert 'YYY' not in env def test_items(self): """Test the SubstitutionEnvironment items() method @@ -1759,7 +1759,7 @@ def exists(env): env2.Dictionary('ZZZ')[5] = 6 assert env1.Dictionary('XXX') is env2.Dictionary('XXX') assert 4 in env2.Dictionary('YYY') - assert not 4 in env1.Dictionary('YYY') + assert 4 not in env1.Dictionary('YYY') assert 5 in env2.Dictionary('ZZZ') assert 5 not in env1.Dictionary('ZZZ') @@ -3551,8 +3551,8 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'YYY' in env assert 'YYY' in env2 assert 'YYY' in env3 - assert not 'ZZZ' in env - assert not 'ZZZ' in env2 + assert 'ZZZ' not in env + assert 'ZZZ' not in env2 assert 'ZZZ' in env3 def test_items(self): diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py index 5d9c799..27b75b3 100644 --- a/src/engine/SCons/Node/AliasTests.py +++ b/src/engine/SCons/Node/AliasTests.py @@ -93,7 +93,7 @@ class AliasTestCase(unittest.TestCase): a2 = SCons.Node.Alias.Alias('a') assert a2.name == 'a', a2.name - assert not a1 is a2 + assert a1 is not a2 assert a1.name == a2.name class AliasNodeInfoTestCase(unittest.TestCase): diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 9c19481..bbfdd1b 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -3066,12 +3066,12 @@ class RepositoryTestCase(_tempdirTestCase): assert r is d1, r r = d2.rentry() - assert not r is d2, r + assert r is not d2, r r = str(r) assert r == os.path.join(self.rep1, 'd2'), r r = d3.rentry() - assert not r is d3, r + assert r is not d3, r r = str(r) assert r == os.path.join(self.rep2, 'd3'), r @@ -3079,12 +3079,12 @@ class RepositoryTestCase(_tempdirTestCase): assert r is e1, r r = e2.rentry() - assert not r is e2, r + assert r is not e2, r r = str(r) assert r == os.path.join(self.rep1, 'e2'), r r = e3.rentry() - assert not r is e3, r + assert r is not e3, r r = str(r) assert r == os.path.join(self.rep2, 'e3'), r @@ -3092,12 +3092,12 @@ class RepositoryTestCase(_tempdirTestCase): assert r is f1, r r = f2.rentry() - assert not r is f2, r + assert r is not f2, r r = str(r) assert r == os.path.join(self.rep1, 'f2'), r r = f3.rentry() - assert not r is f3, r + assert r is not f3, r r = str(r) assert r == os.path.join(self.rep2, 'f3'), r @@ -3127,12 +3127,12 @@ class RepositoryTestCase(_tempdirTestCase): assert r is d1, r r = d2.rdir() - assert not r is d2, r + assert r is not d2, r r = str(r) assert r == os.path.join(self.rep1, 'd2'), r r = d3.rdir() - assert not r is d3, r + assert r is not d3, r r = str(r) assert r == os.path.join(self.rep3, 'd3'), r @@ -3183,12 +3183,12 @@ class RepositoryTestCase(_tempdirTestCase): assert r is f1, r r = f2.rfile() - assert not r is f2, r + assert r is not f2, r r = str(r) assert r == os.path.join(self.rep1, 'f2'), r r = f3.rfile() - assert not r is f3, r + assert r is not f3, r r = f3.rstr() assert r == os.path.join(self.rep3, 'f3'), r diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index d8179ff..8d9d3a9 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -1104,7 +1104,7 @@ class NodeTestCase(unittest.TestCase): for kid in [n1, n3, n4, n6, n7, n9, n10, n12]: assert kid in kids, kid for kid in [n2, n5, n8, n11]: - assert not kid in kids, kid + assert kid not in kids, kid def test_all_children(self): """Test fetching all the "children" of a Node. diff --git a/src/engine/SCons/PathListTests.py b/src/engine/SCons/PathListTests.py index 104be73..09b1132 100644 --- a/src/engine/SCons/PathListTests.py +++ b/src/engine/SCons/PathListTests.py @@ -185,7 +185,7 @@ class PathListTestCase(unittest.TestCase): x3 = SCons.PathList.PathList('x') - assert not x1 is x3, (x1, x3) + assert x1 is not x3, (x1, x3) if __name__ == "__main__": diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 058241d..5e9a358 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -195,7 +195,7 @@ class TempFileMunge(object): # Default to the .lnk suffix for the benefit of the Phar Lap # linkloc linker, which likes to append an .lnk suffix if # none is given. - if env.has_key('TEMPFILESUFFIX'): + if 'TEMPFILESUFFIX' in env: suffix = env.subst('$TEMPFILESUFFIX') else: suffix = '.lnk' diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py index d40a7b6..782072d 100644 --- a/src/engine/SCons/SConsignTests.py +++ b/src/engine/SCons/SConsignTests.py @@ -337,7 +337,7 @@ class SConsignFileTestCase(SConsignTestCase): SCons.SConsign.ForDirectory(DummyNode(test.workpath('dir'))) - assert not SCons.SConsign.DataBase is None, SCons.SConsign.DataBase + assert SCons.SConsign.DataBase is not None, SCons.SConsign.DataBase assert fake_dbm.name == file, fake_dbm.name assert fake_dbm.mode == "c", fake_dbm.mode diff --git a/src/engine/SCons/Scanner/RCTests.py b/src/engine/SCons/Scanner/RCTests.py index 551e613..347149c 100644 --- a/src/engine/SCons/Scanner/RCTests.py +++ b/src/engine/SCons/Scanner/RCTests.py @@ -82,7 +82,7 @@ class DummyEnvironment(collections.UserDict): def Dictionary(self, *args): return self.data - def subst(self, arg, target=None, source=None, conv=None): + def subst(self, strSubst, target=None, source=None, conv=None): if strSubst[0] == '$': return self.data[strSubst[1:]] return strSubst diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index c0c77b0..f23afd1 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -146,7 +146,7 @@ class Node(object): pass def has_builder(self): - return not self.builder is None + return self.builder is not None def is_derived(self): return self.has_builder or self.side_effect @@ -935,7 +935,7 @@ class TaskmasterTestCase(unittest.TestCase): except SCons.Errors.UserError: pass else: - raise TestFailed("did not catch expected UserError") + raise AssertionError("did not catch expected UserError") def raise_BuildError(): raise SCons.Errors.BuildError @@ -948,7 +948,7 @@ class TaskmasterTestCase(unittest.TestCase): except SCons.Errors.BuildError: pass else: - raise TestFailed("did not catch expected BuildError") + raise AssertionError("did not catch expected BuildError") # On a generic (non-BuildError) exception from a Builder, # the target should throw a BuildError exception with the @@ -968,7 +968,7 @@ class TaskmasterTestCase(unittest.TestCase): exc_traceback = sys.exc_info()[2] assert isinstance(e.exc_info[2], type(exc_traceback)), e.exc_info[2] else: - raise TestFailed("did not catch expected BuildError") + raise AssertionError("did not catch expected BuildError") built_text = None cache_text = [] @@ -1049,7 +1049,7 @@ class TaskmasterTestCase(unittest.TestCase): assert cache_text == ["n1 retrieved"], cache_text # If no binfo exists anymore, something has gone wrong... has_binfo = hasattr(n1, 'binfo') - assert has_binfo == True, has_binfo + assert has_binfo, has_binfo def test_exception(self): """Test generic Taskmaster exception handling diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 0ef4a97..9952ccc 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -544,7 +544,7 @@ class _DSPGenerator(object): if t[1] in self.env: if SCons.Util.is_List(self.env[t[1]]): for i in self.env[t[1]]: - if not i in self.sources[t[0]]: + if i not in self.sources[t[0]]: self.sources[t[0]].append(i) else: if not self.env[t[1]] in self.sources[t[0]]: diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index c2b5f0e..38a100f 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -405,20 +405,20 @@ class DummyEnv(object): return self.dict return self.dict[key] - def __setitem__(self,key,value): + def __setitem__(self, key, value): self.dict[key] = value - def __getitem__(self,key): + def __getitem__(self, key): return self.dict[key] - def __contains__(self,key): + def __contains__(self, key): return key in self.dict - def has_key(self,name): + def has_key(self, name): return name in self.dict def get(self, name, value=None): - if self.has_key(name): + if name in self.dict: return self.dict[name] else: return value diff --git a/src/engine/SCons/Variables/ListVariableTests.py b/src/engine/SCons/Variables/ListVariableTests.py index ef4832c..8f79e07 100644 --- a/src/engine/SCons/Variables/ListVariableTests.py +++ b/src/engine/SCons/Variables/ListVariableTests.py @@ -42,7 +42,7 @@ class ListVariableTestCase(unittest.TestCase): assert o.help == 'test option help\n (all|none|comma-separated list of names)\n allowed names: one two three', repr(o.help) assert o.default == 'all', o.default assert o.validator is None, o.validator - assert not o.converter is None, o.converter + assert o.converter is not None, o.converter opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test2', 'test2 help', diff --git a/src/engine/SCons/Variables/PackageVariableTests.py b/src/engine/SCons/Variables/PackageVariableTests.py index cda3a4a..a7e6b0d 100644 --- a/src/engine/SCons/Variables/PackageVariableTests.py +++ b/src/engine/SCons/Variables/PackageVariableTests.py @@ -80,10 +80,10 @@ class PackageVariableTestCase(unittest.TestCase): # False when we give it str(False). This assures consistent operation # through a cycle of Variables.Save() -> Variables(). x = o.converter(str(True)) - assert x == True, "converter returned a string when given str(True)" + assert x, "converter returned a string when given str(True)" x = o.converter(str(False)) - assert x == False, "converter returned a string when given str(False)" + assert not x, "converter returned a string when given str(False)" def test_validator(self): """Test the PackageVariable validator""" -- cgit v0.12 From 4d8892aff67876ac76031d72d8441da8ac46f342 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 23 Jan 2020 13:01:00 -0700 Subject: [PR #3531] fix TestFailed usage another way Per review, the replacement for (deprecated/removed) raising TestFailed is to call self.fail - updated to this. Signed-off-by: Mats Wichmann --- src/engine/SCons/TaskmasterTests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index f23afd1..1a47230 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -935,7 +935,7 @@ class TaskmasterTestCase(unittest.TestCase): except SCons.Errors.UserError: pass else: - raise AssertionError("did not catch expected UserError") + self.fail("did not catch expected UserError") def raise_BuildError(): raise SCons.Errors.BuildError @@ -948,7 +948,7 @@ class TaskmasterTestCase(unittest.TestCase): except SCons.Errors.BuildError: pass else: - raise AssertionError("did not catch expected BuildError") + self.fail("did not catch expected BuildError") # On a generic (non-BuildError) exception from a Builder, # the target should throw a BuildError exception with the @@ -968,7 +968,7 @@ class TaskmasterTestCase(unittest.TestCase): exc_traceback = sys.exc_info()[2] assert isinstance(e.exc_info[2], type(exc_traceback)), e.exc_info[2] else: - raise AssertionError("did not catch expected BuildError") + self.fail("did not catch expected BuildError") built_text = None cache_text = [] -- cgit v0.12 From fef866618b5b93bebbc44b58b317aa9bb891313e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 27 Jan 2020 07:35:33 -0800 Subject: [skip appveyor] update .travis.yml to try to fix broken build --- .travis.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 985a544..99d6802 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,13 +19,6 @@ install: # do the rest of the image setup - ./.travis/install.sh -# pypy is not passing atm, but still report build success for now -# allow coverage to fail, so we can still do testing for all platforms -matrix: - allow_failures: - - python: pypy3 - - stage: Coverage - # run coverage first as its still useful to collect stages: - Coverage @@ -43,6 +36,12 @@ stages: # apparently not guaranteed. jobs: + + # pypy is not passing atm, but still report build success for now + # allow coverage to fail, so we can still do testing for all platforms + allow_failures: + - python: pypy3 + - stage: Coverage include: - &test_job stage: Test -- cgit v0.12 From bb7c5827d957a85f71093412b64571cbb5061514 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 27 Jan 2020 07:43:21 -0800 Subject: [skip appveyor] update .travis.yml to try to fix warning build --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 99d6802..b941f4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,29 +52,24 @@ jobs: env: - PYVER=pypy3 - PYTHON=pypy3 - sudo: required - - <<: *test_job python: 3.5 env: - PYVER=35 - PYTHON=3.5 - sudo: required - <<: *test_job python: 3.6 env: - PYVER=36 - PYTHON=3.6 - sudo: required - <<: *test_job python: 3.7 env: - PYVER=37 - PYTHON=3.7 - sudo: required dist: xenial # required for Python >= 3.7 - <<: *test_job @@ -82,7 +77,6 @@ jobs: env: - PYVER=38 - PYTHON=3.8 - sudo: required dist: bionic # required for Python >= 3.8 -- cgit v0.12 From 68c7c2e6c22cab4301213ecada1516caea7c05ae Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 28 Jan 2020 07:26:46 -0700 Subject: Restore test syntax after earlier change dropped it. Signed-off-by: Mats Wichmann --- test/srcchange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/srcchange.py b/test/srcchange.py index c2356b6..3c23737 100644 --- a/test/srcchange.py +++ b/test/srcchange.py @@ -62,7 +62,7 @@ SubRevision = Action(subrevision) env=Environment() content_env=env.Clone() -content_env.Command('revision.in', [], '%(_python_)s getrevision > $TARGET') +content_env.Command('revision.in', [], r'%(_python_)s getrevision > $TARGET') content_env.AlwaysBuild('revision.in') env.Precious('main.c') env.Command('main.c', 'revision.in', SubRevision) -- cgit v0.12 From f61e0f79acb17b182d3c509eceb6f8d2d1f42939 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 29 Jan 2020 07:24:21 -0700 Subject: Fix regex from recent change The new Python scanner had a couple of regexes not specified as raw strings. Python 3.9a3 complains about invalid escape, causing the option/debug-count test to fail. Adding the 'r' fixes. Signed-off-by: Mats Wichmann --- src/CHANGES.txt | 2 +- src/engine/SCons/Scanner/Python.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 36537cf..3d8b114 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -43,7 +43,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Convert remaining uses of insecure/deprecated mktemp method. - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. - Reduce needless list conversions. - + - Another Python regex syntax fix. RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000 diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py index 0ab3111..deb2241 100644 --- a/src/engine/SCons/Scanner/Python.py +++ b/src/engine/SCons/Scanner/Python.py @@ -42,8 +42,8 @@ import re import SCons.Scanner # Capture python "from a import b" and "import a" statements. -from_cre = re.compile('^\s*from\s+([^\s]+)\s+import\s+(.*)', re.M) -import_cre = re.compile('^\s*import\s+([^\s]+)', re.M) +from_cre = re.compile(r'^\s*from\s+([^\s]+)\s+import\s+(.*)', re.M) +import_cre = re.compile(r'^\s*import\s+([^\s]+)', re.M) def path_function(env, dir=None, target=None, source=None, argument=None): -- cgit v0.12 From eb9f9e4b73df82a7ab0cffc3f66bbc513c72618f Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 29 Jan 2020 12:03:47 -0700 Subject: Requested update to CHANGES.txt --- src/CHANGES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 3d8b114..99184ed 100755 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -43,7 +43,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - Convert remaining uses of insecure/deprecated mktemp method. - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes. - Reduce needless list conversions. - - Another Python regex syntax fix. + - Fixed regex in Python scanner. RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000 -- cgit v0.12