diff options
author | Adam Gross <grossag@vmware.com> | 2020-01-10 14:58:22 (GMT) |
---|---|---|
committer | Adam Gross <grossag@vmware.com> | 2020-01-10 15:04:10 (GMT) |
commit | d5ddf6ddf5c9a061ac0173e8887ce6e3e6bd5a30 (patch) | |
tree | 82704c4b0fd8868b57e20cb69c574fb5fb79df6a /src/engine/SCons | |
parent | e6dc8216872085749db83e14c9545cabb1ed0483 (diff) | |
parent | 9340ef85fea770d01d416ac2dbc2f4991a67e027 (diff) | |
download | SCons-d5ddf6ddf5c9a061ac0173e8887ce6e3e6bd5a30.zip SCons-d5ddf6ddf5c9a061ac0173e8887ce6e3e6bd5a30.tar.gz SCons-d5ddf6ddf5c9a061ac0173e8887ce6e3e6bd5a30.tar.bz2 |
Merge branch 'master' into topic/grossag/valuename
Diffstat (limited to 'src/engine/SCons')
167 files changed, 1065 insertions, 1165 deletions
diff --git a/src/engine/SCons/Action.xml b/src/engine/SCons/Action.xml index ab42958..7a8194e 100644 --- a/src/engine/SCons/Action.xml +++ b/src/engine/SCons/Action.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 3054368..3303750 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1208,10 +1208,6 @@ class CommandActionTestCase(unittest.TestCase): # Newer cygwin seems to return 126 for following expect_nonexecutable_file = 126 expect_nonexecutable_dir = 127 - elif sys.platform.find('sunos') != -1: - expect_nonexistent = 1 - expect_nonexecutable_file = 1 - expect_nonexecutable_dir = 1 else: expect_nonexistent = 127 expect_nonexecutable_file = 126 diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index b03a425..f28e201 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -581,7 +581,7 @@ class BuilderTestCase(unittest.TestCase): assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env) def test_srcsuffix_nonext(self): - "Test target generation from non-extension source suffixes" + """Test target generation from non-extension source suffixes""" env = Environment() b6 = SCons.Builder.Builder(action = '', src_suffix='_src.a', @@ -679,7 +679,7 @@ class BuilderTestCase(unittest.TestCase): """create the file""" with open(str(target[0]), "w"): pass - if (len(source) == 1 and len(target) == 1): + if len(source) == 1 and len(target) == 1: env['CNT'][0] = env['CNT'][0] + 1 env = Environment() 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 07c32b4..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 @@ -130,7 +129,7 @@ class ExceptionTestCase(unittest.TestCase): @unittest.skipIf(sys.platform.startswith("win"), "This fixture will not trigger an OSError on Windows") def test_throws_correct_on_OSError(self): """Test that the correct error is thrown when cache directory cannot be created.""" - privileged_dir = os.path.join(os.getcwd(), "privileged") + privileged_dir = os.path.join(self.tmpdir, "privileged") try: os.mkdir(privileged_dir) os.chmod(privileged_dir, stat.S_IREAD) @@ -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/Defaults.xml b/src/engine/SCons/Defaults.xml index b3899d9..22f46fe 100644 --- a/src/engine/SCons/Defaults.xml +++ b/src/engine/SCons/Defaults.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ @@ -572,15 +572,21 @@ searching the repositories. <scons_function name="DefaultEnvironment"> <arguments signature="global"> -([args]) +([**kwargs]) </arguments> <summary> <para> -Creates and returns a default construction environment object. -This construction environment is used internally by SCons -in order to execute many of the global functions in this list, -and to fetch source files transparently +Creates and returns the default &consenv; object. +The default &consenv; is used internally by SCons +in order to execute many of the global functions in this list +(i.e. those not called as methods of a specific +&consenv;), and to fetch source files transparently from source code management systems. +The default environment is a singleton, so the keyword +arguments affect it only on the first call, on subsequent +calls the already-constructed object is returned. +The default environment can be modified in the same way +as any &consenv;. </para> </summary> </scons_function> diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 1296f54..3e23196 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1428,14 +1428,6 @@ class Base(SubstitutionEnvironment): if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.EnvironmentClone') return clone - def Copy(self, *args, **kw): - global _warn_copy_deprecated - if _warn_copy_deprecated: - msg = "The env.Copy() method is deprecated; use the env.Clone() method instead." - SCons.Warnings.warn(SCons.Warnings.DeprecatedCopyWarning, msg) - _warn_copy_deprecated = False - return self.Clone(*args, **kw) - def _changed_build(self, dependency, target, prev_ni, repo_node=None): if dependency.changed_state(target, prev_ni, repo_node): return 1 @@ -1937,14 +1929,6 @@ class Base(SubstitutionEnvironment): t.set_always_build() return tlist - def BuildDir(self, *args, **kw): - msg = """BuildDir() and the build_dir keyword have been deprecated;\n\tuse VariantDir() and the variant_dir keyword instead.""" - SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg) - if 'build_dir' in kw: - kw['variant_dir'] = kw['build_dir'] - del kw['build_dir'] - return self.VariantDir(*args, **kw) - def Builder(self, **kw): nkw = self.subst_kw(kw) return SCons.Builder.Builder(**nkw) @@ -1983,13 +1967,42 @@ class Base(SubstitutionEnvironment): be any type that the Builder constructor will accept for an action.""" bkw = { - 'action' : action, - 'target_factory' : self.fs.Entry, - 'source_factory' : self.fs.Entry, + 'action': action, + 'target_factory': self.fs.Entry, + 'source_factory': self.fs.Entry, } - try: bkw['source_scanner'] = kw['source_scanner'] - except KeyError: pass - else: del kw['source_scanner'] + # source scanner + try: + bkw['source_scanner'] = kw['source_scanner'] + except KeyError: + pass + else: + del kw['source_scanner'] + + # target scanner + try: + bkw['target_scanner'] = kw['target_scanner'] + except KeyError: + pass + else: + del kw['target_scanner'] + + # source factory + try: + bkw['source_factory'] = kw['source_factory'] + except KeyError: + pass + else: + del kw['source_factory'] + + # target factory + try: + bkw['target_factory'] = kw['target_factory'] + except KeyError: + pass + else: + del kw['target_factory'] + bld = SCons.Builder.Builder(**bkw) return bld(self, target, source, **kw) @@ -2186,16 +2199,6 @@ class Base(SubstitutionEnvironment): target.side_effects.append(side_effect) return side_effects - def SourceCode(self, entry, builder): - """Arrange for a source code builder for (part of) a tree.""" - msg = """SourceCode() has been deprecated and there is no replacement. -\tIf you need this function, please contact scons-dev@scons.org""" - SCons.Warnings.warn(SCons.Warnings.DeprecatedSourceCodeWarning, msg) - entries = self.arg2nodes(entry, self.fs.Entry) - for entry in entries: - entry.set_src_builder(builder) - return entries - def Split(self, arg): """This function converts a string or list into a list of strings or Nodes. This makes things easier for users by allowing files to @@ -2220,7 +2223,7 @@ class Base(SubstitutionEnvironment): def Value(self, value, built_value=None): """ """ - return SCons.Node.Python.Value(value, built_value) + return SCons.Node.Python.ValueWithMemo(value, built_value) def VariantDir(self, variant_dir, src_dir, duplicate=1): variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] @@ -2244,7 +2247,7 @@ class Base(SubstitutionEnvironment): build_source(node.all_children()) def final_source(node): - while (node != node.srcnode()): + while node != node.srcnode(): node = node.srcnode() return node sources = list(map(final_source, sources)) diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml index 516505c..35e4bd8 100644 --- a/src/engine/SCons/Environment.xml +++ b/src/engine/SCons/Environment.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ @@ -613,28 +613,6 @@ env.AppendUnique(CCFLAGS = '-g', FOO = ['foo.yyy']) </summary> </scons_function> -<scons_function name="BuildDir"> -<arguments> -(build_dir, src_dir, [duplicate]) -</arguments> -<summary> -<para> -Deprecated synonyms for -&f-VariantDir; -and -<function>env.VariantDir</function>(). -The -<varname>build_dir</varname> -argument becomes the -<varname>variant_dir</varname> -argument of -&f-VariantDir; -or -<function>env.VariantDir</function>(). -</para> -</summary> -</scons_function> - <scons_function name="Builder"> <arguments> (action, [arguments]) @@ -937,19 +915,29 @@ for a single special-case build. </para> <para> -As a special case, the -<varname>source_scanner</varname> -keyword argument can +&b-Command; builder accepts +<varname>source_scanner</varname>, +<varname>target_scanner</varname>, +<varname>source_factory</varname>, and +<varname>target_factory</varname> +keyword arguments. The *_scanner args can be used to specify a Scanner object -that will be used to scan the sources. -(The global +that will be used to apply a custom +scanner for a source or target. +For example, the global <literal>DirScanner</literal> object can be used if any of the sources will be directories that must be scanned on-disk for changes to files that aren't -already specified in other Builder of function calls.) +already specified in other Builder of function calls. +The *_factory args take a factory function that the +Command will use to turn any sources or targets +specified as strings into SCons Nodes. +See the sections "Builder Objects" +below, for more information about how these +args work in a Builder. </para> <para> @@ -1414,7 +1402,7 @@ This SConstruct: <example_commands> env=Environment() -print env.Dump('CCCOM') +print(env.Dump('CCCOM')) </example_commands> <para> @@ -1431,7 +1419,7 @@ While this SConstruct: <example_commands> env=Environment() -print env.Dump() +print(env.Dump()) </example_commands> <para> @@ -2891,117 +2879,18 @@ function. </summary> </scons_function> -<scons_function name="SourceCode"> -<arguments> -(entries, builder) -</arguments> -<summary> -<para> -This function and its associate factory functions are deprecated. -There is no replacement. -The intended use was to keep a local tree in sync with an archive, -but in actuality the function only causes the archive -to be fetched on the first run. -Synchronizing with the archive is best done external to &SCons;. -</para> - -<para> -Arrange for non-existent source files to -be fetched from a source code management system -using the specified -<varname>builder</varname>. -The specified -<varname>entries</varname> -may be a Node, string or list of both, -and may represent either individual -source files or directories in which -source files can be found. -</para> - -<para> -For any non-existent source files, -&scons; -will search up the directory tree -and use the first -&f-SourceCode; -builder it finds. -The specified -<varname>builder</varname> -may be -<literal>None</literal>, -in which case -&scons; -will not use a builder to fetch -source files for the specified -<varname>entries</varname>, -even if a -&f-SourceCode; -builder has been specified -for a directory higher up the tree. -</para> - -<para> -&scons; -will, by default, -fetch files from SCCS or RCS subdirectories -without explicit configuration. -This takes some extra processing time -to search for the necessary -source code management files on disk. -You can avoid these extra searches -and speed up your build a little -by disabling these searches as follows: -</para> - -<example_commands> -env.SourceCode('.', None) -</example_commands> - -<para> -Note that if the specified -<varname>builder</varname> -is one you create by hand, -it must have an associated -construction environment to use -when fetching a source file. -</para> - -<para> -&scons; -provides a set of canned factory -functions that return appropriate -Builders for various popular -source code management systems. -Canonical examples of invocation include: -</para> - -<example_commands> -env.SourceCode('.', env.BitKeeper('/usr/local/BKsources')) -env.SourceCode('src', env.CVS('/usr/local/CVSROOT')) -env.SourceCode('/', env.RCS()) -env.SourceCode(['f1.c', 'f2.c'], env.SCCS()) -env.SourceCode('no_source.c', None) -</example_commands> -<para> -<!-- env.SourceCode('.', env.Subversion('file:///usr/local/Subversion')) --> -</para> -</summary> -</scons_function> - <scons_function name="Split"> -<arguments> -(arg) -</arguments> +<arguments>(arg)</arguments> <summary> <para> Returns a list of file names or other objects. -If arg is a string, +If <varname>arg</varname> 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, +If <varname>arg</varname> is already a list, the list will be returned untouched. -If arg is any other type of object, +If <varname>arg</varname> is any other type of object, it will be returned as a list containing just the object. </para> @@ -3014,9 +2903,9 @@ 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 + f7.c + f8.c + f9.c """) </example_commands> </summary> @@ -3118,7 +3007,7 @@ Example: </para> <example_commands> -print env.subst("The C compiler is: $CC") +print(env.subst("The C compiler is: $CC")) def compile(target, source, env): sourceDir = env.subst("${SOURCE.srcdir}", diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0957361..f3779c7 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -726,7 +726,7 @@ sys.exit(0) assert r == 'replace_func2', r def test_Override(self): - "Test overriding construction variables" + """Test overriding construction variables""" env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4) assert env['ONE'] == 1, env['ONE'] assert env['TWO'] == 2, env['TWO'] @@ -1408,7 +1408,7 @@ def exists(env): assert env['XYZ'] == 'ddd', env def test_concat(self): - "Test _concat()" + """Test _concat()""" e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b']) s = e1.subst x = s("${_concat('', '', '', __env__)}") @@ -1423,7 +1423,7 @@ def exists(env): assert x == 'preasuf prebsuf', x def test_concat_nested(self): - "Test _concat() on a nested substitution strings." + """Test _concat() on a nested substitution strings.""" e = self.TestEnvironment(PRE='pre', SUF='suf', L1=['a', 'b'], L2=['c', 'd'], @@ -1876,18 +1876,6 @@ def generate(env): assert ('BUILDERS' in env) is False env2 = env.Clone() - def test_Copy(self): - """Test copying using the old env.Copy() method""" - env1 = self.TestEnvironment(XXX = 'x', YYY = 'y') - env2 = env1.Copy() - env1copy = env1.Copy() - assert env1copy == env1copy - assert env2 == env2 - env2.Replace(YYY = 'yyy') - assert env2 == env2 - assert env1 != env2 - assert env1 == env1copy - def test_Detect(self): """Test Detect()ing tools""" test = TestCmd.TestCmd(workdir = '') @@ -1968,7 +1956,7 @@ def generate(env): assert 'XXX' not in env.Dictionary() def test_FindIxes(self): - "Test FindIxes()" + """Test FindIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', SHLIBPREFIX='lib', @@ -2410,7 +2398,7 @@ f5: \ assert hasattr(env3, 'b2'), "b2 was not set" def test_ReplaceIxes(self): - "Test ReplaceIxes()" + """Test ReplaceIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', SHLIBPREFIX='lib', @@ -3267,25 +3255,6 @@ def generate(env): assert ggg.side_effects == [s], ggg.side_effects assert ccc.side_effects == [s], ccc.side_effects - def test_SourceCode(self): - """Test the SourceCode() method.""" - env = self.TestEnvironment(FOO='mmm', BAR='nnn') - e = env.SourceCode('foo', None)[0] - assert e.get_internal_path() == 'foo' - s = e.src_builder() - assert s is None, s - - b = Builder() - e = env.SourceCode(e, b)[0] - assert e.get_internal_path() == 'foo' - s = e.src_builder() - assert s is b, s - - e = env.SourceCode('$BAR$FOO', None)[0] - assert e.get_internal_path() == 'nnnmmm' - s = e.src_builder() - assert s is None, s - def test_Split(self): """Test the Split() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -3315,8 +3284,7 @@ def generate(env): assert v2.value == value2, v2.value assert v2.value is value2, v2.value - assert not v1 is v2 - assert v1.value == v2.value + assert v1 is v2 v3 = env.Value('c', 'build-c') assert v3.value == 'c', v3.value @@ -3462,7 +3430,7 @@ def generate(env): assert x in over, bad_msg % x def test_parse_flags(self): - '''Test the Base class parse_flags argument''' + """Test the Base class parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools=[], parse_flags = '-X') assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] @@ -3476,7 +3444,7 @@ def generate(env): assert env['CPPDEFINES'] == ['FOO', 'BAR'], env['CPPDEFINES'] def test_clone_parse_flags(self): - '''Test the env.Clone() parse_flags argument''' + """Test the env.Clone() parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools = []) env2 = env.Clone(parse_flags = '-X') @@ -3745,7 +3713,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert x == ['x3', 'y3', 'z3'], x def test_parse_flags(self): - '''Test the OverrideEnvironment parse_flags argument''' + """Test the OverrideEnvironment parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = SubstitutionEnvironment() env2 = env.Override({'parse_flags' : '-X'}) diff --git a/src/engine/SCons/EnvironmentValues.py b/src/engine/SCons/EnvironmentValues.py index d94bf3a..6599196 100644 --- a/src/engine/SCons/EnvironmentValues.py +++ b/src/engine/SCons/EnvironmentValues.py @@ -3,7 +3,7 @@ import re _is_valid_var = re.compile(r'[_a-zA-Z]\w*$') _rm = re.compile(r'\$[()]') -_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') +_remove = re.compile(r'\$\([^$]*(\$[^)][^$]*)*\$\)') # Regular expressions for splitting strings and handling substitutions, # for use by the scons_subst() and scons_subst_list() functions: @@ -28,7 +28,7 @@ _remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)') # _dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}' _dollar_exps = re.compile(r'(%s)' % _dollar_exps_str) -_separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str) +_separate_args = re.compile(r'(%s|\s+|[^\s$]+|\$)' % _dollar_exps_str) # This regular expression is used to replace strings of multiple white # space characters in the string result from the scons_subst() function. diff --git a/src/engine/SCons/JobTests.py b/src/engine/SCons/JobTests.py index 26e3d37..2e3af4f 100644 --- a/src/engine/SCons/JobTests.py +++ b/src/engine/SCons/JobTests.py @@ -46,7 +46,7 @@ def get_cpu_nums(): return int( os.popen2( "sysctl -n hw.ncpu")[1].read() ) # Windows: if "NUMBER_OF_PROCESSORS" in os.environ: - ncpus = int( os.environ[ "NUMBER_OF_PROCESSORS" ] ); + ncpus = int(os.environ["NUMBER_OF_PROCESSORS"]) if ncpus > 0: return ncpus return 1 # Default @@ -59,14 +59,14 @@ num_jobs = get_cpu_nums()*2 # in case we werent able to detect num cpus for this test # just make a hardcoded suffcient large number, though not future proof -if(num_jobs == 2): +if num_jobs == 2: num_jobs = 33 # how many tasks to perform for the test num_tasks = num_jobs*5 class DummyLock(object): - "fake lock class to use if threads are not supported" + """fake lock class to use if threads are not supported""" def acquire(self): pass @@ -74,7 +74,7 @@ class DummyLock(object): pass class NoThreadsException(Exception): - "raised by the ParallelTestCase if threads are not supported" + """raised by the ParallelTestCase if threads are not supported""" def __str__(self): return "the interpreter doesn't support threads" @@ -113,7 +113,7 @@ class Task(object): # check if task was executing while another was also executing for j in range(1, self.taskmaster.num_tasks): - if(self.taskmaster.parallel_list[j+1] == 1): + if self.taskmaster.parallel_list[j + 1] == 1: self.taskmaster.found_parallel = True break @@ -237,7 +237,7 @@ class Taskmaster(object): return self.num_postprocessed == self.num_tasks def tasks_were_serial(self): - "analyze the task order to see if they were serial" + """analyze the task order to see if they were serial""" return not self.found_parallel def exception_set(self): @@ -251,7 +251,7 @@ ThreadPoolCallList = [] class ParallelTestCase(unittest.TestCase): def runTest(self): - "test parallel jobs" + """test parallel jobs""" try: import threading @@ -319,7 +319,7 @@ class ParallelTestCase(unittest.TestCase): class SerialTestCase(unittest.TestCase): def runTest(self): - "test a serial job" + """test a serial job""" taskmaster = Taskmaster(num_tasks, self, RandomTask) jobs = SCons.Job.Jobs(1, taskmaster) @@ -338,7 +338,7 @@ class SerialTestCase(unittest.TestCase): class NoParallelTestCase(unittest.TestCase): def runTest(self): - "test handling lack of parallel support" + """test handling lack of parallel support""" def NoParallel(tm, num, stack_size): raise NameError save_Parallel = SCons.Job.Parallel @@ -365,7 +365,7 @@ class NoParallelTestCase(unittest.TestCase): class SerialExceptionTestCase(unittest.TestCase): def runTest(self): - "test a serial job with tasks that raise exceptions" + """test a serial job with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) jobs = SCons.Job.Jobs(1, taskmaster) @@ -382,7 +382,7 @@ class SerialExceptionTestCase(unittest.TestCase): class ParallelExceptionTestCase(unittest.TestCase): def runTest(self): - "test parallel jobs with tasks that raise exceptions" + """test parallel jobs with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) jobs = SCons.Job.Jobs(num_jobs, taskmaster) @@ -534,13 +534,13 @@ class _SConsTaskTest(unittest.TestCase): class SerialTaskTest(_SConsTaskTest): def runTest(self): - "test serial jobs with actual Taskmaster and Task" + """test serial jobs with actual Taskmaster and Task""" self._test_seq(1) class ParallelTaskTest(_SConsTaskTest): def runTest(self): - "test parallel jobs with actual Taskmaster and Task" + """test parallel jobs with actual Taskmaster and Task""" self._test_seq(num_jobs) diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py index a035816..55d94f9 100644 --- a/src/engine/SCons/Node/Alias.py +++ b/src/engine/SCons/Node/Alias.py @@ -37,6 +37,7 @@ import collections import SCons.Errors import SCons.Node import SCons.Util +from SCons.Util import MD5signature class AliasNameSpace(collections.UserDict): def Alias(self, name, **kw): @@ -166,7 +167,7 @@ class Alias(SCons.Node.Node): pass contents = self.get_contents() - csig = SCons.Util.MD5signature(contents) + csig = MD5signature(contents) self.get_ninfo().csig = csig return csig diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 6b0fe98..e1d6f68 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -54,6 +54,7 @@ import SCons.Node import SCons.Node.Alias import SCons.Subst import SCons.Util +from SCons.Util import MD5signature, MD5filesignature, MD5collect import SCons.Warnings from SCons.Debug import Trace @@ -963,14 +964,14 @@ class Entry(Base): def disambiguate(self, must_exist=None): """ - """ - if self.isdir(): - self.__class__ = Dir - self._morph() - elif self.isfile(): + """ + if self.isfile(): self.__class__ = File self._morph() self.clear() + elif self.isdir(): + self.__class__ = Dir + self._morph() else: # There was nothing on-disk at this location, so look in # the src directory. @@ -1862,7 +1863,7 @@ class Dir(Base): node is called which has a child directory, the child directory should return the hash of its contents.""" contents = self.get_contents() - return SCons.Util.MD5signature(contents) + return MD5signature(contents) def do_duplicate(self, src): pass @@ -2501,14 +2502,14 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): Attributes unique to FileBuildInfo: dependency_map : Caches file->csig mapping - for all dependencies. Currently this is only used when using - MD5-timestamp decider. - It's used to ensure that we copy the correct - csig from previous build to be written to .sconsign when current build - is done. Previously the matching of csig to file was strictly by order - they appeared in bdepends, bsources, or bimplicit, and so a change in order - or count of any of these could yield writing wrong csig, and then false positive - rebuilds + for all dependencies. Currently this is only used when using + MD5-timestamp decider. + It's used to ensure that we copy the correct csig from the + previous build to be written to .sconsign when current build + is done. Previously the matching of csig to file was strictly + by order they appeared in bdepends, bsources, or bimplicit, + and so a change in order or count of any of these could + yield writing wrong csig, and then false positive rebuilds """ __slots__ = ['dependency_map', ] current_version_id = 2 @@ -2723,11 +2724,10 @@ class File(Base): Compute and return the MD5 hash for this file. """ if not self.rexists(): - return SCons.Util.MD5signature('') + return MD5signature('') fname = self.rfile().get_abspath() try: - cs = SCons.Util.MD5filesignature(fname, - chunksize=SCons.Node.FS.File.md5_chunksize*1024) + cs = MD5filesignature(fname, chunksize=File.md5_chunksize * 1024) except EnvironmentError as e: if not e.filename: e.filename = fname @@ -3028,7 +3028,7 @@ class File(Base): @see: built() and Node.release_target_info() """ - if (self.released_target_info or SCons.Node.interactive): + if self.released_target_info or SCons.Node.interactive: return if not hasattr(self.attributes, 'keep_targetinfo'): @@ -3210,7 +3210,7 @@ class File(Base): if csig is None: try: - if self.get_size() < SCons.Node.FS.File.md5_chunksize: + if self.get_size() < File.md5_chunksize: contents = self.get_contents() else: csig = self.get_content_hash() @@ -3312,7 +3312,7 @@ class File(Base): # For an "empty" binfo properties like bsources # do not exist: check this to avoid exception. - if (len(binfo.bsourcesigs) + len(binfo.bdependsigs) + \ + if (len(binfo.bsourcesigs) + len(binfo.bdependsigs) + len(binfo.bimplicitsigs)) == 0: return {} @@ -3580,7 +3580,7 @@ class File(Base): node = repo_dir.file_on_disk(self.name) if node and node.exists() and \ - (isinstance(node, File) or isinstance(node, Entry) \ + (isinstance(node, File) or isinstance(node, Entry) or not node.is_derived()): retvals.append(node) @@ -3611,8 +3611,7 @@ class File(Base): cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self) if not self.exists() and cachefile and os.path.exists(cachefile): - self.cachedir_csig = SCons.Util.MD5filesignature(cachefile, \ - SCons.Node.FS.File.md5_chunksize * 1024) + self.cachedir_csig = MD5filesignature(cachefile, File.md5_chunksize * 1024) else: self.cachedir_csig = self.get_csig() return self.cachedir_csig @@ -3632,7 +3631,7 @@ class File(Base): executor = self.get_executor() - result = self.contentsig = SCons.Util.MD5signature(executor.get_contents()) + result = self.contentsig = MD5signature(executor.get_contents()) return result def get_cachedir_bsig(self): @@ -3663,7 +3662,7 @@ class File(Base): sigs.append(self.get_internal_path()) # Merge this all into a single signature - result = self.cachesig = SCons.Util.MD5collect(sigs) + result = self.cachesig = MD5collect(sigs) return result default_fs = None diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index eddfdf0..9c19481 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -2508,8 +2508,8 @@ class FileTestCase(_tempdirTestCase): build_f1, src_f1) def test_changed(self): - """ - Verify that changes between BuildInfo's list of souces, depends, and implicit + """ + Verify that changes between BuildInfo's list of souces, depends, and implicit dependencies do not corrupt content signature values written to .SConsign when using CacheDir and Timestamp-MD5 decider. This is for issue #2980 @@ -3374,10 +3374,11 @@ class find_fileTestCase(unittest.TestCase): node_pseudo.set_src_builder(1) # Any non-zero value. paths = tuple(map(fs.Dir, ['.', 'same', './bar'])) - nodes = [SCons.Node.FS.find_file('foo', paths)] - nodes.append(SCons.Node.FS.find_file('baz', paths)) - nodes.append(SCons.Node.FS.find_file('pseudo', paths)) - nodes.append(SCons.Node.FS.find_file('same', paths)) + nodes = [SCons.Node.FS.find_file('foo', paths), + SCons.Node.FS.find_file('baz', paths), + SCons.Node.FS.find_file('pseudo', paths), + SCons.Node.FS.find_file('same', paths) + ] file_names = list(map(str, nodes)) file_names = list(map(os.path.normpath, file_names)) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 678e03e..d8179ff 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -1304,7 +1304,7 @@ class NodeTestCase(unittest.TestCase): def test_postprocess(self): """Test calling the base Node postprocess() method""" n = SCons.Node.Node() - n.waiting_parents = set( ['foo','bar'] ) + n.waiting_parents = {'foo', 'bar'} n.postprocess() assert n.waiting_parents == set(), n.waiting_parents @@ -1316,7 +1316,7 @@ class NodeTestCase(unittest.TestCase): assert n1.waiting_parents == set(), n1.waiting_parents r = n1.add_to_waiting_parents(n2) assert r == 1, r - assert n1.waiting_parents == set((n2,)), n1.waiting_parents + assert n1.waiting_parents == {n2}, n1.waiting_parents r = n1.add_to_waiting_parents(n2) assert r == 0, r diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 83e38f0..385a645 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -31,6 +31,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Node +_memo_lookup_map = {} + + class ValueNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('csig',) current_version_id = 2 @@ -38,18 +41,18 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase): field_list = ['csig'] def str_to_node(self, s): - return Value(s) + return ValueWithMemo(s) def __getstate__(self): """ Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. + hierarchy and add those to the state dictionary. If a '__dict__' slot + is available, copy all entries to the dictionary. Also include the + version id, which is fixed for all instances of a class. """ state = getattr(self, '__dict__', {}).copy() for obj in type(self).mro(): - for name in getattr(obj,'__slots__',()): + for name in getattr(obj, '__slots__', ()): if hasattr(self, name): state[name] = getattr(self, name) @@ -76,6 +79,7 @@ class ValueBuildInfo(SCons.Node.BuildInfoBase): __slots__ = () current_version_id = 2 + class Value(SCons.Node.Node): """A class for Python variables, typically passed on the command line or generated by a script, but not from a file or some other source. @@ -176,6 +180,28 @@ class Value(SCons.Node.Node): self.get_ninfo().csig = contents return contents + +def ValueWithMemo(value, built_value=None): + global _memo_lookup_map + + # No current support for memoizing a value that needs to be built. + if built_value: + return Value(value, built_value) + + try: + memo_lookup_key = hash(value) + except TypeError: + # Non-primitive types will hit this codepath. + return Value(value) + + try: + return _memo_lookup_map[memo_lookup_key] + except KeyError: + v = Value(value) + _memo_lookup_map[memo_lookup_key] = v + return v + + # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py index 9d3c6b5..45248d3 100644 --- a/src/engine/SCons/Node/PythonTests.py +++ b/src/engine/SCons/Node/PythonTests.py @@ -23,14 +23,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import sys import unittest import SCons.Errors import SCons.Node.Python -class ValueTestCase(unittest.TestCase): +class ValueTestCase(unittest.TestCase): def test_Value(self): """Test creating a Value() object """ @@ -42,7 +41,7 @@ class ValueTestCase(unittest.TestCase): assert v2.value == value2, v2.value assert v2.value is value2, v2.value - assert not v1 is v2 + assert v1 is not v2 assert v1.value == v2.value v3 = SCons.Node.Python.Value('c', 'cb') @@ -98,12 +97,14 @@ class ValueTestCase(unittest.TestCase): csig = v3.get_csig(None) assert csig == 'None', csig + class ValueNodeInfoTestCase(unittest.TestCase): def test___init__(self): """Test ValueNodeInfo initialization""" vvv = SCons.Node.Python.Value('vvv') ni = SCons.Node.Python.ValueNodeInfo() + class ValueBuildInfoTestCase(unittest.TestCase): def test___init__(self): """Test ValueBuildInfo initialization""" @@ -121,6 +122,39 @@ class ValueChildTestCase(unittest.TestCase): contents = node.get_contents() assert len(contents) > 0 + +class ValueMemoTestCase(unittest.TestCase): + def test_memo(self): + """Test memoization""" + # First confirm that ValueWithMemo does memoization. + value1 = SCons.Node.Python.ValueWithMemo('vvv') + value2 = SCons.Node.Python.ValueWithMemo('vvv') + assert value1 is value2 + + # Next confirm that ValueNodeInfo.str_to_node does memoization using + # the same cache as ValueWithMemo. + ni = SCons.Node.Python.ValueNodeInfo() + value3 = ni.str_to_node('vvv') + assert value1 is value3 + + def test_built_value(self): + """Confirm that built values are not memoized.""" + v1 = SCons.Node.Python.ValueWithMemo('c', 'ca') + v2 = SCons.Node.Python.ValueWithMemo('c', 'ca') + assert v1 is not v2 + + def test_non_primitive_values(self): + """Confirm that non-primitive values are not memoized.""" + d = {'a': 1} + v1 = SCons.Node.Python.ValueWithMemo(d) + v2 = SCons.Node.Python.ValueWithMemo(d) + assert v1 is not v2 + + a = [1] + v3 = SCons.Node.Python.ValueWithMemo(a) + v4 = SCons.Node.Python.ValueWithMemo(a) + assert v3 is not v4 + if __name__ == "__main__": unittest.main() diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 4200965..0b58282 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -60,6 +60,7 @@ from SCons.Debug import logInstanceCreation import SCons.Executor import SCons.Memoize import SCons.Util +from SCons.Util import MD5signature from SCons.Debug import Trace @@ -741,12 +742,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() @@ -1167,7 +1168,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): if self.has_builder(): binfo.bact = str(executor) - binfo.bactsig = SCons.Util.MD5signature(executor.get_contents()) + binfo.bactsig = MD5signature(executor.get_contents()) if self._specific_sources: sources = [s for s in self.sources if s not in ignore_set] @@ -1205,7 +1206,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): return self.ninfo.csig except AttributeError: ninfo = self.get_ninfo() - ninfo.csig = SCons.Util.MD5signature(self.get_contents()) + ninfo.csig = MD5signature(self.get_contents()) return self.ninfo.csig def get_cachedir_csig(self): @@ -1496,7 +1497,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)): if self.has_builder(): contents = self.get_executor().get_contents() - newsig = SCons.Util.MD5signature(contents) + newsig = MD5signature(contents) if bi.bactsig != newsig: if t: Trace(': bactsig %s != newsig %s' % (bi.bactsig, newsig)) result = True diff --git a/src/engine/SCons/PathListTests.py b/src/engine/SCons/PathListTests.py index b5989bb..104be73 100644 --- a/src/engine/SCons/PathListTests.py +++ b/src/engine/SCons/PathListTests.py @@ -108,7 +108,7 @@ class subst_pathTestCase(unittest.TestCase): self.env.subst = lambda s, target, source, conv: 'NOT THIS STRING' - pl = SCons.PathList.PathList(('x')) + pl = SCons.PathList.PathList(('x',)) result = pl.subst_path(self.env, 'y', 'z') diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 7d959b7..058241d 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -192,11 +192,6 @@ class TempFileMunge(object): if cmdlist is not None: return cmdlist - # We do a normpath because mktemp() has what appears to be - # a bug in Windows that will use a forward slash as a path - # delimiter. Windows' link mistakes that for a command line - # switch and barfs. - # # 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. @@ -206,7 +201,7 @@ class TempFileMunge(object): suffix = '.lnk' fd, tmp = tempfile.mkstemp(suffix, text=True) - native_tmp = SCons.Util.get_native_path(os.path.normpath(tmp)) + native_tmp = SCons.Util.get_native_path(tmp) if env.get('SHELL', None) == 'sh': # The sh shell will try to escape the backslashes in the diff --git a/src/engine/SCons/Platform/__init__.xml b/src/engine/SCons/Platform/__init__.xml index 7ea895e..4548e00 100644 --- a/src/engine/SCons/Platform/__init__.xml +++ b/src/engine/SCons/Platform/__init__.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Platform/posix.xml b/src/engine/SCons/Platform/posix.xml index 80b5e8d..4b2e0cd 100644 --- a/src/engine/SCons/Platform/posix.xml +++ b/src/engine/SCons/Platform/posix.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Platform/sunos.xml b/src/engine/SCons/Platform/sunos.xml index 4921f4c..6f912e3 100644 --- a/src/engine/SCons/Platform/sunos.xml +++ b/src/engine/SCons/Platform/sunos.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Platform/virtualenv.py b/src/engine/SCons/Platform/virtualenv.py index 4127d8c..4708cb2 100644 --- a/src/engine/SCons/Platform/virtualenv.py +++ b/src/engine/SCons/Platform/virtualenv.py @@ -61,7 +61,7 @@ def _is_path_in(path, base): if not path or not base: # empty path may happen, base too return False rp = os.path.relpath(path, base) - return ((not rp.startswith(os.path.pardir)) and (not rp == os.path.curdir)) + return (not rp.startswith(os.path.pardir)) and (not rp == os.path.curdir) def _inject_venv_variables(env): diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 0a3b199..bb1b46d 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -51,10 +51,6 @@ try: import msvcrt import win32api import win32con - - msvcrt.get_osfhandle - win32api.SetHandleInformation - win32con.HANDLE_FLAG_INHERIT except ImportError: parallel_msg = \ "you do not seem to have the pywin32 extensions installed;\n" + \ @@ -66,28 +62,44 @@ except AttributeError: else: parallel_msg = None - _builtin_open = open + if sys.version_info.major == 2: + import __builtin__ + + _builtin_file = __builtin__.file + _builtin_open = __builtin__.open + + def _scons_fixup_mode(mode): + """Adjust 'mode' to mark handle as non-inheritable. + + SCons is multithreaded, so allowing handles to be inherited by + children opens us up to races, where (e.g.) processes spawned by + the Taskmaster may inherit and retain references to files opened + by other threads. This may lead to sharing violations and, + ultimately, build failures. + + By including 'N' as part of fopen's 'mode' parameter, all file + handles returned from these functions are atomically marked as + non-inheritable. + """ + if not mode: + # Python's default is 'r'. + # https://docs.python.org/2/library/functions.html#open + mode = 'rN' + elif 'N' not in mode: + mode += 'N' + return mode - def _scons_open(*args, **kw): - fp = _builtin_open(*args, **kw) - win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), - win32con.HANDLE_FLAG_INHERIT, - 0) - return fp + class _scons_file(_builtin_file): + def __init__(self, name, mode=None, *args, **kwargs): + _builtin_file.__init__(self, name, _scons_fixup_mode(mode), + *args, **kwargs) - open = _scons_open + def _scons_open(name, mode=None, *args, **kwargs): + return _builtin_open(name, _scons_fixup_mode(mode), + *args, **kwargs) - if sys.version_info.major == 2: - _builtin_file = file - class _scons_file(_builtin_file): - def __init__(self, *args, **kw): - _builtin_file.__init__(self, *args, **kw) - win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), - win32con.HANDLE_FLAG_INHERIT, 0) - file = _scons_file - else: - # No longer needed for python 3.4 and above. Files are opened non sharable - pass + __builtin__.file = _scons_file + __builtin__.open = _scons_open @@ -166,61 +178,68 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): # we redirect it into a temporary file tmpFileStdout # (tmpFileStderr) and copy the contents of this file # to stdout (stderr) given in the argument + # Note that because this will paste shell redirection syntax + # into the cmdline, we have to call a shell to run the command, + # even though that's a bit of a performance hit. if not sh: sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n") return 127 - else: - # one temporary file for stdout and stderr - tmpFileStdout = os.path.normpath(tempfile.mktemp()) - tmpFileStderr = os.path.normpath(tempfile.mktemp()) - - # check if output is redirected - stdoutRedirected = 0 - stderrRedirected = 0 - for arg in args: - # are there more possibilities to redirect stdout ? - if arg.find( ">", 0, 1 ) != -1 or arg.find( "1>", 0, 2 ) != -1: - stdoutRedirected = 1 - # are there more possibilities to redirect stderr ? - if arg.find( "2>", 0, 2 ) != -1: - stderrRedirected = 1 - - # redirect output of non-redirected streams to our tempfiles - if stdoutRedirected == 0: - args.append(">" + str(tmpFileStdout)) - if stderrRedirected == 0: - args.append("2>" + str(tmpFileStderr)) - - # actually do the spawn + + # one temporary file for stdout and stderr + tmpFileStdout, tmpFileStdoutName = tempfile.mkstemp(text=True) + os.close(tmpFileStdout) # don't need open until the subproc is done + tmpFileStderr, tmpFileStderrName = tempfile.mkstemp(text=True) + os.close(tmpFileStderr) + + # check if output is redirected + stdoutRedirected = False + stderrRedirected = False + for arg in args: + # are there more possibilities to redirect stdout ? + if arg.find(">", 0, 1) != -1 or arg.find("1>", 0, 2) != -1: + stdoutRedirected = True + # are there more possibilities to redirect stderr ? + if arg.find("2>", 0, 2) != -1: + stderrRedirected = True + + # redirect output of non-redirected streams to our tempfiles + if not stdoutRedirected: + args.append(">" + tmpFileStdoutName) + if not stderrRedirected: + args.append("2>" + tmpFileStderrName) + + # actually do the spawn + try: + args = [sh, '/C', escape(' '.join(args))] + ret = spawnve(os.P_WAIT, sh, args, env) + except OSError as e: + # catch any error try: - args = [sh, '/C', escape(' '.join(args))] - ret = spawnve(os.P_WAIT, sh, args, env) - except OSError as e: - # catch any error - try: - ret = exitvalmap[e.errno] - except KeyError: - sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e.errno, cmd, e.strerror)) - if stderr is not None: - stderr.write("scons: %s: %s\n" % (cmd, e.strerror)) - # copy child output from tempfiles to our streams - # and do clean up stuff - if stdout is not None and stdoutRedirected == 0: - try: - with open(tmpFileStdout, "r" ) as tmp: - stdout.write(tmp.read()) - os.remove(tmpFileStdout) - except (IOError, OSError): - pass + ret = exitvalmap[e.errno] + except KeyError: + sys.stderr.write("scons: unknown OSError exception code %d - %s: %s\n" % (e.errno, cmd, e.strerror)) + if stderr is not None: + stderr.write("scons: %s: %s\n" % (cmd, e.strerror)) - if stderr is not None and stderrRedirected == 0: - try: - with open(tmpFileStderr, "r" ) as tmp: - stderr.write(tmp.read()) - os.remove(tmpFileStderr) - except (IOError, OSError): - pass - return ret + # copy child output from tempfiles to our streams + # and do clean up stuff + if stdout is not None and not stdoutRedirected: + try: + with open(tmpFileStdoutName, "r") as tmpFileStdout: + stdout.write(tmpFileStdout.read()) + os.remove(tmpFileStdoutName) + except (IOError, OSError): + pass + + if stderr is not None and not stderrRedirected: + try: + with open(tmpFileStderrName, "r") as tmpFileStderr: + stderr.write(tmpFileStderr.read()) + os.remove(tmpFileStderrName) + except (IOError, OSError): + pass + + return ret def exec_spawn(l, env): diff --git a/src/engine/SCons/Platform/win32.xml b/src/engine/SCons/Platform/win32.xml index ca6dc4d..6face5f 100644 --- a/src/engine/SCons/Platform/win32.xml +++ b/src/engine/SCons/Platform/win32.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 71729c9..e706dae 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -270,7 +270,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): cached_error = False cachable = True for t in self.targets: - if T: Trace('%s' % (t)) + if T: Trace('%s' % t) bi = t.get_stored_info().binfo if isinstance(bi, SConfBuildInfo): if T: Trace(': SConfBuildInfo') @@ -280,7 +280,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): else: if T: Trace(': get_state() %s' % t.get_state()) if T: Trace(': changed() %s' % t.changed()) - if (t.get_state() != SCons.Node.up_to_date and t.changed()): + if t.get_state() != SCons.Node.up_to_date and t.changed(): changed = True if T: Trace(': changed %s' % changed) cached_error = cached_error or bi.result @@ -668,7 +668,7 @@ class SConfBase(object): is saved in self.lastTarget (for further processing). """ ok = self.TryLink(text, extension) - if( ok ): + if ok: prog = self.lastTarget pname = prog.get_internal_path() output = self.confdir.File(os.path.basename(pname)+'.out') @@ -866,9 +866,9 @@ class CheckContext(object): return self.sconf.TryRun(*args, **kw) def __getattr__( self, attr ): - if( attr == 'env' ): + if attr == 'env': return self.sconf.env - elif( attr == 'lastTarget' ): + elif attr == 'lastTarget': return self.sconf.lastTarget else: raise AttributeError("CheckContext instance has no attribute '%s'" % attr) @@ -1067,7 +1067,7 @@ def CheckLibWithHeader(context, libs, header, language, """ prog_prefix, dummy = \ createIncludesFromHeaders(header, 0) - if libs == []: + if not libs: libs = [None] if not SCons.Util.is_List(libs): diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index f770450..c5d1fbd 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -56,6 +56,18 @@ class SConfTestCase(unittest.TestCase): os.chdir(self.save_cwd) def _resetSConfState(self): + if sys.platform in ['cygwin', 'win32'] and sys.version_info.major == 2: + # On Windows with Python2, SCons.Platform.win32 redefines the + # built-in file() and open() functions to disable handle + # inheritance. Because we are unloading all SCons modules other + # than SCons.Compat, SCons.Platform.win32 will lose the variables + # it needs. As a result, we should reset the file() and open() + # functions to their original built-in versions. + import __builtin__ + import SCons.Platform.win32 + __builtin__.file = SCons.Platform.win32._builtin_file + __builtin__.open = SCons.Platform.win32._builtin_open + # Ok, this is tricky, and i do not know, if everything is sane. # We try to reset scons' state (including all global variables) import SCons.SConsign @@ -90,22 +102,6 @@ class SConfTestCase(unittest.TestCase): global existing_lib existing_lib = 'm' - if sys.platform in ['cygwin', 'win32']: - # On Windows, SCons.Platform.win32 redefines the builtin - # file() and open() functions to close the file handles. - # This interferes with the unittest.py infrastructure in - # some way. Just sidestep the issue by restoring the - # original builtin functions whenever we have to reset - # all of our global state. - - import SCons.Platform.win32 - - try: - file = SCons.Platform.win32._builtin_file - open = SCons.Platform.win32._builtin_open - except AttributeError: - pass - def _baseTryXXX(self, TryFunc): # TryCompile and TryLink are much the same, so we can test them # in one method, we pass the function as a string ('TryCompile', @@ -155,7 +151,7 @@ class SConfTestCase(unittest.TestCase): log_file=self.test.workpath('config.log')) no_std_header_h = self.test.workpath('config.tests', 'no_std_header.h') test_h = self.test.write( no_std_header_h, - "/* we are changing a dependency now */\n" ); + "/* we are changing a dependency now */\n" ) try: res = checks( self, sconf, TryFunc ) log = self.test.read( self.test.workpath('config.log') ) diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py index 64a2345..abe4042 100644 --- a/src/engine/SCons/Scanner/ScannerTests.py +++ b/src/engine/SCons/Scanner/ScannerTests.py @@ -236,7 +236,7 @@ class BaseTestCase(unittest.TestCase): def test___cmp__(self): """Test the Scanner.Base class __cmp__() method""" s = SCons.Scanner.Base(self.func, "Cmp") - assert s != None + assert s is not None def test_hash(self): """Test the Scanner.Base class __hash__() method""" @@ -578,8 +578,6 @@ class ClassicTestCase(unittest.TestCase): "recursive = 1 didn't return all nodes: %s" % n) - - class ClassicCPPTestCase(unittest.TestCase): def test_find_include(self): """Test the Scanner.ClassicCPP find_include() method""" diff --git a/src/engine/SCons/Scanner/__init__.xml b/src/engine/SCons/Scanner/__init__.xml index 470e045..a79d336 100644 --- a/src/engine/SCons/Scanner/__init__.xml +++ b/src/engine/SCons/Scanner/__init__.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 58dbf64..f9c8384 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -211,10 +211,9 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): last_command_end = finish_time cumulative_command_time = cumulative_command_time+finish_time-start_time if print_action_timestamps: - sys.stdout.write("Command execution start time: %s: %f seconds\n"%(str(self.node), start_time)) + sys.stdout.write("Command execution start timestamp: %s: %f\n"%(str(self.node), start_time)) + sys.stdout.write("Command execution end timestamp: %s: %f\n"%(str(self.node), finish_time)) sys.stdout.write("Command execution time: %s: %f seconds\n"%(str(self.node), finish_time-start_time)) - if print_action_timestamps: - sys.stdout.write("Command execution stop time: %s: %f seconds\n"%(str(self.node), finish_time)) def do_failed(self, status=2): _BuildFailures.append(self.exception[1]) @@ -356,7 +355,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): display("Removed directory " + pathstr) else: errstr = "Path '%s' exists but isn't a file or directory." - raise SCons.Errors.UserError(errstr % (pathstr)) + raise SCons.Errors.UserError(errstr % pathstr) except SCons.Errors.UserError as e: print(e) except (IOError, OSError) as e: @@ -679,7 +678,7 @@ def _set_debug_values(options): options.tree_printers.append(TreePrinter(status=True)) if "time" in debug_values: print_time = 1 - if "action_timestamps" in debug_values: + if "action-timestamps" in debug_values: print_time = 1 print_action_timestamps = 1 if "tree" in debug_values: diff --git a/src/engine/SCons/Script/Main.xml b/src/engine/SCons/Script/Main.xml index e95afbc..5c68dee 100644 --- a/src/engine/SCons/Script/Main.xml +++ b/src/engine/SCons/Script/Main.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ @@ -33,11 +33,11 @@ See its __doc__ string for a discussion of the format. This function adds a new command-line option to be recognized. The specified <varname>arguments</varname> -are the same as supported by the standard Python -<function>optparse.add_option</function>() -method (with a few additional capabilities noted below); +are the same as supported by the <function>add_option</function> +method in the standard Python library module <emphasis>optparse</emphasis>, +with a few additional capabilities noted below; see the documentation for -<literal>optparse</literal> +<emphasis>optparse</emphasis> for a thorough discussion of its option-processing capabities. </para> @@ -78,12 +78,22 @@ the option will have a default value of </para> <para> +Unlike regular <emphasis>optparse</emphasis>, option names +added via <function>AddOption</function> must be matched +exactly, the automatic matching of abbreviations on the +command line for long options is not supported. +To allow specific abbreviations, +include them in the &f-AddOption; call. +</para> + +<para> Once a new command-line option has been added with &f-AddOption;, the option value may be accessed using &f-GetOption; or <function>env.GetOption</function>(). +<!-- The value may also be set, using &f-SetOption; or @@ -95,6 +105,9 @@ Note, however, that a value specified on the command line will <emphasis>always</emphasis> override a value set by any SConscript file. +--> +&f-SetOption; is not currently supported for +options added with &f-AddOption;. </para> <para> @@ -133,6 +146,22 @@ AddOption('--prefix', help='installation prefix') env = Environment(PREFIX = GetOption('prefix')) </example_commands> + +<note> +<para> +While &AddOption; behaves like +<function>add_option</function>, +from the <emphasis>optparse</emphasis> module, +the behavior of options added by &AddOption; +which take arguments is underfined in +<command>scons</command> if whitespace +(rather than an <literal>=</literal> sign) is used as +the separator on the command line when +the option is invoked. +Such usage should be avoided. +</para> +</note> + </summary> </scons_function> diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 7b5d523..8ec8ccf 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -28,7 +28,7 @@ import re import sys import textwrap -no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') +no_hyphen_re = re.compile(r'(\s+|(?<=[\w!\"\'&.,?])-{2,}(?=\w))') try: from gettext import gettext @@ -622,7 +622,7 @@ def Parser(version): debug_options = ["count", "duplicate", "explain", "findlibs", "includes", "memoizer", "memory", "objects", "pdb", "prepare", "presub", "stacktrace", - "time", "action_timestamps"] + "time", "action-timestamps"] def opt_debug(option, opt, value__, parser, debug_options=debug_options, diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index eabaddb..0298a69 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -42,7 +42,7 @@ import SCons.Platform import SCons.SConf import SCons.Script.Main import SCons.Tool -import SCons.Util +from SCons.Util import is_List, is_String, is_Dict, flatten from . import Main @@ -98,7 +98,7 @@ def compute_exports(exports): retval = {} try: for export in exports: - if SCons.Util.is_Dict(export): + if is_Dict(export): retval.update(export) else: try: @@ -133,7 +133,7 @@ call_stack = [] def Return(*vars, **kw): retval = [] try: - fvars = SCons.Util.flatten(vars) + fvars = flatten(vars) for var in fvars: for v in var.split(): retval.append(call_stack[-1].globals[v]) @@ -420,7 +420,7 @@ class SConsEnvironment(SCons.Environment.Base): except KeyError: raise SCons.Errors.UserError("Invalid SConscript usage - no parameters") - if not SCons.Util.is_List(dirs): + if not is_List(dirs): dirs = [ dirs ] dirs = list(map(str, dirs)) @@ -441,13 +441,13 @@ class SConsEnvironment(SCons.Environment.Base): raise SCons.Errors.UserError("Invalid SConscript() usage - too many arguments") - if not SCons.Util.is_List(files): + if not is_List(files): files = [ files ] if kw.get('exports'): exports.extend(self.Split(kw['exports'])) - variant_dir = kw.get('variant_dir') or kw.get('build_dir') + variant_dir = kw.get('variant_dir') if variant_dir: if len(files) != 1: raise SCons.Errors.UserError("Invalid SConscript() usage - can only specify one SConscript with a variant_dir") @@ -577,9 +577,6 @@ class SConsEnvironment(SCons.Environment.Base): UserError: a script is not found and such exceptions are enabled. """ - if 'build_dir' in kw: - msg = """The build_dir keyword has been deprecated; use the variant_dir keyword instead.""" - SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg) def subst_element(x, subst=self.subst): if SCons.Util.is_List(x): x = list(map(subst, x)) @@ -589,15 +586,10 @@ class SConsEnvironment(SCons.Environment.Base): ls = list(map(subst_element, ls)) subst_kw = {} for key, val in kw.items(): - if SCons.Util.is_String(val): + if is_String(val): val = self.subst(val) elif SCons.Util.is_List(val): - result = [] - for v in val: - if SCons.Util.is_String(v): - v = self.subst(v) - result.append(v) - val = result + val = [self.subst(v) if is_String(v) else v for v in val] subst_kw[key] = val files, exports = self._get_SConscript_filenames(ls, subst_kw) diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml index 330a56c..a1e0129 100644 --- a/src/engine/SCons/Script/SConscript.xml +++ b/src/engine/SCons/Script/SConscript.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ @@ -252,16 +252,16 @@ This specifies help text to be printed if the <option>-h</option> 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 <option>-h</option> message. </para> @@ -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: </para> <example_commands> diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 24af73e..8f526be 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -314,7 +314,6 @@ GlobalDefaultEnvironmentFunctions = [ 'AddPreAction', 'Alias', 'AlwaysBuild', - 'BuildDir', 'CacheDir', 'Clean', #The Command() method is handled separately, below. @@ -345,7 +344,6 @@ GlobalDefaultEnvironmentFunctions = [ 'Requires', 'SConsignFile', 'SideEffect', - 'SourceCode', 'Split', 'Tag', 'Value', diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 2de64c5..a1ef053 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -331,6 +331,399 @@ def subst_dict(target, source): return dict + +class StringSubber(object): + """A class to construct the results of a scons_subst() call. + + This binds a specific construction environment, mode, target and + source with two methods (substitute() and expand()) that handle + the expansion. + """ + def __init__(self, env, mode, conv, gvars): + self.env = env + self.mode = mode + self.conv = conv + self.gvars = gvars + + def expand(self, s, lvars): + """Expand a single "token" as necessary, returning an + appropriate string containing the expansion. + + This handles expanding different types of things (strings, + lists, callables) appropriately. It calls the wrapper + substitute() method to re-expand things as necessary, so that + the results of expansions of side-by-side strings still get + re-evaluated separately, not smushed together. + """ + if is_String(s): + try: + s0, s1 = s[:2] + except (IndexError, ValueError): + return s + if s0 != '$': + return s + if s1 == '$': + # In this case keep the double $'s which we'll later + # swap for a single dollar sign as we need to retain + # this information to properly avoid matching "$("" when + # the actual text was "$$("" (or "$)"" when "$$)"" ) + return '$$' + elif s1 in '()': + return s + else: + key = s[1:] + if key[0] == '{' or '.' in key: + 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] + elif key in self.gvars: + s = self.gvars[key] + else: + 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'], old_s) + + if s is None and NameError not in AllowableExceptions: + raise_exception(NameError(key), lvars['TARGETS'], old_s) + elif s is None: + return '' + + # Before re-expanding the result, handle + # recursive expansion by copying the local + # variable dictionary and overwriting a null + # string for the value of the variable name + # we just expanded. + # + # This could potentially be optimized by only + # copying lvars when s contains more expansions, + # but lvars is usually supposed to be pretty + # small, and deeply nested variable expansions + # are probably more the exception than the norm, + # so it should be tolerable for now. + lv = lvars.copy() + var = key.split('.')[0] + lv[var] = '' + return self.substitute(s, lv) + elif is_Sequence(s): + def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): + return conv(substitute(l, lvars)) + return list(map(func, s)) + elif callable(s): + try: + s = s(target=lvars['TARGETS'], + source=lvars['SOURCES'], + env=self.env, + for_signature=(self.mode != SUBST_CMD)) + except TypeError: + # This probably indicates that it's a callable + # object that doesn't match our calling arguments + # (like an Action). + if self.mode == SUBST_RAW: + return s + s = self.conv(s) + return self.substitute(s, lvars) + elif s is None: + return '' + else: + return s + + def substitute(self, args, lvars): + """Substitute expansions in an argument or list of arguments. + + This serves as a wrapper for splitting up a string into + separate tokens. + """ + if is_String(args) and not isinstance(args, CmdStringHolder): + args = str(args) # In case it's a UserString. + try: + def sub_match(match): + return self.conv(self.expand(match.group(1), lvars)) + result = _dollar_exps.sub(sub_match, args) + except TypeError: + # If the internal conversion routine doesn't return + # strings (it could be overridden to return Nodes, for + # example), then the 1.5.2 re module will throw this + # exception. Back off to a slower, general-purpose + # algorithm that works for all data types. + args = _separate_args.findall(args) + result = [] + for a in args: + result.append(self.conv(self.expand(a, lvars))) + if len(result) == 1: + result = result[0] + else: + result = ''.join(map(str, result)) + return result + else: + return self.expand(args, lvars) + + +class ListSubber(collections.UserList): + """A class to construct the results of a scons_subst_list() call. + + Like StringSubber, this class binds a specific construction + environment, mode, target and source with two methods + (substitute() and expand()) that handle the expansion. + + In addition, however, this class is used to track the state of + the result(s) we're gathering so we can do the appropriate thing + whenever we have to append another word to the result--start a new + line, start a new word, append to the current word, etc. We do + this by setting the "append" attribute to the right method so + that our wrapper methods only need ever call ListSubber.append(), + and the rest of the object takes care of doing the right thing + internally. + """ + def __init__(self, env, mode, conv, gvars): + collections.UserList.__init__(self, []) + self.env = env + self.mode = mode + self.conv = conv + self.gvars = gvars + + if self.mode == SUBST_RAW: + self.add_strip = lambda x: self.append(x) + else: + self.add_strip = lambda x: None + self.in_strip = None + 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 + + 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 + expansion to the current result. + + This handles expanding different types of things (strings, + lists, callables) appropriately. It calls the wrapper + substitute() method to re-expand things as necessary, so that + the results of expansions of side-by-side strings still get + re-evaluated separately, not smushed together. + """ + + if is_String(s): + try: + s0, s1 = s[:2] + except (IndexError, ValueError): + self.append(s) + return + if s0 != '$': + self.append(s) + return + if s1 == '$': + self.append('$') + elif s1 == '(': + self.open_strip('$(') + elif s1 == ')': + self.close_strip('$)') + else: + key = s[1:] + if key[0] == '{' or key.find('.') >= 0: + 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] + elif key in self.gvars: + s = self.gvars[key] + else: + 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'], old_s) + + if s is None and NameError not in AllowableExceptions: + raise_exception(NameError(), lvars['TARGETS'], old_s) + 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 + + # Before re-expanding the result, handle + # recursive expansion by copying the local + # variable dictionary and overwriting a null + # string for the value of the variable name + # we just expanded. + lv = lvars.copy() + var = key.split('.')[0] + lv[var] = '' + self.substitute(s, lv, 0) + self.this_word() + elif is_Sequence(s): + for a in s: + self.substitute(a, lvars, 1) + self.next_word() + elif callable(s): + try: + s = s(target=lvars['TARGETS'], + source=lvars['SOURCES'], + env=self.env, + for_signature=(self.mode != SUBST_CMD)) + except TypeError: + # This probably indicates that it's a callable + # object that doesn't match our calling arguments + # (like an Action). + if self.mode == SUBST_RAW: + self.append(s) + return + s = self.conv(s) + self.substitute(s, lvars, within_list) + elif s is None: + self.this_word() + else: + self.append(s) + + def substitute(self, args, lvars, within_list): + """Substitute expansions in an argument or list of arguments. + + This serves as a wrapper for splitting up a string into + separate tokens. + """ + + if is_String(args) and not isinstance(args, CmdStringHolder): + args = str(args) # In case it's a UserString. + args = _separate_args.findall(args) + for a in args: + if a[0] in ' \t\n\r\f\v': + if '\n' in a: + self.next_line() + elif within_list: + self.append(a) + else: + self.next_word() + else: + self.expand(a, lvars, within_list) + else: + self.expand(args, lvars, within_list) + + def next_line(self): + """Arrange for the next word to start a new line. This + is like starting a new word, except that we have to append + another line to the result.""" + collections.UserList.append(self, []) + self.next_word() + + def this_word(self): + """Arrange for the next word to append to the end of the + current last word in the result.""" + self.append = self.add_to_current_word + + def next_word(self): + """Arrange for the next word to start a new word.""" + self.append = self.add_new_word + + def add_to_current_word(self, x): + """Append the string x to the end of the current last word + in the result. If that is not possible, then just add + it as a new word. Make sure the entire concatenated string + inherits the object attributes of x (in particular, the + escape function) by wrapping it as CmdStringHolder.""" + + if not self.in_strip or self.mode != SUBST_SIG: + try: + current_word = self[-1][-1] + except IndexError: + self.add_new_word(x) + else: + # All right, this is a hack and it should probably + # be refactored out of existence in the future. + # The issue is that we want to smoosh words together + # and make one file name that gets escaped if + # we're expanding something like foo$EXTENSION, + # but we don't want to smoosh them together if + # it's something like >$TARGET, because then we'll + # treat the '>' like it's part of the file name. + # So for now, just hard-code looking for the special + # command-line redirection characters... + try: + last_char = str(current_word)[-1] + except IndexError: + last_char = '\0' + if last_char in '<>|': + self.add_new_word(x) + else: + y = current_word + x + + # We used to treat a word appended to a literal + # as a literal itself, but this caused problems + # with interpreting quotes around space-separated + # targets on command lines. Removing this makes + # none of the "substantive" end-to-end tests fail, + # so we'll take this out but leave it commented + # for now in case there's a problem not covered + # by the test cases and we need to resurrect this. + #literal1 = self.literal(self[-1][-1]) + #literal2 = self.literal(x) + y = self.conv(y) + if is_String(y): + #y = CmdStringHolder(y, literal1 or literal2) + y = CmdStringHolder(y, None) + self[-1][-1] = y + + def add_new_word(self, x): + if not self.in_strip or self.mode != SUBST_SIG: + literal = self.literal(x) + x = self.conv(x) + if is_String(x): + x = CmdStringHolder(x, literal) + self[-1].append(x) + self.append = self.add_to_current_word + + def literal(self, x): + try: + l = x.is_literal + except AttributeError: + return None + else: + return l() + + def open_strip(self, x): + """Handle the "open strip" $( token.""" + self.add_strip(x) + self.in_strip = 1 + + def close_strip(self, x): + """Handle the "close strip" $) token.""" + self.add_strip(x) + self.in_strip = None + + # Constants for the "mode" parameter to scons_subst_list() and # scons_subst(). SUBST_RAW gives the raw command line. SUBST_CMD # gives a command line suitable for passing to a shell. SUBST_SIG @@ -394,7 +787,7 @@ _list_remove = [ _rm_list, None, _remove_list ] # _dollar_exps_str = r'\$[\$\(\)]|\$[_a-zA-Z][\.\w]*|\${[^}]*}' _dollar_exps = re.compile(r'(%s)' % _dollar_exps_str) -_separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str) +_separate_args = re.compile(r'(%s|\s+|[^\s$]+|\$)' % _dollar_exps_str) # This regular expression is used to replace strings of multiple white # space characters in the string result from the scons_subst() function. @@ -412,136 +805,6 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ if (isinstance(strSubst, str) and '$' not in strSubst) or isinstance(strSubst, CmdStringHolder): return strSubst - class StringSubber(object): - """A class to construct the results of a scons_subst() call. - - This binds a specific construction environment, mode, target and - source with two methods (substitute() and expand()) that handle - the expansion. - """ - def __init__(self, env, mode, conv, gvars): - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - def expand(self, s, lvars): - """Expand a single "token" as necessary, returning an - appropriate string containing the expansion. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - return s - if s0 != '$': - return s - if s1 == '$': - # In this case keep the double $'s which we'll later - # swap for a single dollar sign as we need to retain - # this information to properly avoid matching "$("" when - # the actual text was "$$("" (or "$)"" when "$$)"" ) - return '$$' - elif s1 in '()': - return s - else: - key = s[1:] - 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) - 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 '' - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - # - # This could potentially be optimized by only - # copying lvars when s contains more expansions, - # but lvars is usually supposed to be pretty - # small, and deeply nested variable expansions - # are probably more the exception than the norm, - # so it should be tolerable for now. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - return self.substitute(s, lv) - elif is_Sequence(s): - def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): - return conv(substitute(l, lvars)) - return list(map(func, s)) - elif callable(s): - try: - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - except TypeError: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - return s - s = self.conv(s) - return self.substitute(s, lvars) - elif s is None: - return '' - else: - return s - - def substitute(self, args, lvars): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - separate tokens. - """ - if is_String(args) and not isinstance(args, CmdStringHolder): - args = str(args) # In case it's a UserString. - try: - def sub_match(match): - return self.conv(self.expand(match.group(1), lvars)) - result = _dollar_exps.sub(sub_match, args) - except TypeError: - # If the internal conversion routine doesn't return - # strings (it could be overridden to return Nodes, for - # example), then the 1.5.2 re module will throw this - # exception. Back off to a slower, general-purpose - # algorithm that works for all data types. - args = _separate_args.findall(args) - result = [] - for a in args: - result.append(self.conv(self.expand(a, lvars))) - if len(result) == 1: - result = result[0] - else: - result = ''.join(map(str, result)) - return result - else: - return self.expand(args, lvars) - if conv is None: conv = _strconv[mode] @@ -615,234 +878,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv The companion scons_subst() function (above) handles basic substitutions within strings, so see that function instead if that's what you're looking for. - """ - class ListSubber(collections.UserList): - """A class to construct the results of a scons_subst_list() call. - - Like StringSubber, this class binds a specific construction - environment, mode, target and source with two methods - (substitute() and expand()) that handle the expansion. - - In addition, however, this class is used to track the state of - the result(s) we're gathering so we can do the appropriate thing - whenever we have to append another word to the result--start a new - line, start a new word, append to the current word, etc. We do - this by setting the "append" attribute to the right method so - that our wrapper methods only need ever call ListSubber.append(), - and the rest of the object takes care of doing the right thing - internally. - """ - def __init__(self, env, mode, conv, gvars): - collections.UserList.__init__(self, []) - self.env = env - self.mode = mode - self.conv = conv - self.gvars = gvars - - if self.mode == SUBST_RAW: - self.add_strip = lambda x: self.append(x) - else: - self.add_strip = lambda x: None - self.in_strip = None - self.next_line() - - def expand(self, s, lvars, within_list): - """Expand a single "token" as necessary, appending the - expansion to the current result. - - This handles expanding different types of things (strings, - lists, callables) appropriately. It calls the wrapper - substitute() method to re-expand things as necessary, so that - the results of expansions of side-by-side strings still get - re-evaluated separately, not smushed together. - """ - - if is_String(s): - try: - s0, s1 = s[:2] - except (IndexError, ValueError): - self.append(s) - return - if s0 != '$': - self.append(s) - return - if s1 == '$': - self.append('$') - elif s1 == '(': - self.open_strip('$(') - elif s1 == ')': - self.close_strip('$)') - else: - key = s[1:] - 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) - 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 - - # Before re-expanding the result, handle - # recursive expansion by copying the local - # variable dictionary and overwriting a null - # string for the value of the variable name - # we just expanded. - lv = lvars.copy() - var = key.split('.')[0] - lv[var] = '' - self.substitute(s, lv, 0) - self.this_word() - elif is_Sequence(s): - for a in s: - self.substitute(a, lvars, 1) - self.next_word() - elif callable(s): - try: - s = s(target=lvars['TARGETS'], - source=lvars['SOURCES'], - env=self.env, - for_signature=(self.mode != SUBST_CMD)) - except TypeError: - # This probably indicates that it's a callable - # object that doesn't match our calling arguments - # (like an Action). - if self.mode == SUBST_RAW: - self.append(s) - return - s = self.conv(s) - self.substitute(s, lvars, within_list) - elif s is None: - self.this_word() - else: - self.append(s) - - def substitute(self, args, lvars, within_list): - """Substitute expansions in an argument or list of arguments. - - This serves as a wrapper for splitting up a string into - separate tokens. - """ - - if is_String(args) and not isinstance(args, CmdStringHolder): - args = str(args) # In case it's a UserString. - args = _separate_args.findall(args) - for a in args: - if a[0] in ' \t\n\r\f\v': - if '\n' in a: - self.next_line() - elif within_list: - self.append(a) - else: - self.next_word() - else: - self.expand(a, lvars, within_list) - else: - self.expand(args, lvars, within_list) - - def next_line(self): - """Arrange for the next word to start a new line. This - is like starting a new word, except that we have to append - another line to the result.""" - collections.UserList.append(self, []) - self.next_word() - - def this_word(self): - """Arrange for the next word to append to the end of the - current last word in the result.""" - self.append = self.add_to_current_word - - def next_word(self): - """Arrange for the next word to start a new word.""" - self.append = self.add_new_word - - def add_to_current_word(self, x): - """Append the string x to the end of the current last word - in the result. If that is not possible, then just add - it as a new word. Make sure the entire concatenated string - inherits the object attributes of x (in particular, the - escape function) by wrapping it as CmdStringHolder.""" - - if not self.in_strip or self.mode != SUBST_SIG: - try: - current_word = self[-1][-1] - except IndexError: - self.add_new_word(x) - else: - # All right, this is a hack and it should probably - # be refactored out of existence in the future. - # The issue is that we want to smoosh words together - # and make one file name that gets escaped if - # we're expanding something like foo$EXTENSION, - # but we don't want to smoosh them together if - # it's something like >$TARGET, because then we'll - # treat the '>' like it's part of the file name. - # So for now, just hard-code looking for the special - # command-line redirection characters... - try: - last_char = str(current_word)[-1] - except IndexError: - last_char = '\0' - if last_char in '<>|': - self.add_new_word(x) - else: - y = current_word + x - - # We used to treat a word appended to a literal - # as a literal itself, but this caused problems - # with interpreting quotes around space-separated - # targets on command lines. Removing this makes - # none of the "substantive" end-to-end tests fail, - # so we'll take this out but leave it commented - # for now in case there's a problem not covered - # by the test cases and we need to resurrect this. - #literal1 = self.literal(self[-1][-1]) - #literal2 = self.literal(x) - y = self.conv(y) - if is_String(y): - #y = CmdStringHolder(y, literal1 or literal2) - y = CmdStringHolder(y, None) - self[-1][-1] = y - - def add_new_word(self, x): - if not self.in_strip or self.mode != SUBST_SIG: - literal = self.literal(x) - x = self.conv(x) - if is_String(x): - x = CmdStringHolder(x, literal) - self[-1].append(x) - self.append = self.add_to_current_word - - def literal(self, x): - try: - l = x.is_literal - except AttributeError: - return None - else: - return l() - - def open_strip(self, x): - """Handle the "open strip" $( token.""" - self.add_strip(x) - self.in_strip = 1 - - def close_strip(self, x): - """Handle the "close strip" $) token.""" - self.add_strip(x) - self.in_strip = None - + """ if conv is None: conv = _strconv[mode] diff --git a/src/engine/SCons/Subst.xml b/src/engine/SCons/Subst.xml index e9ec599..980a9ad 100644 --- a/src/engine/SCons/Subst.xml +++ b/src/engine/SCons/Subst.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py index f6fe1ec..c25b377 100644 --- a/src/engine/SCons/SubstTests.py +++ b/src/engine/SCons/SubstTests.py @@ -133,8 +133,8 @@ class SubstTestCase(unittest.TestCase): return self.value # only use of this is currently commented out below - def function_foo(arg): - pass + #def function_foo(arg): + # pass target = [ MyNode("./foo/bar.exe"), MyNode("/bar/baz with spaces.obj"), @@ -207,7 +207,7 @@ class SubstTestCase(unittest.TestCase): 'S' : 'x y', 'LS' : ['x y'], 'L' : ['x', 'y'], - 'TS' : ('x y'), + 'TS' : ('x y',), 'T' : ('x', 'y'), 'CS' : cs, 'CL' : cl, diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 4892026..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(SCons.Util.UnicodeType('\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() @@ -874,8 +874,10 @@ class Taskmaster(object): # These nodes have not even been visited yet. Add # them to the list so that on some next pass we can # take a stab at evaluating them (or their children). - children_not_visited.reverse() - self.candidates.extend(self.order(children_not_visited)) + if children_not_visited: + if len(children_not_visited) > 1: + children_not_visited.reverse() + self.candidates.extend(self.order(children_not_visited)) # if T and children_not_visited: # T.write(self.trace_message(' adding to candidates: %s' % map(str, children_not_visited))) diff --git a/src/engine/SCons/Tool/386asm.xml b/src/engine/SCons/Tool/386asm.xml index c592ed8..4c8d5a5 100644 --- a/src/engine/SCons/Tool/386asm.xml +++ b/src/engine/SCons/Tool/386asm.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml index 8c8c1b5..7cc47da 100644 --- a/src/engine/SCons/Tool/DCommon.xml +++ b/src/engine/SCons/Tool/DCommon.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py index a7e247d..1711de1 100644 --- a/src/engine/SCons/Tool/JavaCommon.py +++ b/src/engine/SCons/Tool/JavaCommon.py @@ -40,7 +40,7 @@ default_java_version = '1.4' # a switch for which jdk versions to use the Scope state for smarter # anonymous inner class parsing. -scopeStateVersions = ('1.8') +scopeStateVersions = ('1.8',) # Glob patterns for use in finding where the JDK is. # These are pairs, *dir_glob used in the general case, @@ -87,8 +87,8 @@ if java_parsing: # any alphanumeric token surrounded by angle brackets (generics); # the multi-line comment begin and end tokens /* and */; # array declarations "[]". - _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' + - r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' + + _reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"{\};.()]|' + + r'\d*\.\d*|[A-Za-z_][\w$.]*|<[A-Za-z_]\w+>|' + r'/\*|\*/|\[\])') diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index bbccf61..386f445 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -50,7 +50,7 @@ elif LOGFILE: level=logging.DEBUG) debug = logging.getLogger(name=__name__).debug else: - debug = lambda x: None + def debug(x): return None # SCONS_CACHE_MSVC_CONFIG is public, and is documented. @@ -58,6 +58,7 @@ CONFIG_CACHE = os.environ.get('SCONS_CACHE_MSVC_CONFIG') if CONFIG_CACHE in ('1', 'true', 'True'): CONFIG_CACHE = os.path.join(os.path.expanduser('~'), '.scons_msvc_cache') + def read_script_env_cache(): """ fetch cached msvc env vars if requested, else return empty dict """ envcache = {} @@ -65,7 +66,7 @@ def read_script_env_cache(): try: with open(CONFIG_CACHE, 'r') as f: envcache = json.load(f) - #TODO can use more specific FileNotFoundError when py2 dropped + # TODO can use more specific FileNotFoundError when py2 dropped except IOError: # don't fail if no cache file, just proceed without it pass @@ -88,6 +89,7 @@ def write_script_env_cache(cache): _is_win64 = None + def is_win64(): """Return true if running on windows 64 bits. @@ -122,6 +124,7 @@ def is_win64(): def read_reg(value, hkroot=SCons.Util.HKEY_LOCAL_MACHINE): return SCons.Util.RegGetValue(hkroot, value)[0] + def has_reg(value): """Return True if the given key exists in HKEY_LOCAL_MACHINE, False otherwise.""" @@ -134,6 +137,7 @@ def has_reg(value): # Functions for fetching environment variable settings from batch files. + def normalize_env(env, keys, force=False): """Given a dictionary representing a shell environment, add the variables from os.environ needed for the processing of .bat files; the keys are @@ -172,11 +176,12 @@ def normalize_env(env, keys, force=False): if sys32_wbem_dir not in normenv['PATH']: normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir - debug("PATH: %s"%normenv['PATH']) + debug("PATH: %s" % normenv['PATH']) return normenv -def get_output(vcbat, args = None, env = None): + +def get_output(vcbat, args=None, env=None): """Parse the output of given bat file, with given args.""" if env is None: @@ -242,7 +247,13 @@ def get_output(vcbat, args = None, env = None): output = stdout.decode("mbcs") return output -KEEPLIST = ("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat') + +KEEPLIST = ("INCLUDE", "LIB", "LIBPATH", "PATH", 'VSCMD_ARG_app_plat', + 'VCINSTALLDIR', # needed by clang -VS 2017 and newer + 'VCToolsInstallDir', # needed by clang - VS 2015 and older + ) + + def parse_output(output, keep=KEEPLIST): """ Parse output from running visual c++/studios vcvarsall.bat and running set diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py index 281c1e3..9627f17 100644 --- a/src/engine/SCons/Tool/MSCommon/sdk.py +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -110,12 +110,12 @@ class SDKDefinition(object): """ Return the script to initialize the VC compiler installed by SDK """ - if (host_arch == 'amd64' and target_arch == 'x86'): + if host_arch == 'amd64' and target_arch == 'x86': # No cross tools needed compiling 32 bits on 64 bit machine host_arch=target_arch arch_string=target_arch - if (host_arch != target_arch): + if host_arch != target_arch: arch_string='%s_%s'%(host_arch,target_arch) debug("get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string, diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 4f6048d..6f9bd12 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -161,11 +161,18 @@ def get_host_target(env): if not host_platform: host_platform = platform.machine() + # Solaris returns i86pc for both 32 and 64 bit architectures + if host_platform == "i86pc": + if platform.architecture()[0] == "64bit": + host_platform = "amd64" + else: + host_platform = "x86" + # Retain user requested TARGET_ARCH req_target_platform = env.get('TARGET_ARCH') debug('get_host_target() req_target_platform:%s'%req_target_platform) - if req_target_platform: + if req_target_platform: # If user requested a specific platform then only try that one. target_platform = req_target_platform else: @@ -502,7 +509,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version): debug('_check_cl_exists_in_vc_dir(): found ' + _CL_EXE_NAME + '!') return True - elif ver_num <= 14 and ver_num >= 8: + elif 14 >= ver_num >= 8: # Set default value to be -1 as "" which is the value for x86/x86 yields true when tested # if not host_trgt_dir @@ -534,7 +541,7 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version): debug('_check_cl_exists_in_vc_dir(): found ' + _CL_EXE_NAME + '!') return True - elif ver_num < 8 and ver_num >= 6: + elif 8 > ver_num >= 6: # not sure about these versions so if a walk the VC dir (could be slow) for root, _, files in os.walk(vc_dir): if _CL_EXE_NAME in files: @@ -759,12 +766,12 @@ def msvc_find_valid_batch_script(env, version): vc_script=None continue if not vc_script and sdk_script: - debug('msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script)) + debug('msvc_find_valid_batch_script() use_script 4: trying sdk script: %s' % sdk_script) try: d = script_env(sdk_script) found = sdk_script except BatchFileExecutionError as e: - debug('msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e)) + debug('msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script), e)) continue elif not vc_script and not sdk_script: debug('msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found') diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index f255b21..14306ab 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -774,11 +774,11 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw): for link, linktgt in symlinks: env.SideEffect(link, linktgt) - if (Verbose): + if Verbose: print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path())) clean_list = [x for x in nodes if x != linktgt] env.Clean(list(set([linktgt] + clean_targets)), clean_list) - if (Verbose): + if Verbose: print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list])) @@ -792,18 +792,18 @@ def CreateLibSymlinks(env, symlinks): for link, linktgt in symlinks: linktgt = link.get_dir().rel_path(linktgt) link = link.get_path() - if (Verbose): + if Verbose: print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt)) # Delete the (previously created) symlink if exists. Let only symlinks # to be deleted to prevent accidental deletion of source files... if env.fs.islink(link): env.fs.unlink(link) - if (Verbose): + if Verbose: print("CreateLibSymlinks: removed old symlink %r" % link) # If a file or directory exists with the same name as link, an OSError # will be thrown, which should be enough, I think. env.fs.symlink(linktgt, link) - if (Verbose): + if Verbose: print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt)) return 0 diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml index b6e5a43..b00e24e 100644 --- a/src/engine/SCons/Tool/__init__.xml +++ b/src/engine/SCons/Tool/__init__.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/aixc++.xml b/src/engine/SCons/Tool/aixc++.xml index 3aa891a..bbbf4b9 100644 --- a/src/engine/SCons/Tool/aixc++.xml +++ b/src/engine/SCons/Tool/aixc++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/aixcc.xml b/src/engine/SCons/Tool/aixcc.xml index 11a4ce3..f017e5a 100644 --- a/src/engine/SCons/Tool/aixcc.xml +++ b/src/engine/SCons/Tool/aixcc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/aixf77.xml b/src/engine/SCons/Tool/aixf77.xml index 46e241e..e869625 100644 --- a/src/engine/SCons/Tool/aixf77.xml +++ b/src/engine/SCons/Tool/aixf77.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/aixlink.xml b/src/engine/SCons/Tool/aixlink.xml index 23288e9..bf003ce 100644 --- a/src/engine/SCons/Tool/aixlink.xml +++ b/src/engine/SCons/Tool/aixlink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/applelink.xml b/src/engine/SCons/Tool/applelink.xml index 2856e06..fc0cf63 100644 --- a/src/engine/SCons/Tool/applelink.xml +++ b/src/engine/SCons/Tool/applelink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ar.xml b/src/engine/SCons/Tool/ar.xml index 5d4becb..6731397 100644 --- a/src/engine/SCons/Tool/ar.xml +++ b/src/engine/SCons/Tool/ar.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/as.xml b/src/engine/SCons/Tool/as.xml index 7661a29..7c964a9 100644 --- a/src/engine/SCons/Tool/as.xml +++ b/src/engine/SCons/Tool/as.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/bcc32.xml b/src/engine/SCons/Tool/bcc32.xml index 743ec00..e043f0f 100644 --- a/src/engine/SCons/Tool/bcc32.xml +++ b/src/engine/SCons/Tool/bcc32.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/c++.xml b/src/engine/SCons/Tool/c++.xml index d5fcad7..b59816b 100644 --- a/src/engine/SCons/Tool/c++.xml +++ b/src/engine/SCons/Tool/c++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml index 7ce8b36..06e73ff 100644 --- a/src/engine/SCons/Tool/cc.xml +++ b/src/engine/SCons/Tool/cc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/clang.py b/src/engine/SCons/Tool/clang.py index 081ab67..162daad 100644 --- a/src/engine/SCons/Tool/clang.py +++ b/src/engine/SCons/Tool/clang.py @@ -46,6 +46,7 @@ import sys import SCons.Util import SCons.Tool.cc from SCons.Tool.clangCommon import get_clang_install_dirs +from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang'] @@ -62,6 +63,10 @@ def generate(env): clang_bin_dir = os.path.dirname(clang) env.AppendENVPath('PATH', clang_bin_dir) + # Set-up ms tools paths + msvc_setup_env_once(env) + + env['CC'] = env.Detect(compilers) or 'clang' if env['PLATFORM'] in ['cygwin', 'win32']: env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS') diff --git a/src/engine/SCons/Tool/clang.xml b/src/engine/SCons/Tool/clang.xml index e2e50d4..8751f97 100644 --- a/src/engine/SCons/Tool/clang.xml +++ b/src/engine/SCons/Tool/clang.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/clangCommon/__init__.py b/src/engine/SCons/Tool/clangCommon/__init__.py index 37efbf6..5501457 100644 --- a/src/engine/SCons/Tool/clangCommon/__init__.py +++ b/src/engine/SCons/Tool/clangCommon/__init__.py @@ -6,6 +6,7 @@ clang_win32_dirs = [ r'C:\Program Files\LLVM\bin', r'C:\cygwin64\bin', r'C:\msys64', + r'C:\msys64\mingw64\bin', r'C:\cygwin\bin', r'C:\msys', ] diff --git a/src/engine/SCons/Tool/clangxx.py b/src/engine/SCons/Tool/clangxx.py index a29cf79..b1dc6f3 100644 --- a/src/engine/SCons/Tool/clangxx.py +++ b/src/engine/SCons/Tool/clangxx.py @@ -47,6 +47,7 @@ import SCons.Tool import SCons.Util import SCons.Tool.cxx from SCons.Tool.clangCommon import get_clang_install_dirs +from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang++'] @@ -75,6 +76,10 @@ def generate(env): clangxx_bin_dir = os.path.dirname(clangxx) env.AppendENVPath('PATH', clangxx_bin_dir) + # Set-up ms tools paths + msvc_setup_env_once(env) + + # determine compiler version if env['CXX']: pipe = SCons.Action._subproc(env, [env['CXX'], '--version'], diff --git a/src/engine/SCons/Tool/clangxx.xml b/src/engine/SCons/Tool/clangxx.xml index 2c1c2ca..32870ce 100644 --- a/src/engine/SCons/Tool/clangxx.xml +++ b/src/engine/SCons/Tool/clangxx.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/cvf.xml b/src/engine/SCons/Tool/cvf.xml index e6c550b..580dea1 100644 --- a/src/engine/SCons/Tool/cvf.xml +++ b/src/engine/SCons/Tool/cvf.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/cyglink.xml b/src/engine/SCons/Tool/cyglink.xml index 42208f1..702bff4 100644 --- a/src/engine/SCons/Tool/cyglink.xml +++ b/src/engine/SCons/Tool/cyglink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/default.xml b/src/engine/SCons/Tool/default.xml index 4b862fb..9192e43 100644 --- a/src/engine/SCons/Tool/default.xml +++ b/src/engine/SCons/Tool/default.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/dmd.xml b/src/engine/SCons/Tool/dmd.xml index a3620ce..5d653bb 100644 --- a/src/engine/SCons/Tool/dmd.xml +++ b/src/engine/SCons/Tool/dmd.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py index b93d916..c4fdfba 100644 --- a/src/engine/SCons/Tool/docbook/__init__.py +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -135,7 +135,7 @@ def __get_xml_text(root): """ Return the text for the given root node (xml.dom.minidom). """ txt = "" for e in root.childNodes: - if (e.nodeType == e.TEXT_NODE): + if e.nodeType == e.TEXT_NODE: txt += e.data return txt @@ -207,7 +207,7 @@ def _detect(env): if env.get('DOCBOOK_PREFER_XSLTPROC',''): prefer_xsltproc = True - if ((not has_libxml2 and not has_lxml) or (prefer_xsltproc)): + if (not has_libxml2 and not has_lxml) or prefer_xsltproc: # Try to find the XSLT processors __detect_cl_tool(env, 'DOCBOOK_XSLTPROC', xsltproc_com, xsltproc_com_priority) __detect_cl_tool(env, 'DOCBOOK_XMLLINT', xmllint_com) diff --git a/src/engine/SCons/Tool/docbook/__init__.xml b/src/engine/SCons/Tool/docbook/__init__.xml index 6559d16..32f085b 100644 --- a/src/engine/SCons/Tool/docbook/__init__.xml +++ b/src/engine/SCons/Tool/docbook/__init__.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py index e7b8cfa..de1375d 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py @@ -33,10 +33,10 @@ def adjustColumnWidths(ctx, nodeset): # Get the nominal table width varString = lookupVariable(tctxt, "nominal.table.width", None) - if varString == None: - nominalWidth = 6 * pixelsPerInch; + if varString is None: + nominalWidth = 6 * pixelsPerInch else: - nominalWidth = convertLength(varString); + nominalWidth = convertLength(varString) # Get the requested table width tableWidth = lookupVariable(tctxt, "table.width", "100%") @@ -58,13 +58,13 @@ def adjustColumnWidths(ctx, nodeset): colChildren = colgroup.children col = colChildren - while col != None: + while col is not None: if foStylesheet: width = col.prop("column-width") else: width = col.prop("width") - if width == None: + if width is None: width = "1*" relPart = 0.0 @@ -145,7 +145,7 @@ def adjustColumnWidths(ctx, nodeset): # Side-effect free? We don' need no steenkin' side-effect free! count = 0 col = colChildren - while col != None: + while col is not None: if foStylesheet: col.setProp("column-width", widths[count]) else: @@ -161,8 +161,8 @@ def convertLength(length): global pixelsPerInch global unitHash - m = re.search('([+-]?[\d\.]+)(\S+)', length) - if m != None and m.lastindex > 1: + m = re.search('([+-]?[\d.]+)(\S+)', length) + if m is not None and m.lastindex > 1: unit = pixelsPerInch if m.group(2) in unitHash: unit = unitHash[m.group(2)] @@ -204,7 +204,7 @@ def correctRoundingError(floatWidths): def lookupVariable(tctxt, varName, default): varString = tctxt.variableLookup(varName, None) - if varString == None: + if varString is None: return default # If it's a list, get the first element diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py index 77ca0de..d5529b8 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py @@ -36,7 +36,7 @@ try: outfile = None count = 4 - while (sys.argv[count]): + while sys.argv[count]: try: name, value = sys.argv[count].split("=", 2) if name in params: diff --git a/src/engine/SCons/Tool/dvi.xml b/src/engine/SCons/Tool/dvi.xml index bfffc33..d3d7328 100644 --- a/src/engine/SCons/Tool/dvi.xml +++ b/src/engine/SCons/Tool/dvi.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/dvipdf.xml b/src/engine/SCons/Tool/dvipdf.xml index c0df409..a2747bd 100644 --- a/src/engine/SCons/Tool/dvipdf.xml +++ b/src/engine/SCons/Tool/dvipdf.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/dvips.xml b/src/engine/SCons/Tool/dvips.xml index 5d4a29f..d19392a 100644 --- a/src/engine/SCons/Tool/dvips.xml +++ b/src/engine/SCons/Tool/dvips.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/f03.xml b/src/engine/SCons/Tool/f03.xml index 0b3f786..c020b81 100644 --- a/src/engine/SCons/Tool/f03.xml +++ b/src/engine/SCons/Tool/f03.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/f08.xml b/src/engine/SCons/Tool/f08.xml index 6a49c75..802e4cc 100644 --- a/src/engine/SCons/Tool/f08.xml +++ b/src/engine/SCons/Tool/f08.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/f77.xml b/src/engine/SCons/Tool/f77.xml index d07931b..abfc4a2 100644 --- a/src/engine/SCons/Tool/f77.xml +++ b/src/engine/SCons/Tool/f77.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/f90.xml b/src/engine/SCons/Tool/f90.xml index 8f1da95..94249a3 100644 --- a/src/engine/SCons/Tool/f90.xml +++ b/src/engine/SCons/Tool/f90.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/f95.xml b/src/engine/SCons/Tool/f95.xml index 1cce442..4a4db46 100644 --- a/src/engine/SCons/Tool/f95.xml +++ b/src/engine/SCons/Tool/f95.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/fortran.xml b/src/engine/SCons/Tool/fortran.xml index 9af41dd..53bcfb1 100644 --- a/src/engine/SCons/Tool/fortran.xml +++ b/src/engine/SCons/Tool/fortran.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/g++.xml b/src/engine/SCons/Tool/g++.xml index dadb4aa..a871310 100644 --- a/src/engine/SCons/Tool/g++.xml +++ b/src/engine/SCons/Tool/g++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/g77.xml b/src/engine/SCons/Tool/g77.xml index b7f8368..33596ab 100644 --- a/src/engine/SCons/Tool/g77.xml +++ b/src/engine/SCons/Tool/g77.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gas.xml b/src/engine/SCons/Tool/gas.xml index 6e0de94..d71f38a 100644 --- a/src/engine/SCons/Tool/gas.xml +++ b/src/engine/SCons/Tool/gas.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gcc.xml b/src/engine/SCons/Tool/gcc.xml index d6b9b41..4d5374d 100644 --- a/src/engine/SCons/Tool/gcc.xml +++ b/src/engine/SCons/Tool/gcc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gdc.xml b/src/engine/SCons/Tool/gdc.xml index 4c6c2f8..b0fd89e 100644 --- a/src/engine/SCons/Tool/gdc.xml +++ b/src/engine/SCons/Tool/gdc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gettext.xml b/src/engine/SCons/Tool/gettext.xml index f9f8b81..aa30a7a 100644 --- a/src/engine/SCons/Tool/gettext.xml +++ b/src/engine/SCons/Tool/gettext.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gfortran.xml b/src/engine/SCons/Tool/gfortran.xml index aa32e01..0c9f40b 100644 --- a/src/engine/SCons/Tool/gfortran.xml +++ b/src/engine/SCons/Tool/gfortran.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gnulink.xml b/src/engine/SCons/Tool/gnulink.xml index 0e055c7..2fb9bba 100644 --- a/src/engine/SCons/Tool/gnulink.xml +++ b/src/engine/SCons/Tool/gnulink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/gs.xml b/src/engine/SCons/Tool/gs.xml index 898f077..44c9737 100644 --- a/src/engine/SCons/Tool/gs.xml +++ b/src/engine/SCons/Tool/gs.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/hpc++.xml b/src/engine/SCons/Tool/hpc++.xml index bfc9411..97a8625 100644 --- a/src/engine/SCons/Tool/hpc++.xml +++ b/src/engine/SCons/Tool/hpc++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/hpcc.xml b/src/engine/SCons/Tool/hpcc.xml index f304b90..85a60e1 100644 --- a/src/engine/SCons/Tool/hpcc.xml +++ b/src/engine/SCons/Tool/hpcc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/hplink.xml b/src/engine/SCons/Tool/hplink.xml index 07d9bb9..2aa7fe5 100644 --- a/src/engine/SCons/Tool/hplink.xml +++ b/src/engine/SCons/Tool/hplink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/icc.xml b/src/engine/SCons/Tool/icc.xml index f4c3dda..f89df9f 100644 --- a/src/engine/SCons/Tool/icc.xml +++ b/src/engine/SCons/Tool/icc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/icl.xml b/src/engine/SCons/Tool/icl.xml index d6c9723..1f9ecaa 100644 --- a/src/engine/SCons/Tool/icl.xml +++ b/src/engine/SCons/Tool/icl.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ifl.xml b/src/engine/SCons/Tool/ifl.xml index 7f7a7d4..48c9b2e 100644 --- a/src/engine/SCons/Tool/ifl.xml +++ b/src/engine/SCons/Tool/ifl.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ifort.xml b/src/engine/SCons/Tool/ifort.xml index 7b05b7d..267f1bc 100644 --- a/src/engine/SCons/Tool/ifort.xml +++ b/src/engine/SCons/Tool/ifort.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ilink.xml b/src/engine/SCons/Tool/ilink.xml index e5f818f..2941714 100644 --- a/src/engine/SCons/Tool/ilink.xml +++ b/src/engine/SCons/Tool/ilink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ilink32.xml b/src/engine/SCons/Tool/ilink32.xml index 0ae6f2b..07c5f9b 100644 --- a/src/engine/SCons/Tool/ilink32.xml +++ b/src/engine/SCons/Tool/ilink32.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index c0a193b..dcb3581 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -168,7 +168,7 @@ def installShlibLinks(dest, source, env): Verbose = False symlinks = listShlibLinksToInstall(dest, source, env) if Verbose: - print('installShlibLinks: symlinks={:r}'.format(SCons.Tool.StringizeLibSymlinks(symlinks))) + print('installShlibLinks: symlinks={!r}'.format(SCons.Tool.StringizeLibSymlinks(symlinks))) if symlinks: SCons.Tool.CreateLibSymlinks(env, symlinks) return @@ -244,7 +244,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): Verbose = False _INSTALLED_FILES.extend(target) if Verbose: - print("add_versioned_targets_to_INSTALLED_FILES: target={:r}".format(list(map(str, target)))) + print("add_versioned_targets_to_INSTALLED_FILES: target={!r}".format(list(map(str, target)))) symlinks = listShlibLinksToInstall(target[0], source, env) if symlinks: SCons.Tool.EmitLibSymlinks(env, symlinks, target[0]) diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml index 74169b3..150308b 100644 --- a/src/engine/SCons/Tool/install.xml +++ b/src/engine/SCons/Tool/install.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index 1f3fcea..5a101b4 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -318,7 +318,7 @@ def get_intel_compiler_top(version, abi): if not os.path.exists(os.path.join(top, "Bin", "icl.exe")) \ and not os.path.exists(os.path.join(top, "Bin", abi, "icl.exe")) \ and not os.path.exists(os.path.join(top, "Bin", archdir, "icl.exe")): - raise MissingDirError("Can't find Intel compiler in %s"%(top)) + raise MissingDirError("Can't find Intel compiler in %s" % top) elif is_mac or is_linux: def find_in_2008style_dir(version): # first dir is new (>=9.0) style, second is old (8.0) style. @@ -387,7 +387,7 @@ def get_intel_compiler_top(version, abi): def generate(env, version=None, abi=None, topdir=None, verbose=0): - """Add Builders and construction variables for Intel C/C++ compiler + r"""Add Builders and construction variables for Intel C/C++ compiler to an Environment. args: version: (string) compiler version to use, like "80" @@ -551,7 +551,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): # Look for license file dir # in system environment, registry, and default location. envlicdir = os.environ.get("INTEL_LICENSE_FILE", '') - K = ('SOFTWARE\Intel\Licenses') + K = r'SOFTWARE\Intel\Licenses' try: k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K) reglicdir = SCons.Util.RegQueryValueEx(k, "w_cpp")[0] diff --git a/src/engine/SCons/Tool/intelc.xml b/src/engine/SCons/Tool/intelc.xml index 391d1c3..5404374 100644 --- a/src/engine/SCons/Tool/intelc.xml +++ b/src/engine/SCons/Tool/intelc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py index e75fa13..502aa60 100644 --- a/src/engine/SCons/Tool/jar.py +++ b/src/engine/SCons/Tool/jar.py @@ -158,7 +158,7 @@ def Jar(env, target = None, source = [], *args, **kw): # files. def dir_to_class(s): dir_targets = env.JavaClassDir(source = s, *args, **kw) - if(dir_targets == []): + if dir_targets == []: # no classes files could be built from the source dir # so pass the dir as is. return [env.fs.Dir(s)] diff --git a/src/engine/SCons/Tool/jar.xml b/src/engine/SCons/Tool/jar.xml index 1197b62..30c51f8 100644 --- a/src/engine/SCons/Tool/jar.xml +++ b/src/engine/SCons/Tool/jar.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/javac.xml b/src/engine/SCons/Tool/javac.xml index 97ec7d2..bc89342 100644 --- a/src/engine/SCons/Tool/javac.xml +++ b/src/engine/SCons/Tool/javac.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/javah.py b/src/engine/SCons/Tool/javah.py index 80f8a6b..fbfcbe2 100644 --- a/src/engine/SCons/Tool/javah.py +++ b/src/engine/SCons/Tool/javah.py @@ -115,7 +115,7 @@ def getJavaHClassPath(env,target, source, for_signature): path = "${SOURCE.attributes.java_classdir}" if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']: path = SCons.Util.AppendPath(path, env['JAVACLASSPATH']) - return "-classpath %s" % (path) + return "-classpath %s" % path def generate(env): """Add Builders and construction variables for javah to an Environment.""" diff --git a/src/engine/SCons/Tool/javah.xml b/src/engine/SCons/Tool/javah.xml index d944a48..4d436b1 100644 --- a/src/engine/SCons/Tool/javah.xml +++ b/src/engine/SCons/Tool/javah.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/latex.xml b/src/engine/SCons/Tool/latex.xml index 4a2760d..9a2e2df 100644 --- a/src/engine/SCons/Tool/latex.xml +++ b/src/engine/SCons/Tool/latex.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/ldc.xml b/src/engine/SCons/Tool/ldc.xml index 6a80436..6707f7e 100644 --- a/src/engine/SCons/Tool/ldc.xml +++ b/src/engine/SCons/Tool/ldc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/lex.xml b/src/engine/SCons/Tool/lex.xml index f933451..4e76c2a 100644 --- a/src/engine/SCons/Tool/lex.xml +++ b/src/engine/SCons/Tool/lex.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml index 75b2ed8..654dafc 100644 --- a/src/engine/SCons/Tool/link.xml +++ b/src/engine/SCons/Tool/link.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/linkloc.xml b/src/engine/SCons/Tool/linkloc.xml index aa17ae0..80849c9 100644 --- a/src/engine/SCons/Tool/linkloc.xml +++ b/src/engine/SCons/Tool/linkloc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/m4.xml b/src/engine/SCons/Tool/m4.xml index 1957dc9..0e2c466 100644 --- a/src/engine/SCons/Tool/m4.xml +++ b/src/engine/SCons/Tool/m4.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/masm.xml b/src/engine/SCons/Tool/masm.xml index b3a6a7a..c4ad409 100644 --- a/src/engine/SCons/Tool/masm.xml +++ b/src/engine/SCons/Tool/masm.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/midl.xml b/src/engine/SCons/Tool/midl.xml index 63cf527..bee23e0 100644 --- a/src/engine/SCons/Tool/midl.xml +++ b/src/engine/SCons/Tool/midl.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mingw.xml b/src/engine/SCons/Tool/mingw.xml index 0ad7e95..80f9790 100644 --- a/src/engine/SCons/Tool/mingw.xml +++ b/src/engine/SCons/Tool/mingw.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/msgfmt.xml b/src/engine/SCons/Tool/msgfmt.xml index 77a1498..a42a742 100644 --- a/src/engine/SCons/Tool/msgfmt.xml +++ b/src/engine/SCons/Tool/msgfmt.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/msginit.xml b/src/engine/SCons/Tool/msginit.xml index 0099b29..e494fbc 100644 --- a/src/engine/SCons/Tool/msginit.xml +++ b/src/engine/SCons/Tool/msginit.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/msgmerge.xml b/src/engine/SCons/Tool/msgmerge.xml index 139b21c..71dbe24 100644 --- a/src/engine/SCons/Tool/msgmerge.xml +++ b/src/engine/SCons/Tool/msgmerge.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mslib.xml b/src/engine/SCons/Tool/mslib.xml index d65bf48..1837467 100644 --- a/src/engine/SCons/Tool/mslib.xml +++ b/src/engine/SCons/Tool/mslib.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 0fa6454..fc5f009 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -220,7 +220,7 @@ def embedManifestDllCheck(target, source, env): if env.get('WINDOWS_EMBED_MANIFEST', 0): manifestSrc = target[0].get_abspath() + '.manifest' if os.path.exists(manifestSrc): - ret = (embedManifestDllAction) ([target[0]],None,env) + ret = embedManifestDllAction([target[0]], None, env) if ret: raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) return ret @@ -234,7 +234,7 @@ def embedManifestExeCheck(target, source, env): if env.get('WINDOWS_EMBED_MANIFEST', 0): manifestSrc = target[0].get_abspath() + '.manifest' if os.path.exists(manifestSrc): - ret = (embedManifestExeAction) ([target[0]],None,env) + ret = embedManifestExeAction([target[0]], None, env) if ret: raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) return ret diff --git a/src/engine/SCons/Tool/mslink.xml b/src/engine/SCons/Tool/mslink.xml index 87e1768..1691335 100644 --- a/src/engine/SCons/Tool/mslink.xml +++ b/src/engine/SCons/Tool/mslink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mssdk.xml b/src/engine/SCons/Tool/mssdk.xml index 4444793..aa61d0f 100644 --- a/src/engine/SCons/Tool/mssdk.xml +++ b/src/engine/SCons/Tool/mssdk.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/msvc.xml b/src/engine/SCons/Tool/msvc.xml index ff65364..dcac6cc 100644 --- a/src/engine/SCons/Tool/msvc.xml +++ b/src/engine/SCons/Tool/msvc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 7dca9e1..929e558 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -172,9 +172,9 @@ def makeHierarchy(sources): return hierarchy class _UserGenerator(object): - ''' + """ Base class for .dsp.user file generator - ''' + """ # Default instance values. # Ok ... a bit defensive, but it does not seem reasonable to crash the # build for a workspace user file. :-) @@ -980,7 +980,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): if SCons.Util.is_Dict(value): self.file.write('\t\t\t<Filter\n' '\t\t\t\tName="%s"\n' - '\t\t\t\tFilter="">\n' % (key)) + '\t\t\t\tFilter="">\n' % key) self.printSources(value, commonprefix) self.file.write('\t\t\t</Filter>\n') @@ -992,7 +992,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): file = os.path.normpath(file) self.file.write('\t\t\t<File\n' '\t\t\t\tRelativePath="%s">\n' - '\t\t\t</File>\n' % (file)) + '\t\t\t</File>\n' % file) def PrintSourceFiles(self): categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', @@ -2047,17 +2047,17 @@ def generate(env): (version_num, suite) = (7.0, None) # guess at a default if 'MSVS' not in env: env['MSVS'] = {} - if (version_num < 7.0): + if version_num < 7.0: env['MSVS']['PROJECTSUFFIX'] = '.dsp' env['MSVS']['SOLUTIONSUFFIX'] = '.dsw' - elif (version_num < 10.0): + elif version_num < 10.0: env['MSVS']['PROJECTSUFFIX'] = '.vcproj' env['MSVS']['SOLUTIONSUFFIX'] = '.sln' else: env['MSVS']['PROJECTSUFFIX'] = '.vcxproj' env['MSVS']['SOLUTIONSUFFIX'] = '.sln' - if (version_num >= 10.0): + if version_num >= 10.0: env['MSVSENCODING'] = 'utf-8' else: env['MSVSENCODING'] = 'Windows-1252' diff --git a/src/engine/SCons/Tool/msvs.xml b/src/engine/SCons/Tool/msvs.xml index 3a9fdf0..b1f79b2 100644 --- a/src/engine/SCons/Tool/msvs.xml +++ b/src/engine/SCons/Tool/msvs.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mwcc.xml b/src/engine/SCons/Tool/mwcc.xml index 4073dd5..529ff1b 100644 --- a/src/engine/SCons/Tool/mwcc.xml +++ b/src/engine/SCons/Tool/mwcc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/mwld.xml b/src/engine/SCons/Tool/mwld.xml index a683794..56d939c 100644 --- a/src/engine/SCons/Tool/mwld.xml +++ b/src/engine/SCons/Tool/mwld.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/nasm.xml b/src/engine/SCons/Tool/nasm.xml index f26eb78..f573d5a 100644 --- a/src/engine/SCons/Tool/nasm.xml +++ b/src/engine/SCons/Tool/nasm.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/packaging.xml b/src/engine/SCons/Tool/packaging.xml index 877b88f..8ab4912 100644 --- a/src/engine/SCons/Tool/packaging.xml +++ b/src/engine/SCons/Tool/packaging.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/packaging/__init__.xml b/src/engine/SCons/Tool/packaging/__init__.xml index 41a3f11..31c6eed 100644 --- a/src/engine/SCons/Tool/packaging/__init__.xml +++ b/src/engine/SCons/Tool/packaging/__init__.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ @@ -850,9 +850,9 @@ Examples: </para> <example_commands> -# makes sure the built library will be installed with 0644 file +# makes sure the built library will be installed with 0o644 file # access mode -Tag( Library( 'lib.c' ), UNIX_ATTR="0644" ) +Tag( Library( 'lib.c' ), UNIX_ATTR="0o644" ) # marks file2.txt to be a documentation file Tag( 'file2.txt', DOC ) diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index 0ef18ec..9f28b72 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -182,7 +182,7 @@ def generate_guids(root): def string_wxsfile(target, source, env): - return "building WiX file %s"%( target[0].path ) + return "building WiX file %s" % target[0].path def build_wxsfile(target, source, env): """ Compiles a .wxs file from the keywords given in env['msi_spec'] and @@ -224,7 +224,7 @@ def build_wxsfile(target, source, env): # setup function # def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): - """ Create the wix default target directory layout and return the innermost + r""" Create the wix default target directory layout and return the innermost directory. We assume that the XML tree delivered in the root argument already contains diff --git a/src/engine/SCons/Tool/pdf.xml b/src/engine/SCons/Tool/pdf.xml index 037494b..7bf44cc 100644 --- a/src/engine/SCons/Tool/pdf.xml +++ b/src/engine/SCons/Tool/pdf.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/pdflatex.xml b/src/engine/SCons/Tool/pdflatex.xml index af4970c..75eb4d4 100644 --- a/src/engine/SCons/Tool/pdflatex.xml +++ b/src/engine/SCons/Tool/pdflatex.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/pdftex.xml b/src/engine/SCons/Tool/pdftex.xml index cf7e70c..a8c7fd0 100644 --- a/src/engine/SCons/Tool/pdftex.xml +++ b/src/engine/SCons/Tool/pdftex.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/qt.xml b/src/engine/SCons/Tool/qt.xml index 6f8d668..cd54991 100644 --- a/src/engine/SCons/Tool/qt.xml +++ b/src/engine/SCons/Tool/qt.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/rmic.xml b/src/engine/SCons/Tool/rmic.xml index bc9e2ba..e8b6c26 100644 --- a/src/engine/SCons/Tool/rmic.xml +++ b/src/engine/SCons/Tool/rmic.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/rpcgen.xml b/src/engine/SCons/Tool/rpcgen.xml index 087bf38..f9142f1 100644 --- a/src/engine/SCons/Tool/rpcgen.xml +++ b/src/engine/SCons/Tool/rpcgen.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sgiar.xml b/src/engine/SCons/Tool/sgiar.xml index d964bee..edb7a60 100644 --- a/src/engine/SCons/Tool/sgiar.xml +++ b/src/engine/SCons/Tool/sgiar.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sgic++.xml b/src/engine/SCons/Tool/sgic++.xml index 2fea7b3..a299d22 100644 --- a/src/engine/SCons/Tool/sgic++.xml +++ b/src/engine/SCons/Tool/sgic++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sgicc.xml b/src/engine/SCons/Tool/sgicc.xml index ecf2b66..82a84ec 100644 --- a/src/engine/SCons/Tool/sgicc.xml +++ b/src/engine/SCons/Tool/sgicc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sgilink.xml b/src/engine/SCons/Tool/sgilink.xml index 7a15562..ff54d89 100644 --- a/src/engine/SCons/Tool/sgilink.xml +++ b/src/engine/SCons/Tool/sgilink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sunar.xml b/src/engine/SCons/Tool/sunar.xml index f875217..e267182 100644 --- a/src/engine/SCons/Tool/sunar.xml +++ b/src/engine/SCons/Tool/sunar.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sunc++.xml b/src/engine/SCons/Tool/sunc++.xml index 4d28f29..c671a5a 100644 --- a/src/engine/SCons/Tool/sunc++.xml +++ b/src/engine/SCons/Tool/sunc++.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/suncc.xml b/src/engine/SCons/Tool/suncc.xml index f64adc4..9c94e67 100644 --- a/src/engine/SCons/Tool/suncc.xml +++ b/src/engine/SCons/Tool/suncc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/suncxx.py b/src/engine/SCons/Tool/suncxx.py index 090df7d..1c35612 100644 --- a/src/engine/SCons/Tool/suncxx.py +++ b/src/engine/SCons/Tool/suncxx.py @@ -41,20 +41,18 @@ import subprocess import SCons.Tool.cxx cplusplus = SCons.Tool.cxx -#cplusplus = __import__('c++', globals(), locals(), []) +# cplusplus = __import__('c++', globals(), locals(), []) package_info = {} + def get_package_info(package_name, pkginfo, pkgchk): try: return package_info[package_name] 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: @@ -68,13 +66,16 @@ def get_package_info(package_name, pkginfo, pkgchk): pathname = os.path.dirname(sadm_match.group(1)) try: + popen_args = {'stdout': subprocess.PIPE, + 'stderr': DEVNULL} + popen_args['universal_newlines'] = True p = subprocess.Popen([pkginfo, '-l', package_name], - stdout=subprocess.PIPE, - stderr=DEVNULL) + **popen_args) except EnvironmentError: pass else: - pkginfo_contents = p.communicate()[0].decode() + pkginfo_contents = p.communicate()[0] + pkginfo_contents.decode() version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M) version_match = version_re.search(pkginfo_contents) if version_match: @@ -82,13 +83,16 @@ def get_package_info(package_name, pkginfo, pkgchk): if pathname is None: try: + popen_args = {'stdout': subprocess.PIPE, + 'stderr': DEVNULL} + popen_args['universal_newlines'] = True p = subprocess.Popen([pkgchk, '-l', package_name], - stdout=subprocess.PIPE, - stderr=DEVNULL) + **popen_args) except EnvironmentError: pass else: - pkgchk_contents = p.communicate()[0].decode() + pkgchk_contents = p.communicate()[0] + pkgchk_contents.decode() pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M) pathname_match = pathname_re.search(pkgchk_contents) if pathname_match: @@ -97,7 +101,8 @@ def get_package_info(package_name, pkginfo, pkgchk): package_info[package_name] = (pathname, version) return package_info[package_name] -# use the package installer tool lslpp to figure out where cppc and what + +# use the package installer tool "pkg" to figure out where cppc and what # version of it is installed def get_cppc(env): cxx = env.subst('$CXX') @@ -119,6 +124,7 @@ def get_cppc(env): return (cppcPath, 'CC', 'CC', cppcVersion) + def generate(env): """Add Builders and construction variables for SunPRO C++.""" path, cxx, shcxx, version = get_cppc(env) @@ -131,10 +137,11 @@ def generate(env): env['CXX'] = cxx env['SHCXX'] = shcxx env['CXXVERSION'] = version - env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -KPIC') - env['SHOBJPREFIX'] = 'so_' - env['SHOBJSUFFIX'] = '.o' - + env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -KPIC') + env['SHOBJPREFIX'] = 'so_' + env['SHOBJSUFFIX'] = '.o' + + def exists(env): path, cxx, shcxx, version = get_cppc(env) if path and cxx: diff --git a/src/engine/SCons/Tool/sunf77.xml b/src/engine/SCons/Tool/sunf77.xml index ebbddfc..dbcf7c3 100644 --- a/src/engine/SCons/Tool/sunf77.xml +++ b/src/engine/SCons/Tool/sunf77.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sunf90.xml b/src/engine/SCons/Tool/sunf90.xml index 82a220b..627d58d 100644 --- a/src/engine/SCons/Tool/sunf90.xml +++ b/src/engine/SCons/Tool/sunf90.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sunf95.xml b/src/engine/SCons/Tool/sunf95.xml index 2e9a191..43c47e1 100644 --- a/src/engine/SCons/Tool/sunf95.xml +++ b/src/engine/SCons/Tool/sunf95.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/sunlink.xml b/src/engine/SCons/Tool/sunlink.xml index 7e92acc..b8544cc 100644 --- a/src/engine/SCons/Tool/sunlink.xml +++ b/src/engine/SCons/Tool/sunlink.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/swig.xml b/src/engine/SCons/Tool/swig.xml index db83e6b..46b45f4 100644 --- a/src/engine/SCons/Tool/swig.xml +++ b/src/engine/SCons/Tool/swig.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/tar.xml b/src/engine/SCons/Tool/tar.xml index c65317a..cf4022a 100644 --- a/src/engine/SCons/Tool/tar.xml +++ b/src/engine/SCons/Tool/tar.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py index 5cf7bca..fa18cf9 100644 --- a/src/engine/SCons/Tool/tex.py +++ b/src/engine/SCons/Tool/tex.py @@ -204,7 +204,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None # with LaTeXAction and from the pdflatex.py with PDFLaTeXAction # set this up now for the case where the user requests a different extension # for the target filename - if (XXXLaTeXAction == LaTeXAction): + if XXXLaTeXAction == LaTeXAction: callerSuffix = ".dvi" else: callerSuffix = env['PDFSUFFIX'] @@ -283,7 +283,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None count = 0 - while (must_rerun_latex and count < int(env.subst('$LATEXRETRIES'))) : + while must_rerun_latex and count < int(env.subst('$LATEXRETRIES')): result = XXXLaTeXAction(target, source, env) if result != 0: return result @@ -461,7 +461,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if Verbose: print("rerun Latex due to undefined references or citations") - if (count >= int(env.subst('$LATEXRETRIES')) and must_rerun_latex): + if count >= int(env.subst('$LATEXRETRIES')) and must_rerun_latex: print("reached max number of retries on Latex ,",int(env.subst('$LATEXRETRIES'))) # end of while loop @@ -861,7 +861,7 @@ def generate_darwin(env): environ = {} env['ENV'] = environ - if (platform.system() == 'Darwin'): + if platform.system() == 'Darwin': try: ospath = env['ENV']['PATHOSX'] except: diff --git a/src/engine/SCons/Tool/tex.xml b/src/engine/SCons/Tool/tex.xml index 8965daf..da1bf20 100644 --- a/src/engine/SCons/Tool/tex.xml +++ b/src/engine/SCons/Tool/tex.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ 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/Tool/textfile.xml b/src/engine/SCons/Tool/textfile.xml index 3b4a038..957e18c 100644 --- a/src/engine/SCons/Tool/textfile.xml +++ b/src/engine/SCons/Tool/textfile.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/tlib.xml b/src/engine/SCons/Tool/tlib.xml index b9afef4..ee94717 100644 --- a/src/engine/SCons/Tool/tlib.xml +++ b/src/engine/SCons/Tool/tlib.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index 936924b..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): @@ -133,7 +133,7 @@ def _update_pot_file(target, source, env): re_cdate = re.compile(r'^"POT-Creation-Date: .*"$[\r\n]?', re.M) old_content_nocdate = re.sub(re_cdate, "", old_content) new_content_nocdate = re.sub(re_cdate, "", new_content) - if (old_content_nocdate == new_content_nocdate): + if old_content_nocdate == new_content_nocdate: # Messages are up-to-date needs_update = False explain = "messages in file found to be up-to-date" diff --git a/src/engine/SCons/Tool/xgettext.xml b/src/engine/SCons/Tool/xgettext.xml index 380f92a..0493157 100644 --- a/src/engine/SCons/Tool/xgettext.xml +++ b/src/engine/SCons/Tool/xgettext.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/yacc.xml b/src/engine/SCons/Tool/yacc.xml index 48ec4b0..10817b0 100644 --- a/src/engine/SCons/Tool/yacc.xml +++ b/src/engine/SCons/Tool/yacc.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Tool/zip.xml b/src/engine/SCons/Tool/zip.xml index 2791909..f465da1 100644 --- a/src/engine/SCons/Tool/zip.xml +++ b/src/engine/SCons/Tool/zip.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0"?> <!-- __COPYRIGHT__ diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 8519a98..130cc5e 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -36,19 +36,11 @@ import pprint import hashlib 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 @@ -60,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 @@ -208,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 @@ -312,18 +299,21 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None): '\n') sys.stdout.write(legend) - tags = ['['] - tags.append(' E'[IDX(root.exists())]) - tags.append(' R'[IDX(root.rexists() and not root.exists())]) - tags.append(' BbB'[[0,1][IDX(root.has_explicit_builder())] + - [0,2][IDX(root.has_builder())]]) - tags.append(' S'[IDX(root.side_effect)]) - tags.append(' P'[IDX(root.precious)]) - tags.append(' A'[IDX(root.always_build)]) - tags.append(' C'[IDX(root.is_up_to_date())]) - tags.append(' N'[IDX(root.noclean)]) - tags.append(' H'[IDX(root.nocache)]) - tags.append(']') + tags = [ + '[', + ' E'[IDX(root.exists())], + ' R'[IDX(root.rexists() and not root.exists())], + ' BbB'[ + [0, 1][IDX(root.has_explicit_builder())] + + [0, 2][IDX(root.has_builder())] + ], + ' S'[IDX(root.side_effect)], ' P'[IDX(root.precious)], + ' A'[IDX(root.always_build)], + ' C'[IDX(root.is_up_to_date())], + ' N'[IDX(root.noclean)], + ' H'[IDX(root.nocache)], + ']' + ] else: tags = [] @@ -352,7 +342,6 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None): margin.pop() - # Functions for deciding if things are like various types, mainly to # handle UserDict, UserList and UserString like their underlying types. # @@ -390,7 +379,7 @@ except NameError: try: BaseStringTypes = (str, unicode) except NameError: - BaseStringTypes = (str) + BaseStringTypes = str def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes): return isinstance(obj, DictTypes) @@ -610,6 +599,7 @@ class Proxy(object): return self._subject == other return self.__dict__ == other.__dict__ + class Delegate(object): """A Python Descriptor class that delegates attribute fetches to an underlying wrapped subject of a Proxy. Typical use: @@ -619,6 +609,7 @@ class Delegate(object): """ def __init__(self, attribute): self.attribute = attribute + def __get__(self, obj, cls): if isinstance(obj, cls): return getattr(obj._subject, self.attribute) @@ -1576,11 +1567,8 @@ del __revision__ def to_bytes(s): if s is None: return b'None' - if not PY3 and isinstance(s, UnicodeType): - # 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') @@ -1588,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 0017844..ee07e61 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,15 +308,12 @@ 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')), - bytearray(u'Hello', 'utf-8'), - "Check that to_bytes creates byte array when presented with unicode string. PY2 only") + 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): """Test the to_String() method.""" @@ -352,18 +336,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='') @@ -451,11 +423,11 @@ class UtilTestCase(unittest.TestCase): assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}") assert get_environment_var("$FOO_BAR1234") == "FOO_BAR1234", get_environment_var("$FOO_BAR1234") assert get_environment_var("${BAR_FOO1234}") == "BAR_FOO1234", get_environment_var("${BAR_FOO1234}") - assert get_environment_var("${BAR}FOO") == None, get_environment_var("${BAR}FOO") - assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ") - assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR") - assert get_environment_var("$FOO[0]") == None, get_environment_var("$FOO[0]") - assert get_environment_var("${some('complex expression')}") == None, get_environment_var( + assert get_environment_var("${BAR}FOO") is None, get_environment_var("${BAR}FOO") + assert get_environment_var("$BAR ") is None, get_environment_var("$BAR ") + assert get_environment_var("FOO$BAR") is None, get_environment_var("FOO$BAR") + assert get_environment_var("$FOO[0]") is None, get_environment_var("$FOO[0]") + assert get_environment_var("${some('complex expression')}") is None, get_environment_var( "${some('complex expression')}") def test_Proxy(self): @@ -506,13 +478,14 @@ class UtilTestCase(unittest.TestCase): def test_get_native_path(self): """Test the get_native_path() function.""" import tempfile - filename = tempfile.mktemp() - str = '1234567890 ' + filename + f, filename = tempfile.mkstemp(text=True) + os.close(f) + data = '1234567890 ' + filename try: with open(filename, 'w') as f: - f.write(str) - with open(get_native_path(filename)) as f: - assert f.read() == str + f.write(data) + with open(get_native_path(filename), 'r') as f: + assert f.read() == data finally: try: os.unlink(filename) diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py index 718b3d5..fcec963 100644 --- a/src/engine/SCons/Warnings.py +++ b/src/engine/SCons/Warnings.py @@ -120,27 +120,15 @@ class PythonVersionWarning(DeprecatedWarning): class DeprecatedSourceCodeWarning(FutureDeprecatedWarning): pass -class DeprecatedBuildDirWarning(DeprecatedWarning): - pass - class TaskmasterNeedsExecuteWarning(DeprecatedWarning): pass -class DeprecatedCopyWarning(MandatoryDeprecatedWarning): - pass - class DeprecatedOptionsWarning(MandatoryDeprecatedWarning): pass class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning): pass -class DeprecatedSigModuleWarning(MandatoryDeprecatedWarning): - pass - -class DeprecatedBuilderKeywordsWarning(MandatoryDeprecatedWarning): - pass - class DeprecatedMissingSConscriptWarning(DeprecatedWarning): pass diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index d34243e..18bef48 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -78,12 +78,8 @@ def rename_module(new, old): return False -# TODO: FIXME -# In 3.x, 'pickle' automatically loads the fast version if available. -rename_module('pickle', 'cPickle') - -# Default pickle protocol. Higher protocols are more efficient/featureful -# but incompatible with older Python versions. On Python 2.7 this is 2. +# Default pickle protocol. Higher protocols are more efficient/featured +# but incompatible with older Python versions. # Negative numbers choose the highest available protocol. import pickle @@ -91,54 +87,6 @@ import pickle # Changed to 2 so py3.5+'s pickle will be compatible with py2.7. PICKLE_PROTOCOL = pickle.HIGHEST_PROTOCOL -# TODO: FIXME -# In 3.x, 'profile' automatically loads the fast version if available. -rename_module('profile', 'cProfile') - -# TODO: FIXME -# Before Python 3.0, the 'queue' module was named 'Queue'. -rename_module('queue', 'Queue') - -# TODO: FIXME -# Before Python 3.0, the 'winreg' module was named '_winreg' -rename_module('winreg', '_winreg') - -# Python 3 moved builtin intern() to sys package -# To make porting easier, make intern always live -# in sys package (for python 2.7.x) -try: - sys.intern -except AttributeError: - # We must be using python 2.7.x so monkey patch - # intern into the sys package - sys.intern = intern - -# UserDict, UserList, UserString are in # collections for 3.x, -# but standalone in 2.7.x. Monkey-patch into collections for 2.7. -import collections - -try: - collections.UserDict -except AttributeError: - from UserDict import UserDict as _UserDict - collections.UserDict = _UserDict - del _UserDict - -try: - collections.UserList -except AttributeError: - from UserList import UserList as _UserList - collections.UserList = _UserList - del _UserList - -try: - collections.UserString -except AttributeError: - from UserString import UserString as _UserString - collections.UserString = _UserString - del _UserString - - import shutil try: shutil.SameFileError diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 0b346e8..eff7715 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -770,12 +770,6 @@ import re import shutil import tempfile -tempfile.template = 'cppTests.' -if os.name in ('posix', 'nt'): - tempfile.template = 'cppTests.' + str(os.getpid()) + '.' -else: - tempfile.template = 'cppTests.' - _Cleanup = [] def _clean(): @@ -785,19 +779,17 @@ def _clean(): atexit.register(_clean) +if os.name in ('posix', 'nt'): + tmpprefix = 'cppTests.' + str(os.getpid()) + '.' +else: + tmpprefix = 'cppTests.' + class fileTestCase(unittest.TestCase): cpp_class = cpp.DumbPreProcessor def setUp(self): - try: - path = tempfile.mktemp(prefix=tempfile.template) - except TypeError: - # The tempfile.mktemp() function in earlier versions of Python - # has no prefix argument, but uses the tempfile.template - # value that we set above. - path = tempfile.mktemp() + path = tempfile.mkdtemp(prefix=tmpprefix) _Cleanup.append(path) - os.mkdir(path) self.tempdir = path self.orig_cwd = os.getcwd() os.chdir(path) diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 14bd93d..55254b3 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -131,9 +131,10 @@ class dblite(object): # Note how we catch KeyErrors too here, which might happen # when we don't have cPickle available (default pickle # throws it). - if (ignore_corrupt_dbfiles == 0): raise - if (ignore_corrupt_dbfiles == 1): + if ignore_corrupt_dbfiles: corruption_warning(self._file_name) + else: + raise def close(self): if self._needs_sync: @@ -166,13 +167,13 @@ class dblite(object): except OSError: pass self._needs_sync = 00000 - if (keep_all_files): + if keep_all_files: self._shutil_copyfile( self._file_name, self._file_name + "_" + str(int(self._time_time()))) def _check_writable(self): - if (self._flag == "r"): + if self._flag == "r": raise IOError("Read-only database: %s" % self._file_name) def __getitem__(self, key): @@ -180,9 +181,9 @@ class dblite(object): def __setitem__(self, key, value): self._check_writable() - if (not is_string(key)): + if not is_string(key): raise TypeError("key `%s' must be a string but is %s" % (key, type(key))) - if (not is_bytes(value)): + if not is_bytes(value): raise TypeError("value `%s' must be a bytes but is %s" % (value, type(value))) self._dict[key] = value self._needs_sync = 0o001 @@ -280,7 +281,7 @@ def _exercise(): raise RuntimeError("IOError expected.") -if (__name__ == "__main__"): +if __name__ == "__main__": _exercise() # Local Variables: |