summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/CHANGES.txt18
-rw-r--r--src/engine/MANIFEST.in2
-rw-r--r--src/engine/SCons/Builder.py2
-rw-r--r--src/engine/SCons/BuilderTests.py14
-rw-r--r--src/engine/SCons/CacheDir.py6
-rw-r--r--src/engine/SCons/CacheDirTests.py6
-rw-r--r--src/engine/SCons/Environment.py8
-rw-r--r--src/engine/SCons/Environment.xml110
-rw-r--r--src/engine/SCons/EnvironmentTests.py12
-rw-r--r--src/engine/SCons/Node/AliasTests.py2
-rw-r--r--src/engine/SCons/Node/FS.py4
-rw-r--r--src/engine/SCons/Node/FSTests.py20
-rw-r--r--src/engine/SCons/Node/NodeTests.py2
-rw-r--r--src/engine/SCons/Node/Python.py22
-rw-r--r--src/engine/SCons/Node/PythonTests.py34
-rw-r--r--src/engine/SCons/PathListTests.py2
-rw-r--r--src/engine/SCons/Platform/__init__.py2
-rw-r--r--src/engine/SCons/SConf.py6
-rw-r--r--src/engine/SCons/SConsignTests.py2
-rw-r--r--src/engine/SCons/Scanner/Python.py171
-rw-r--r--src/engine/SCons/Scanner/PythonTests.py269
-rw-r--r--src/engine/SCons/Scanner/RCTests.py2
-rw-r--r--src/engine/SCons/Script/Interactive.py2
-rw-r--r--src/engine/SCons/Script/Main.py4
-rw-r--r--src/engine/SCons/Script/Main.xml88
-rw-r--r--src/engine/SCons/Script/SConscript.xml12
-rw-r--r--src/engine/SCons/Subst.py97
-rw-r--r--src/engine/SCons/Subst.xml2
-rw-r--r--src/engine/SCons/Taskmaster.py2
-rw-r--r--src/engine/SCons/TaskmasterTests.py10
-rw-r--r--src/engine/SCons/Tool/DCommon.xml32
-rw-r--r--src/engine/SCons/Tool/MSCommon/common.py4
-rw-r--r--src/engine/SCons/Tool/__init__.py4
-rw-r--r--src/engine/SCons/Tool/c++.xml17
-rw-r--r--src/engine/SCons/Tool/cc.xml22
-rw-r--r--src/engine/SCons/Tool/f03.xml16
-rw-r--r--src/engine/SCons/Tool/f08.xml16
-rw-r--r--src/engine/SCons/Tool/f77.xml16
-rw-r--r--src/engine/SCons/Tool/f90.xml16
-rw-r--r--src/engine/SCons/Tool/f95.xml16
-rw-r--r--src/engine/SCons/Tool/fortran.xml16
-rw-r--r--src/engine/SCons/Tool/install.xml37
-rw-r--r--src/engine/SCons/Tool/intelc.py8
-rw-r--r--src/engine/SCons/Tool/javac.xml12
-rw-r--r--src/engine/SCons/Tool/link.xml24
-rw-r--r--src/engine/SCons/Tool/msvs.py27
-rw-r--r--src/engine/SCons/Tool/msvsTests.py14
-rw-r--r--src/engine/SCons/Tool/packaging.xml66
-rw-r--r--src/engine/SCons/Tool/packaging/__init__.xml56
-rw-r--r--src/engine/SCons/Tool/packaging/ipk.py2
-rw-r--r--src/engine/SCons/Tool/packaging/rpm.py2
-rw-r--r--src/engine/SCons/Tool/python.py49
-rw-r--r--src/engine/SCons/Tool/python.xml36
-rw-r--r--src/engine/SCons/Tool/suncxx.py18
-rw-r--r--src/engine/SCons/Tool/textfile.py12
-rw-r--r--src/engine/SCons/Tool/textfile.xml10
-rw-r--r--src/engine/SCons/Tool/xgettext.py2
-rw-r--r--src/engine/SCons/Util.py36
-rw-r--r--src/engine/SCons/UtilTests.py36
-rw-r--r--src/engine/SCons/Variables/ListVariableTests.py2
-rw-r--r--src/engine/SCons/Variables/PackageVariableTests.py4
-rw-r--r--src/engine/SCons/cpp.py4
-rw-r--r--src/test_interrupts.py2
63 files changed, 1090 insertions, 477 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index ad936e4..3acd034 100755
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -15,6 +15,17 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- Added C:\msys64\mingw64\bin to default mingw and clang windows PATH's. This
is a reasonable default and also aligns with changes in Appveyor's VS2019 image.
- Drop support for Python 2.7. SCons will be Python 3.5+ going forward.
+ - Change SCons.Node.ValueWithMemo to consider any name passed when memoizing Value() nodes
+
+ From Jeremy Elson:
+ - Updated design doc to use the correct syntax for Depends()
+
+ From Adam Gross:
+ - Added support for taking instances of the Value class as implicit
+ dependencies.
+ - Added new module SCons.Scanner.Python to allow scanning .py files.
+ - Added support for explicitly passing a name when creating Value() nodes. This may be useful
+ when the value can't be converted to a string or if having a name is otherwise desirable.
From Andrew Morrow:
- Fix Issue #3469 - Fixed improper reuse of temporary and compiled files by Configure when changing
@@ -33,12 +44,19 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
- Improve performance of Subst by preventing unnecessary frame
allocations by no longer defining the *Subber classes inside of their
respective function calls.
+ - Improve performance of Subst in some cases by preventing
+ unnecessary calls to eval when a token is surrounded in braces
+ but is not a function call.
+ - Improve performance of subst by removing unnecessary recursion.
From Mats Wichmann:
- Remove deprecated SourceCode
- str.format syntax errors fixed
- a bunch of linter/checker syntax fixups
- Convert remaining uses of insecure/deprecated mktemp method.
+ - Clean up some duplications in manpage. Clarify portion of manpage on Dir and File nodes.
+ - Reduce needless list conversions.
+ - Fixed regex in Python scanner.
RELEASE 3.1.2 - Mon, 17 Dec 2019 02:06:27 +0000
diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in
index 3125824..3c2c0c2 100644
--- a/src/engine/MANIFEST.in
+++ b/src/engine/MANIFEST.in
@@ -40,6 +40,7 @@ SCons/Scanner/Fortran.py
SCons/Scanner/IDL.py
SCons/Scanner/LaTeX.py
SCons/Scanner/Prog.py
+SCons/Scanner/Python.py
SCons/Scanner/RC.py
SCons/Scanner/SWIG.py
SCons/SConf.py
@@ -140,6 +141,7 @@ SCons/Tool/pdf.py
SCons/Tool/pdflatex.py
SCons/Tool/pdftex.py
SCons/Tool/PharLapCommon.py
+SCons/Tool/python.py
SCons/Tool/qt.py
SCons/Tool/rmic.py
SCons/Tool/rpcgen.py
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 69bb19e..13949e5 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -230,7 +230,7 @@ class OverrideWarner(collections.UserDict):
def warn(self):
if self.already_warned:
return
- for k in list(self.keys()):
+ for k in self.keys():
if k in misleading_keywords:
alt = misleading_keywords[k]
msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k)
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index f28e201..b4286fd 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -173,7 +173,7 @@ class MyNode_without_target_from_source(object):
def builder_set(self, builder):
self.builder = builder
def has_builder(self):
- return not self.builder is None
+ return self.builder is not None
def set_explicit(self, is_explicit):
self.is_explicit = is_explicit
def has_explicit_builder(self):
@@ -205,7 +205,7 @@ class BuilderTestCase(unittest.TestCase):
"""Test simple Builder creation
"""
builder = SCons.Builder.Builder(action="foo")
- assert not builder is None, builder
+ assert builder is not None, builder
builder = SCons.Builder.Builder(action="foo", OVERRIDE='x')
x = builder.overrides['OVERRIDE']
assert x == 'x', x
@@ -429,7 +429,7 @@ class BuilderTestCase(unittest.TestCase):
return Foo(target)
builder = SCons.Builder.Builder(target_factory = FooFactory)
assert builder.target_factory is FooFactory
- assert not builder.source_factory is FooFactory
+ assert builder.source_factory is not FooFactory
def test_source_factory(self):
"""Test a Builder that creates source nodes of a specified class
@@ -440,7 +440,7 @@ class BuilderTestCase(unittest.TestCase):
global Foo
return Foo(source)
builder = SCons.Builder.Builder(source_factory = FooFactory)
- assert not builder.target_factory is FooFactory
+ assert builder.target_factory is not FooFactory
assert builder.source_factory is FooFactory
def test_splitext(self):
@@ -737,7 +737,7 @@ class BuilderTestCase(unittest.TestCase):
with open(str(t), 'w') as f:
f.write("function2\n")
for t in tlist:
- if not t in list(map(str, target)):
+ if t not in list(map(str, target)):
with open(t, 'w') as f:
f.write("function2\n")
return 1
@@ -768,7 +768,7 @@ class BuilderTestCase(unittest.TestCase):
with open(str(t), 'w') as f:
f.write("function3\n")
for t in tlist:
- if not t in list(map(str, target)):
+ if t not in list(map(str, target)):
with open(t, 'w') as f:
f.write("function3\n")
return 1
@@ -821,7 +821,7 @@ class BuilderTestCase(unittest.TestCase):
assert s == ['aaa.bar'], s
builder3 = SCons.Builder.Builder(action='bld3')
- assert not builder3.src_builder is builder1.src_builder
+ assert builder3.src_builder is not builder1.src_builder
builder4 = SCons.Builder.Builder(action='bld4',
src_suffix='.i',
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index 10c088d..9bb7ef3 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -36,7 +36,6 @@ import sys
import SCons
import SCons.Action
import SCons.Warnings
-from SCons.Util import PY3
cache_enabled = True
cache_debug = False
@@ -160,10 +159,7 @@ class CacheDir(object):
if path is None:
return
- if PY3:
- self._readconfig3(path)
- else:
- self._readconfig2(path)
+ self._readconfig3(path)
def _readconfig3(self, path):
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 0e242c4..ff22d01 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -33,7 +33,6 @@ import stat
from TestCmd import TestCmd
import SCons.CacheDir
-from SCons.Util import PY3
built_it = None
@@ -169,10 +168,7 @@ class ExceptionTestCase(unittest.TestCase):
os.remove(old_config)
try:
- if PY3:
- self._CacheDir._readconfig3(self._CacheDir.path)
- else:
- self._CacheDir._readconfig2(self._CacheDir.path)
+ self._CacheDir._readconfig3(self._CacheDir.path)
assert False, "Should have raised exception and did not"
except SCons.Errors.SConsEnvironmentError as e:
assert str(e) == "Failed to write cache configuration for {}".format(self._CacheDir.path)
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 3e23196..5e76e35 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -1854,7 +1854,7 @@ class Base(SubstitutionEnvironment):
uniq = {}
for executor in [n.get_executor() for n in nodes]:
uniq[executor] = 1
- for executor in list(uniq.keys()):
+ for executor in uniq.keys():
executor.add_pre_action(action)
return nodes
@@ -1864,7 +1864,7 @@ class Base(SubstitutionEnvironment):
uniq = {}
for executor in [n.get_executor() for n in nodes]:
uniq[executor] = 1
- for executor in list(uniq.keys()):
+ for executor in uniq.keys():
executor.add_post_action(action)
return nodes
@@ -2220,10 +2220,10 @@ class Base(SubstitutionEnvironment):
else:
return [self.subst(arg)]
- def Value(self, value, built_value=None):
+ def Value(self, value, built_value=None, name=None):
"""
"""
- return SCons.Node.Python.ValueWithMemo(value, built_value)
+ return SCons.Node.Python.ValueWithMemo(value, built_value, name)
def VariantDir(self, variant_dir, src_dir, duplicate=1):
variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0]
diff --git a/src/engine/SCons/Environment.xml b/src/engine/SCons/Environment.xml
index b1c2039..e1d5e74 100644
--- a/src/engine/SCons/Environment.xml
+++ b/src/engine/SCons/Environment.xml
@@ -65,15 +65,6 @@ env['BUILDERS']['NewBuilder'] = foo
</summary>
</cvar>
-<cvar name="Dir">
-<summary>
-<para>
-A function that converts a string
-into a Dir instance relative to the target being built.
-</para>
-</summary>
-</cvar>
-
<cvar name="ENV">
<summary>
<para>
@@ -130,15 +121,6 @@ env = Environment(ENV = {'PATH' : os.environ['PATH']})
</summary>
</cvar>
-<cvar name="File">
-<summary>
-<para>
-A function that converts a string into a File instance relative to the
-target being built.
-</para>
-</summary>
-</cvar>
-
<cvar name="SCANNERS">
<summary>
<para>
@@ -460,6 +442,8 @@ including another alias.
can be called multiple times for the same
alias to add additional targets to the alias,
or additional actions to the list for this alias.
+Aliases are global even if set through
+the construction environment method.
</para>
<para>
@@ -1163,17 +1147,16 @@ env.Decider('content')
</example_commands>
<para>
-In addition to the above already-available functions,
-the
+In addition to the above already-available functions, the
<varname>function</varname>
-argument may be an actual Python function
-that takes the following three arguments:
+argument may be a Python function you supply.
+Such a function must accept the following four arguments:
</para>
<para>
<variablelist>
<varlistentry>
-<term><parameter>dependency</parameter></term>
+<term><parameter class="function">dependency</parameter></term>
<listitem>
<para>
The Node (file) which
@@ -1187,7 +1170,7 @@ was built.
</listitem>
</varlistentry>
<varlistentry>
-<term><parameter>target</parameter></term>
+<term><parameter class="function">target</parameter></term>
<listitem>
<para>
The Node (file) being built.
@@ -1200,7 +1183,7 @@ has "changed."
</listitem>
</varlistentry>
<varlistentry>
-<term><parameter>prev_ni</parameter></term>
+<term><parameter class="function">prev_ni</parameter></term>
<listitem>
<para>
Stored information about the state of the
@@ -1216,12 +1199,17 @@ size, or content signature.
</listitem>
</varlistentry>
<varlistentry>
-<term><parameter>repo_node</parameter></term>
+<term><parameter class="function">repo_node</parameter></term>
<listitem>
<para>
-Use this node instead of the one specified by
+If set, use this Node instead of the one specified by
<varname>dependency</varname>
- to determine if the dependency has changed.
+to determine if the dependency has changed.
+This argument is optional so should be written
+as a default argument (typically it would be
+written as <literal>repo_node=None</literal>).
+A caller will normally only set this if the
+target only exists in a Repository.
</para>
</listitem>
</varlistentry>
@@ -1351,11 +1339,10 @@ cc_values = env.Dictionary('CC', 'CCFLAGS', 'CCCOM')
</arguments>
<summary>
<para>
-This returns a Directory Node,
-an object that represents the specified directory
-<varname>name</varname>.
+Returns Directory Node(s).
+A Directory Node is an object that represents a directory.
<varname>name</varname>
-can be a relative or absolute path.
+can be a relative or absolute path or a list of such paths.
<varname>directory</varname>
is an optional directory that will be used as the parent directory.
If no
@@ -1366,7 +1353,10 @@ is specified, the current script's directory is used as the parent.
<para>
If
<varname>name</varname>
-is a list, SCons returns a list of Dir nodes.
+is a single pathname, the corresponding node is returned.
+If
+<varname>name</varname>
+is a list, SCons returns a list of nodes.
Construction variables are expanded in
<varname>name</varname>.
</para>
@@ -1511,20 +1501,24 @@ if Execute("mkdir sub/dir/ectory"):
</arguments>
<summary>
<para>
-This returns a
-File Node,
-an object that represents the specified file
-<varname>name</varname>.
+Returns File Node(s).
+A File Node is an object that represents a file.
<varname>name</varname>
-can be a relative or absolute path.
+can be a relative or absolute path or a list of such paths.
<varname>directory</varname>
is an optional directory that will be used as the parent directory.
+If no
+<varname>directory</varname>
+is specified, the current script's directory is used as the parent.
</para>
<para>
If
<varname>name</varname>
-is a list, SCons returns a list of File nodes.
+is a single pathname, the corresponding node is returned.
+If
+<varname>name</varname>
+is a list, SCons returns a list of nodes.
Construction variables are expanded in
<varname>name</varname>.
</para>
@@ -2879,6 +2873,38 @@ function.
</summary>
</scons_function>
+<scons_function name="Split">
+<arguments>(arg)</arguments>
+<summary>
+<para>
+Returns a list of file names or other objects.
+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 <varname>arg</varname> is already a list,
+the list will be returned untouched.
+If <varname>arg</varname> is any other type of object,
+it will be returned as a list
+containing just the object.
+</para>
+
+<para>
+Example:
+</para>
+
+<example_commands>
+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
+""")
+</example_commands>
+</summary>
+</scons_function>
+
<scons_function name="subst">
<arguments signature="env">
(input, [raw, target, source, conv])
@@ -3055,7 +3081,7 @@ env.Tool('opengl', toolpath = ['build/tools'])
<scons_function name="Value">
<arguments>
-(value, [built_value])
+(value, [built_value], [name])
</arguments>
<summary>
<para>
@@ -3070,6 +3096,10 @@ will be rebuilt.
files are up-to-date.)
When using timestamp source signatures, Value Nodes'
timestamps are equal to the system time when the Node is created.
+<varname>name</varname> can be provided as an alternative name
+for the resulting <literal>Value</literal> node; this is advised
+if the <varname>value</varname> parameter can't be converted to
+a string.
</para>
<para>
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index f3779c7..01baba3 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -236,7 +236,7 @@ class SubstitutionTestCase(unittest.TestCase):
"""
env = SubstitutionEnvironment(XXX = 'x')
assert 'XXX' in env
- assert not 'YYY' in env
+ assert 'YYY' not in env
def test_items(self):
"""Test the SubstitutionEnvironment items() method
@@ -1759,7 +1759,7 @@ def exists(env):
env2.Dictionary('ZZZ')[5] = 6
assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
assert 4 in env2.Dictionary('YYY')
- assert not 4 in env1.Dictionary('YYY')
+ assert 4 not in env1.Dictionary('YYY')
assert 5 in env2.Dictionary('ZZZ')
assert 5 not in env1.Dictionary('ZZZ')
@@ -3289,6 +3289,10 @@ def generate(env):
v3 = env.Value('c', 'build-c')
assert v3.value == 'c', v3.value
+ v4 = env.Value(b'\x00\x0F', name='name')
+ assert v4.value == b'\x00\x0F', v4.value
+ assert v4.name == 'name', v4.name
+
def test_Environment_global_variable(self):
"""Test setting Environment variable to an Environment.Base subclass"""
@@ -3547,8 +3551,8 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
assert 'YYY' in env
assert 'YYY' in env2
assert 'YYY' in env3
- assert not 'ZZZ' in env
- assert not 'ZZZ' in env2
+ assert 'ZZZ' not in env
+ assert 'ZZZ' not in env2
assert 'ZZZ' in env3
def test_items(self):
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index 5d9c799..27b75b3 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -93,7 +93,7 @@ class AliasTestCase(unittest.TestCase):
a2 = SCons.Node.Alias.Alias('a')
assert a2.name == 'a', a2.name
- assert not a1 is a2
+ assert a1 is not a2
assert a1.name == a2.name
class AliasNodeInfoTestCase(unittest.TestCase):
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index e1d6f68..6f16256 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -1612,7 +1612,7 @@ class Dir(Base):
This clears any cached information that is invalidated by changing
the repository."""
- for node in list(self.entries.values()):
+ for node in self.entries.values():
if node != self.dir:
if node != self and isinstance(node, Dir):
node.__clearRepositoryCache(duplicate)
@@ -1623,7 +1623,7 @@ class Dir(Base):
except AttributeError:
pass
if duplicate is not None:
- node.duplicate=duplicate
+ node.duplicate = duplicate
def __resetDuplicate(self, node):
if node != self:
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 9c19481..bbfdd1b 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -3066,12 +3066,12 @@ class RepositoryTestCase(_tempdirTestCase):
assert r is d1, r
r = d2.rentry()
- assert not r is d2, r
+ assert r is not d2, r
r = str(r)
assert r == os.path.join(self.rep1, 'd2'), r
r = d3.rentry()
- assert not r is d3, r
+ assert r is not d3, r
r = str(r)
assert r == os.path.join(self.rep2, 'd3'), r
@@ -3079,12 +3079,12 @@ class RepositoryTestCase(_tempdirTestCase):
assert r is e1, r
r = e2.rentry()
- assert not r is e2, r
+ assert r is not e2, r
r = str(r)
assert r == os.path.join(self.rep1, 'e2'), r
r = e3.rentry()
- assert not r is e3, r
+ assert r is not e3, r
r = str(r)
assert r == os.path.join(self.rep2, 'e3'), r
@@ -3092,12 +3092,12 @@ class RepositoryTestCase(_tempdirTestCase):
assert r is f1, r
r = f2.rentry()
- assert not r is f2, r
+ assert r is not f2, r
r = str(r)
assert r == os.path.join(self.rep1, 'f2'), r
r = f3.rentry()
- assert not r is f3, r
+ assert r is not f3, r
r = str(r)
assert r == os.path.join(self.rep2, 'f3'), r
@@ -3127,12 +3127,12 @@ class RepositoryTestCase(_tempdirTestCase):
assert r is d1, r
r = d2.rdir()
- assert not r is d2, r
+ assert r is not d2, r
r = str(r)
assert r == os.path.join(self.rep1, 'd2'), r
r = d3.rdir()
- assert not r is d3, r
+ assert r is not d3, r
r = str(r)
assert r == os.path.join(self.rep3, 'd3'), r
@@ -3183,12 +3183,12 @@ class RepositoryTestCase(_tempdirTestCase):
assert r is f1, r
r = f2.rfile()
- assert not r is f2, r
+ assert r is not f2, r
r = str(r)
assert r == os.path.join(self.rep1, 'f2'), r
r = f3.rfile()
- assert not r is f3, r
+ assert r is not f3, r
r = f3.rstr()
assert r == os.path.join(self.rep3, 'f3'), r
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index d8179ff..8d9d3a9 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -1104,7 +1104,7 @@ class NodeTestCase(unittest.TestCase):
for kid in [n1, n3, n4, n6, n7, n9, n10, n12]:
assert kid in kids, kid
for kid in [n2, n5, n8, n11]:
- assert not kid in kids, kid
+ assert kid not in kids, kid
def test_all_children(self):
"""Test fetching all the "children" of a Node.
diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py
index a5bcd4b..68c6ee8 100644
--- a/src/engine/SCons/Node/Python.py
+++ b/src/engine/SCons/Node/Python.py
@@ -88,7 +88,7 @@ class Value(SCons.Node.Node):
NodeInfo = ValueNodeInfo
BuildInfo = ValueBuildInfo
- def __init__(self, value, built_value=None):
+ def __init__(self, value, built_value=None, name=None):
SCons.Node.Node.__init__(self)
self.value = value
self.changed_since_last_build = 6
@@ -96,6 +96,13 @@ class Value(SCons.Node.Node):
if built_value is not None:
self.built_value = built_value
+ # Set a name so it can be a child of a node and not break
+ # its parent's implementation of Node.get_contents.
+ if name:
+ self.name = name
+ else:
+ self.name = str(value)
+
def str_for_display(self):
return repr(self.value)
@@ -177,23 +184,26 @@ class Value(SCons.Node.Node):
return contents
-def ValueWithMemo(value, built_value=None):
+def ValueWithMemo(value, built_value=None, name=None):
+ """
+ Memoized Value() node factory.
+ """
global _memo_lookup_map
# No current support for memoizing a value that needs to be built.
if built_value:
- return Value(value, built_value)
+ return Value(value, built_value, name=name)
try:
- memo_lookup_key = hash(value)
+ memo_lookup_key = hash((value, name))
except TypeError:
# Non-primitive types will hit this codepath.
- return Value(value)
+ return Value(value, name=name)
try:
return _memo_lookup_map[memo_lookup_key]
except KeyError:
- v = Value(value)
+ v = Value(value, built_value, name)
_memo_lookup_map[memo_lookup_key] = v
return v
diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py
index dbb4ec8..51a49c0 100644
--- a/src/engine/SCons/Node/PythonTests.py
+++ b/src/engine/SCons/Node/PythonTests.py
@@ -64,6 +64,12 @@ class ValueTestCase(unittest.TestCase):
v2.build()
assert v2.built_value == 'faked', v2.built_value
+ v3 = SCons.Node.Python.Value(b'\x00\x0F', name='name')
+ v3.executor = fake_executor()
+ v3.build()
+ assert v3.name == 'name', v3.name
+ assert v3.built_value == 'faked', v3.built_value
+
def test_read(self):
"""Test the Value.read() method
"""
@@ -98,6 +104,9 @@ class ValueTestCase(unittest.TestCase):
assert csig == 'None', csig
+
+
+
class ValueNodeInfoTestCase(unittest.TestCase):
def test___init__(self):
"""Test ValueNodeInfo initialization"""
@@ -112,6 +121,18 @@ class ValueBuildInfoTestCase(unittest.TestCase):
bi = SCons.Node.Python.ValueBuildInfo()
+class ValueChildTestCase(unittest.TestCase):
+ def test___init__(self):
+ """Test support for a Value() being an implicit dependency of a Node"""
+ value = SCons.Node.Python.Value('v')
+ node = SCons.Node.Node()
+ node._func_get_contents = 2 # Pretend to be a Dir.
+ node.add_to_implicit([value])
+ contents = node.get_contents()
+ expected_contents = '%s %s\n' % (value.get_csig(), value.name)
+ assert contents == expected_contents
+
+
class ValueMemoTestCase(unittest.TestCase):
def test_memo(self):
"""Test memoization"""
@@ -144,6 +165,19 @@ class ValueMemoTestCase(unittest.TestCase):
v4 = SCons.Node.Python.ValueWithMemo(a)
assert v3 is not v4
+ def test_value_set_name(self):
+ """ Confirm setting name and caching takes the name into account """
+
+ v1 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name')
+ v2 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name2')
+ v3 = SCons.Node.Python.ValueWithMemo('Jibberish')
+
+ self.assertEqual(v1.name,'name', msg=v1.name)
+ self.assertEqual(v2.name,'name2', msg=v2.name)
+ self.assertEqual(v3.name,'Jibberish', msg=v3.name)
+ self.assertTrue(v1 is not v2, msg="v1 and v2 should be different as they have different names but same values")
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/src/engine/SCons/PathListTests.py b/src/engine/SCons/PathListTests.py
index 104be73..09b1132 100644
--- a/src/engine/SCons/PathListTests.py
+++ b/src/engine/SCons/PathListTests.py
@@ -185,7 +185,7 @@ class PathListTestCase(unittest.TestCase):
x3 = SCons.PathList.PathList('x')
- assert not x1 is x3, (x1, x3)
+ assert x1 is not x3, (x1, x3)
if __name__ == "__main__":
diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py
index 058241d..5e9a358 100644
--- a/src/engine/SCons/Platform/__init__.py
+++ b/src/engine/SCons/Platform/__init__.py
@@ -195,7 +195,7 @@ class TempFileMunge(object):
# Default to the .lnk suffix for the benefit of the Phar Lap
# linkloc linker, which likes to append an .lnk suffix if
# none is given.
- if env.has_key('TEMPFILESUFFIX'):
+ if 'TEMPFILESUFFIX' in env:
suffix = env.subst('$TEMPFILESUFFIX')
else:
suffix = '.lnk'
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index b2a6357..50a1329 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -133,8 +133,8 @@ def CreateConfigHBuilder(env):
_stringConfigH)
sconfigHBld = SCons.Builder.Builder(action=action)
env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} )
- for k in list(_ac_config_hs.keys()):
- env.SConfigHBuilder(k, env.Value(_ac_config_hs[k]))
+ for k, v in _ac_config_hs.items():
+ env.SConfigHBuilder(k, env.Value(v))
class SConfWarning(SCons.Warnings.Warning):
@@ -717,7 +717,7 @@ class SConfBase(object):
"""Adds all the tests given in the tests dictionary to this SConf
instance
"""
- for name in list(tests.keys()):
+ for name in tests.keys():
self.AddTest(name, tests[name])
def _createDir( self, node ):
diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py
index d40a7b6..782072d 100644
--- a/src/engine/SCons/SConsignTests.py
+++ b/src/engine/SCons/SConsignTests.py
@@ -337,7 +337,7 @@ class SConsignFileTestCase(SConsignTestCase):
SCons.SConsign.ForDirectory(DummyNode(test.workpath('dir')))
- assert not SCons.SConsign.DataBase is None, SCons.SConsign.DataBase
+ assert SCons.SConsign.DataBase is not None, SCons.SConsign.DataBase
assert fake_dbm.name == file, fake_dbm.name
assert fake_dbm.mode == "c", fake_dbm.mode
diff --git a/src/engine/SCons/Scanner/Python.py b/src/engine/SCons/Scanner/Python.py
new file mode 100644
index 0000000..deb2241
--- /dev/null
+++ b/src/engine/SCons/Scanner/Python.py
@@ -0,0 +1,171 @@
+"""SCons.Scanner.Python
+
+This module implements the dependency scanner for Python code.
+
+One important note about the design is that this does not take any dependencies
+upon packages or binaries in the Python installation unless they are listed in
+PYTHONPATH. To do otherwise would have required code to determine where the
+Python installation is, which is outside of the scope of a scanner like this.
+If consumers want to pick up dependencies upon these packages, they must put
+those directories in PYTHONPATH.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import itertools
+import os
+import re
+import SCons.Scanner
+
+# Capture python "from a import b" and "import a" statements.
+from_cre = re.compile(r'^\s*from\s+([^\s]+)\s+import\s+(.*)', re.M)
+import_cre = re.compile(r'^\s*import\s+([^\s]+)', re.M)
+
+
+def path_function(env, dir=None, target=None, source=None, argument=None):
+ """Retrieves a tuple with all search paths."""
+ paths = env['ENV'].get('PYTHONPATH', '').split(os.pathsep)
+ if source:
+ paths.append(source[0].dir.abspath)
+ return tuple(paths)
+
+
+def find_include_names(node):
+ """
+ Scans the node for all imports.
+
+ Returns a list of tuples. Each tuple has two elements:
+ 1. The main import (e.g. module, module.file, module.module2)
+ 2. Additional optional imports that could be functions or files
+ in the case of a "from X import Y" statement. In the case of a
+ normal "import" statement, this is None.
+ """
+ text = node.get_text_contents()
+ all_matches = []
+ matches = from_cre.findall(text)
+ if matches:
+ for match in matches:
+ imports = [i.strip() for i in match[1].split(',')]
+
+ # Add some custom logic to strip out "as" because the regex
+ # includes it.
+ last_import_split = imports[-1].split()
+ if len(last_import_split) > 1:
+ imports[-1] = last_import_split[0]
+
+ all_matches.append((match[0], imports))
+
+ matches = import_cre.findall(text)
+ if matches:
+ for match in matches:
+ all_matches.append((match, None))
+
+ return all_matches
+
+
+def scan(node, env, path=()):
+ # cache the includes list in node so we only scan it once:
+ if node.includes is not None:
+ includes = node.includes
+ else:
+ includes = find_include_names(node)
+ # Intern the names of the include files. Saves some memory
+ # if the same header is included many times.
+ node.includes = list(map(SCons.Util.silent_intern, includes))
+
+ # XXX TODO: Sort?
+ nodes = []
+ if callable(path):
+ path = path()
+ for module, imports in includes:
+ is_relative = module.startswith('.')
+ if is_relative:
+ # This is a relative include, so we must ignore PYTHONPATH.
+ module_lstripped = module.lstrip('.')
+ # One dot is current directory, two is parent, three is
+ # grandparent, etc.
+ num_parents = len(module) - len(module_lstripped) - 1
+ current_dir = node.get_dir()
+ for i in itertools.repeat(None, num_parents):
+ current_dir = current_dir.up()
+
+ search_paths = [current_dir.abspath]
+ search_string = module_lstripped
+ else:
+ search_paths = path
+ search_string = module
+
+ module_components = search_string.split('.')
+ for search_path in search_paths:
+ candidate_path = os.path.join(search_path, *module_components)
+ # The import stored in "module" could refer to a directory or file.
+ import_dirs = []
+ if os.path.isdir(candidate_path):
+ import_dirs = module_components
+
+ # Because this resolved to a directory, there is a chance that
+ # additional imports (e.g. from module import A, B) could refer
+ # to files to import.
+ if imports:
+ for imp in imports:
+ file = os.path.join(candidate_path, imp + '.py')
+ if os.path.isfile(file):
+ nodes.append(file)
+ elif os.path.isfile(candidate_path + '.py'):
+ nodes.append(candidate_path + '.py')
+ import_dirs = module_components[:-1]
+
+ # We can ignore imports because this resolved to a file. Any
+ # additional imports (e.g. from module.file import A, B) would
+ # only refer to functions in this file.
+
+ # Take a dependency on all __init__.py files from all imported
+ # packages unless it's a relative import. If it's a relative
+ # import, we don't need to take the dependency because Python
+ # requires that all referenced packages have already been imported,
+ # which means that the dependency has already been established.
+ if import_dirs and not is_relative:
+ for i in range(len(import_dirs)):
+ init_components = module_components[:i+1] + ['__init__.py']
+ init_path = os.path.join(search_path, *(init_components))
+ if os.path.isfile(init_path):
+ nodes.append(init_path)
+ break
+
+ return sorted(nodes)
+
+
+PythonSuffixes = ['.py']
+PythonScanner = SCons.Scanner.Base(scan, name='PythonScanner',
+ skeys=PythonSuffixes,
+ path_function=path_function, recursive=1)
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Scanner/PythonTests.py b/src/engine/SCons/Scanner/PythonTests.py
new file mode 100644
index 0000000..0d4e628
--- /dev/null
+++ b/src/engine/SCons/Scanner/PythonTests.py
@@ -0,0 +1,269 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.compat
+
+import collections
+import os
+import unittest
+
+import TestCmd
+
+import SCons.Node.FS
+import SCons.Scanner.Python
+
+test = TestCmd.TestCmd(workdir='')
+test.dir_fixture('python_scanner')
+
+if os.path.normcase('foo') == os.path.normcase('FOO'):
+ my_normpath = os.path.normcase
+else:
+ my_normpath = os.path.normpath
+
+
+def deps_match(self, deps, headers):
+ global my_normpath
+ scanned = list(map(my_normpath, list(map(str, deps))))
+ expect = list(map(my_normpath, headers))
+ self.assertTrue(scanned == expect,
+ "expect %s != scanned %s" % (expect, scanned))
+
+
+# Copied from LaTeXTests.py.
+class DummyEnvironment(collections.UserDict):
+ def __init__(self, **kw):
+ collections.UserDict.__init__(self)
+ self.data.update(kw)
+ self.fs = SCons.Node.FS.FS(test.workpath(''))
+ self['ENV'] = {}
+
+ def Dictionary(self, *args):
+ return self.data
+
+ def subst(self, strSubst, target=None, source=None, conv=None):
+ if strSubst[0] == '$':
+ return self.data[strSubst[1:]]
+ return strSubst
+
+ def subst_list(self, strSubst, target=None, source=None, conv=None):
+ if strSubst[0] == '$':
+ return [self.data[strSubst[1:]]]
+ return [[strSubst]]
+
+ def subst_path(self, path, target=None, source=None, conv=None):
+ if not isinstance(path, list):
+ path = [path]
+ return list(map(self.subst, path))
+
+ def get_calculator(self):
+ return None
+
+ def get_factory(self, factory):
+ return factory or self.fs.File
+
+ def Dir(self, filename):
+ return self.fs.Dir(filename)
+
+ def File(self, filename):
+ return self.fs.File(filename)
+
+
+class PythonScannerTestPythonPath(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ env['ENV']['PYTHONPATH'] = test.workpath('')
+ path = s.path(env)
+ deps = s(env.File('imports_simple_package.py'), env, path)
+ files = ['simple_package/__init__.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestPythonCallablePath(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ env['ENV']['PYTHONPATH'] = test.workpath('')
+ deps = s(env.File('imports_simple_package.py'), env,
+ lambda : s.path(env))
+ files = ['simple_package/__init__.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportSimplePackage(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('imports_simple_package.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py']
+ deps_match(self, deps, files)
+
+ # Repeat the test in case there are any issues caching includes.
+ deps = s(node, env, path)
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('import_simple_package_module1_as.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('import_simple_package_module1.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('from_import_simple_package_module1.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('from_import_simple_package_module1_as.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestFromImportSimplePackageModulesNoSpace(
+ unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('from_import_simple_package_modules_no_space.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py',
+ 'simple_package/module2.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestFromImportSimplePackageModulesWithSpace(
+ unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('from_import_simple_package_modules_with_space.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['simple_package/__init__.py', 'simple_package/module1.py',
+ 'simple_package/module2.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestCurdirReferenceScript(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.Dir('curdir_reference').File('script.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['curdir_reference/helper.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportsNested3(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File('imports_nested3.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['nested1/__init__.py', 'nested1/nested2/__init__.py',
+ 'nested1/nested2/nested3/__init__.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportsGrandparentModule(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File(
+ 'nested1/nested2/nested3/imports_grandparent_module.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ # Note: there is some ambiguity here in what the scanner should return.
+ # Relative imports require that the referenced packages have already
+ # been imported.
+ files = ['nested1/module.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportsParentModule(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File(
+ 'nested1/nested2/nested3/imports_parent_module.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['nested1/nested2/module.py']
+ deps_match(self, deps, files)
+
+
+class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase):
+ def runTest(self):
+ env = DummyEnvironment()
+ s = SCons.Scanner.Python.PythonScanner
+ node = env.File(
+ 'nested1/nested2/nested3/imports_parent_then_submodule.py')
+ path = s.path(env, source=[node])
+ deps = s(node, env, path)
+ files = ['nested1/nested2a/module.py']
+ deps_match(self, deps, files)
+
+
+if __name__ == "__main__":
+ unittest.main()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Scanner/RCTests.py b/src/engine/SCons/Scanner/RCTests.py
index 551e613..347149c 100644
--- a/src/engine/SCons/Scanner/RCTests.py
+++ b/src/engine/SCons/Scanner/RCTests.py
@@ -82,7 +82,7 @@ class DummyEnvironment(collections.UserDict):
def Dictionary(self, *args):
return self.data
- def subst(self, arg, target=None, source=None, conv=None):
+ def subst(self, strSubst, target=None, source=None, conv=None):
if strSubst[0] == '$':
return self.data[strSubst[1:]]
return strSubst
diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py
index cc4f23c..59299f1 100644
--- a/src/engine/SCons/Script/Interactive.py
+++ b/src/engine/SCons/Script/Interactive.py
@@ -247,7 +247,7 @@ version Prints SCons version information.
while n:
n = walker.get_next()
- for node in list(seen_nodes.keys()):
+ for node in seen_nodes.keys():
# Call node.clear() to clear most of the state
node.clear()
# node.clear() doesn't reset node.state, so call
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index f9c8384..a0d7f4c 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -743,9 +743,9 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
modname = os.path.basename(pathname)[:-len(sfx)]
site_m = {"__file__": pathname, "__name__": modname, "__doc__": None}
re_special = re.compile("__[^_]+__")
- for k in list(m.__dict__.keys()):
+ for k, v in m.__dict__.items():
if not re_special.match(k):
- site_m[k] = m.__dict__[k]
+ site_m[k] = v
# This is the magic.
exec(compile(fp.read(), fp.name, 'exec'), site_m)
diff --git a/src/engine/SCons/Script/Main.xml b/src/engine/SCons/Script/Main.xml
index 5c68dee..b54df0e 100644
--- a/src/engine/SCons/Script/Main.xml
+++ b/src/engine/SCons/Script/Main.xml
@@ -312,7 +312,7 @@ The options supported are:
<term><literal>cache_debug</literal></term>
<listitem>
<para>
-which corresponds to --cache-debug;
+which corresponds to <option>--cache-debug</option>;
</para>
</listitem>
</varlistentry>
@@ -320,7 +320,7 @@ which corresponds to --cache-debug;
<term><literal>cache_disable</literal></term>
<listitem>
<para>
-which corresponds to --cache-disable;
+which corresponds to <option>--cache-disable</option>;
</para>
</listitem>
</varlistentry>
@@ -328,7 +328,7 @@ which corresponds to --cache-disable;
<term><literal>cache_force</literal></term>
<listitem>
<para>
-which corresponds to --cache-force;
+which corresponds to <option>--cache-force</option>;
</para>
</listitem>
</varlistentry>
@@ -336,7 +336,7 @@ which corresponds to --cache-force;
<term><literal>cache_show</literal></term>
<listitem>
<para>
-which corresponds to --cache-show;
+which corresponds to <option>--cache-show</option>;
</para>
</listitem>
</varlistentry>
@@ -344,7 +344,8 @@ which corresponds to --cache-show;
<term><literal>clean</literal></term>
<listitem>
<para>
-which corresponds to -c, --clean and --remove;
+which corresponds to <option>-c</option>, <option>--clean</option>
+and <option>--remove</option>;
</para>
</listitem>
</varlistentry>
@@ -352,7 +353,7 @@ which corresponds to -c, --clean and --remove;
<term><literal>config</literal></term>
<listitem>
<para>
-which corresponds to --config;
+which corresponds to <option>--config</option>;
</para>
</listitem>
</varlistentry>
@@ -360,7 +361,7 @@ which corresponds to --config;
<term><literal>directory</literal></term>
<listitem>
<para>
-which corresponds to -C and --directory;
+which corresponds to <option>-C</option> and <option>--directory</option>;
</para>
</listitem>
</varlistentry>
@@ -368,7 +369,7 @@ which corresponds to -C and --directory;
<term><literal>diskcheck</literal></term>
<listitem>
<para>
-which corresponds to --diskcheck
+which corresponds to <option>--diskcheck</option>;
</para>
</listitem>
</varlistentry>
@@ -376,7 +377,7 @@ which corresponds to --diskcheck
<term><literal>duplicate</literal></term>
<listitem>
<para>
-which corresponds to --duplicate;
+which corresponds to <option>--duplicate</option>;
</para>
</listitem>
</varlistentry>
@@ -384,7 +385,7 @@ which corresponds to --duplicate;
<term><literal>file</literal></term>
<listitem>
<para>
-which corresponds to -f, --file, --makefile and --sconstruct;
+which corresponds to <option>-f</option>, <option>--file</option>, <option>--makefile</option> and <option>--sconstruct</option>;
</para>
</listitem>
</varlistentry>
@@ -392,7 +393,7 @@ which corresponds to -f, --file, --makefile and --sconstruct;
<term><literal>help</literal></term>
<listitem>
<para>
-which corresponds to -h and --help;
+which corresponds to <option>-h</option> and <option>--help</option>;
</para>
</listitem>
</varlistentry>
@@ -400,7 +401,7 @@ which corresponds to -h and --help;
<term><literal>ignore_errors</literal></term>
<listitem>
<para>
-which corresponds to --ignore-errors;
+which corresponds to <option>--ignore-errors</option>;
</para>
</listitem>
</varlistentry>
@@ -408,7 +409,7 @@ which corresponds to --ignore-errors;
<term><literal>implicit_cache</literal></term>
<listitem>
<para>
-which corresponds to --implicit-cache;
+which corresponds to <option>--implicit-cache</option>;
</para>
</listitem>
</varlistentry>
@@ -416,7 +417,7 @@ which corresponds to --implicit-cache;
<term><literal>implicit_deps_changed</literal></term>
<listitem>
<para>
-which corresponds to --implicit-deps-changed;
+which corresponds to <option>--implicit-deps-changed</option>;
</para>
</listitem>
</varlistentry>
@@ -424,7 +425,7 @@ which corresponds to --implicit-deps-changed;
<term><literal>implicit_deps_unchanged</literal></term>
<listitem>
<para>
-which corresponds to --implicit-deps-unchanged;
+which corresponds to <option>--implicit-deps-unchanged</option>;
</para>
</listitem>
</varlistentry>
@@ -432,7 +433,7 @@ which corresponds to --implicit-deps-unchanged;
<term><literal>interactive</literal></term>
<listitem>
<para>
-which corresponds to --interact and --interactive;
+which corresponds to <option>--interact</option> and <option>--interactive</option>;
</para>
</listitem>
</varlistentry>
@@ -440,7 +441,7 @@ which corresponds to --interact and --interactive;
<term><literal>keep_going</literal></term>
<listitem>
<para>
-which corresponds to -k and --keep-going;
+which corresponds to <option>-k</option> and <option>--keep-going</option>;
</para>
</listitem>
</varlistentry>
@@ -448,7 +449,7 @@ which corresponds to -k and --keep-going;
<term><literal>max_drift</literal></term>
<listitem>
<para>
-which corresponds to --max-drift;
+which corresponds to <option>--max-drift</option>;
</para>
</listitem>
</varlistentry>
@@ -456,7 +457,9 @@ which corresponds to --max-drift;
<term><literal>no_exec</literal></term>
<listitem>
<para>
-which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
+which corresponds to <option>-n</option>,
+<option>--no-exec</option>, <option>--just-print</option>,
+<option>--dry-run</option> and <option>--recon</option>;
</para>
</listitem>
</varlistentry>
@@ -464,7 +467,7 @@ which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
<term><literal>no_site_dir</literal></term>
<listitem>
<para>
-which corresponds to --no-site-dir;
+which corresponds to <option>--no-site-dir</option>;
</para>
</listitem>
</varlistentry>
@@ -472,7 +475,7 @@ which corresponds to --no-site-dir;
<term><literal>num_jobs</literal></term>
<listitem>
<para>
-which corresponds to -j and --jobs;
+which corresponds to <option>-j</option> and <option>--jobs</option>;
</para>
</listitem>
</varlistentry>
@@ -480,7 +483,7 @@ which corresponds to -j and --jobs;
<term><literal>profile_file</literal></term>
<listitem>
<para>
-which corresponds to --profile;
+which corresponds to <option>--profile</option>;
</para>
</listitem>
</varlistentry>
@@ -488,7 +491,7 @@ which corresponds to --profile;
<term><literal>question</literal></term>
<listitem>
<para>
-which corresponds to -q and --question;
+which corresponds to <option>-q</option> and <option>--question</option>;
</para>
</listitem>
</varlistentry>
@@ -496,7 +499,7 @@ which corresponds to -q and --question;
<term><literal>random</literal></term>
<listitem>
<para>
-which corresponds to --random;
+which corresponds to <option>--random</option>;
</para>
</listitem>
</varlistentry>
@@ -504,7 +507,7 @@ which corresponds to --random;
<term><literal>repository</literal></term>
<listitem>
<para>
-which corresponds to -Y, --repository and --srcdir;
+which corresponds to <option>-Y</option>, <option>--repository</option> and <option>--srcdir</option>;
</para>
</listitem>
</varlistentry>
@@ -512,7 +515,7 @@ which corresponds to -Y, --repository and --srcdir;
<term><literal>silent</literal></term>
<listitem>
<para>
-which corresponds to -s, --silent and --quiet;
+which corresponds to <option>-s</option>, <option>--silent</option> and <option>--quiet</option>;
</para>
</listitem>
</varlistentry>
@@ -520,7 +523,7 @@ which corresponds to -s, --silent and --quiet;
<term><literal>site_dir</literal></term>
<listitem>
<para>
-which corresponds to --site-dir;
+which corresponds to <option>--site-dir</option>;
</para>
</listitem>
</varlistentry>
@@ -528,7 +531,7 @@ which corresponds to --site-dir;
<term><literal>stack_size</literal></term>
<listitem>
<para>
-which corresponds to --stack-size;
+which corresponds to <option>--stack-size</option>;
</para>
</listitem>
</varlistentry>
@@ -536,7 +539,7 @@ which corresponds to --stack-size;
<term><literal>taskmastertrace_file</literal></term>
<listitem>
<para>
-which corresponds to --taskmastertrace; and
+which corresponds to <option>--taskmastertrace</option>; and
</para>
</listitem>
</varlistentry>
@@ -544,7 +547,7 @@ which corresponds to --taskmastertrace; and
<term><literal>warn</literal></term>
<listitem>
<para>
-which corresponds to --warn and --warning.
+which corresponds to <option>--warn</option> and <option>--warning</option>.
</para>
</listitem>
</varlistentry>
@@ -553,7 +556,7 @@ which corresponds to --warn and --warning.
<para>
See the documentation for the
-corresponding command line object for information about each specific
+corresponding command line option for information about each specific
option.
</para>
</summary>
@@ -749,7 +752,8 @@ line options from a SConscript file. The options supported are:
<term><literal>clean</literal></term>
<listitem>
<para>
-which corresponds to -c, --clean and --remove;
+which corresponds to <option>-c</option>, <option>--clean</option>
+and <option>--remove</option>;
</para>
</listitem>
</varlistentry>
@@ -757,7 +761,7 @@ which corresponds to -c, --clean and --remove;
<term><literal>duplicate</literal></term>
<listitem>
<para>
-which corresponds to --duplicate;
+which corresponds to <option>--duplicate</option>;
</para>
</listitem>
</varlistentry>
@@ -765,7 +769,7 @@ which corresponds to --duplicate;
<term><literal>help</literal></term>
<listitem>
<para>
-which corresponds to -h and --help;
+which corresponds to <option>-h</option> and <option>--help</option>;
</para>
</listitem>
</varlistentry>
@@ -773,7 +777,7 @@ which corresponds to -h and --help;
<term><literal>implicit_cache</literal></term>
<listitem>
<para>
-which corresponds to --implicit-cache;
+which corresponds to <option>--implicit-cache</option>;
</para>
</listitem>
</varlistentry>
@@ -781,7 +785,7 @@ which corresponds to --implicit-cache;
<term><literal>max_drift</literal></term>
<listitem>
<para>
-which corresponds to --max-drift;
+which corresponds to <option>--max-drift</option>;
</para>
</listitem>
</varlistentry>
@@ -789,7 +793,9 @@ which corresponds to --max-drift;
<term><literal>no_exec</literal></term>
<listitem>
<para>
-which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
+which corresponds to <option>-n</option>, <option>--no-exec</option>,
+<option>--just-print</option>, <option>--dry-run</option>
+and <option>--recon</option>;
</para>
</listitem>
</varlistentry>
@@ -797,7 +803,7 @@ which corresponds to -n, --no-exec, --just-print, --dry-run and --recon;
<term><literal>num_jobs</literal></term>
<listitem>
<para>
-which corresponds to -j and --jobs;
+which corresponds to <option>-j</option> and <option>--jobs</option>;
</para>
</listitem>
</varlistentry>
@@ -805,7 +811,7 @@ which corresponds to -j and --jobs;
<term><literal>random</literal></term>
<listitem>
<para>
-which corresponds to --random; and
+which corresponds to <option>--random</option>; and
</para>
</listitem>
</varlistentry>
@@ -813,7 +819,7 @@ which corresponds to --random; and
<term><literal>silent</literal></term>
<listitem>
<para>
-which corresponds to --silent.
+which corresponds to <option>--silent</option>.
</para>
</listitem>
</varlistentry>
@@ -830,7 +836,7 @@ which corresponds to --stack-size.
<para>
See the documentation for the
-corresponding command line object for information about each specific
+corresponding command line option for information about each specific
option.
</para>
diff --git a/src/engine/SCons/Script/SConscript.xml b/src/engine/SCons/Script/SConscript.xml
index 874c110..a1e0129 100644
--- a/src/engine/SCons/Script/SConscript.xml
+++ b/src/engine/SCons/Script/SConscript.xml
@@ -252,16 +252,16 @@ This specifies help text to be printed if the
<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/Subst.py b/src/engine/SCons/Subst.py
index 664cd6c..a1ef053 100644
--- a/src/engine/SCons/Subst.py
+++ b/src/engine/SCons/Subst.py
@@ -375,23 +375,29 @@ class StringSubber(object):
if key[0] == '{' or '.' in key:
if key[0] == '{':
key = key[1:-1]
- try:
- s = eval(key, self.gvars, lvars)
- except KeyboardInterrupt:
- raise
- except Exception as e:
- if e.__class__ in AllowableExceptions:
- return ''
- raise_exception(e, lvars['TARGETS'], s)
+
+ # 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:
- if key in lvars:
- s = lvars[key]
- elif key in self.gvars:
- s = self.gvars[key]
- elif NameError not in AllowableExceptions:
- raise_exception(NameError(key), lvars['TARGETS'], s)
- else:
- return ''
+ try:
+ s = eval(key, self.gvars, lvars)
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ if e.__class__ in AllowableExceptions:
+ return ''
+ raise_exception(e, lvars['TARGETS'], 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
@@ -493,6 +499,21 @@ class ListSubber(collections.UserList):
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.
@@ -524,23 +545,35 @@ class ListSubber(collections.UserList):
if key[0] == '{' or key.find('.') >= 0:
if key[0] == '{':
key = key[1:-1]
- try:
- s = eval(key, self.gvars, lvars)
- except KeyboardInterrupt:
- raise
- except Exception as e:
- if e.__class__ in AllowableExceptions:
- return
- raise_exception(e, lvars['TARGETS'], s)
+
+ # 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:
- if key in lvars:
- s = lvars[key]
- elif key in self.gvars:
- s = self.gvars[key]
- elif NameError not in AllowableExceptions:
- raise_exception(NameError(), lvars['TARGETS'], s)
- else:
- return
+ try:
+ s = eval(key, self.gvars, lvars)
+ except KeyboardInterrupt:
+ raise
+ except Exception as e:
+ if e.__class__ in AllowableExceptions:
+ return
+ raise_exception(e, lvars['TARGETS'], 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
diff --git a/src/engine/SCons/Subst.xml b/src/engine/SCons/Subst.xml
index 980a9ad..77372ce 100644
--- a/src/engine/SCons/Subst.xml
+++ b/src/engine/SCons/Subst.xml
@@ -39,7 +39,7 @@ or
<literal>IndexError</literal>
exception will expand to a
<literal>''</literal>
-(a null string) and not cause scons to fail.
+(an empty string) and not cause scons to fail.
All exceptions not in the specified list
will generate an error message
and terminate processing.
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index 06fc94c..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()
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index c0c77b0..1a47230 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -146,7 +146,7 @@ class Node(object):
pass
def has_builder(self):
- return not self.builder is None
+ return self.builder is not None
def is_derived(self):
return self.has_builder or self.side_effect
@@ -935,7 +935,7 @@ class TaskmasterTestCase(unittest.TestCase):
except SCons.Errors.UserError:
pass
else:
- raise TestFailed("did not catch expected UserError")
+ self.fail("did not catch expected UserError")
def raise_BuildError():
raise SCons.Errors.BuildError
@@ -948,7 +948,7 @@ class TaskmasterTestCase(unittest.TestCase):
except SCons.Errors.BuildError:
pass
else:
- raise TestFailed("did not catch expected BuildError")
+ self.fail("did not catch expected BuildError")
# On a generic (non-BuildError) exception from a Builder,
# the target should throw a BuildError exception with the
@@ -968,7 +968,7 @@ class TaskmasterTestCase(unittest.TestCase):
exc_traceback = sys.exc_info()[2]
assert isinstance(e.exc_info[2], type(exc_traceback)), e.exc_info[2]
else:
- raise TestFailed("did not catch expected BuildError")
+ self.fail("did not catch expected BuildError")
built_text = None
cache_text = []
@@ -1049,7 +1049,7 @@ class TaskmasterTestCase(unittest.TestCase):
assert cache_text == ["n1 retrieved"], cache_text
# If no binfo exists anymore, something has gone wrong...
has_binfo = hasattr(n1, 'binfo')
- assert has_binfo == True, has_binfo
+ assert has_binfo, has_binfo
def test_exception(self):
"""Test generic Taskmaster exception handling
diff --git a/src/engine/SCons/Tool/DCommon.xml b/src/engine/SCons/Tool/DCommon.xml
index 7cc47da..6d907c6 100644
--- a/src/engine/SCons/Tool/DCommon.xml
+++ b/src/engine/SCons/Tool/DCommon.xml
@@ -27,6 +27,7 @@ See its __doc__ string for a discussion of the format.
<summary>
<para>
The D compiler to use.
+See also &cv-link-SHDC; for compiling to shared objects.
</para>
</summary>
</cvar>
@@ -37,6 +38,18 @@ The D compiler to use.
The command line used to compile a D file to an object file.
Any options specified in the &cv-link-DFLAGS; construction variable
is included on this command line.
+See also &cv-link-SHDCOM; for compiling to shared objects.
+</para>
+</summary>
+</cvar>
+
+<cvar name="DCOMSTR">
+<summary>
+<para>
+If set, the string displayed when a D source file
+is compiled to a (static) object file.
+If not set, then &cv-link-DCOM; (the command line) is displayed.
+See also &cv-link-SHDCOMSTR; for compiling to shared objects.
</para>
</summary>
</cvar>
@@ -181,6 +194,7 @@ DLIBLINKSUFFIX.
<summary>
<para>
Name of the linker to use for linking systems including D sources.
+See also &cv-link-SHDLINK; for linking shared objects.
</para>
</summary>
</cvar>
@@ -189,6 +203,7 @@ Name of the linker to use for linking systems including D sources.
<summary>
<para>
The command line to use when linking systems including D sources.
+See also &cv-link-SHDLINKCOM; for linking shared objects.
</para>
</summary>
</cvar>
@@ -197,6 +212,7 @@ The command line to use when linking systems including D sources.
<summary>
<para>
List of linker flags.
+See also &cv-link-SHDLINKFLAGS; for linking shared objects.
</para>
</summary>
</cvar>
@@ -278,6 +294,7 @@ DVERSUFFIX.
<para>
The name of the compiler to use when compiling D source
destined to be in a shared objects.
+See also &cv-link-DC; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -286,6 +303,18 @@ destined to be in a shared objects.
<summary>
<para>
The command line to use when compiling code to be part of shared objects.
+See also &cv-link-DCOM; for compiling to static objects.
+</para>
+</summary>
+</cvar>
+
+<cvar name="SHDCOMSTR">
+<summary>
+<para>
+If set, the string displayed when a D source file
+is compiled to a (shared) object file.
+If not set, then &cv-link-SHDCOM; (the command line) is displayed.
+See also &cv-link-DCOMSTR; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -311,6 +340,7 @@ SHDLIBVERSIONFLAGS.
<para>
The linker to use when creating shared objects for code bases
include D sources.
+See also &cv-link-DLINK; for linking static objects.
</para>
</summary>
</cvar>
@@ -319,6 +349,7 @@ include D sources.
<summary>
<para>
The command line to use when generating shared objects.
+See also &cv-link-DLINKCOM; for linking static objects.
</para>
</summary>
</cvar>
@@ -327,6 +358,7 @@ The command line to use when generating shared objects.
<summary>
<para>
The list of flags to use when generating a shared object.
+See also &cv-link-DLINKFLAGS; for linking static objects.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
index 386f445..4ce605b 100644
--- a/src/engine/SCons/Tool/MSCommon/common.py
+++ b/src/engine/SCons/Tool/MSCommon/common.py
@@ -152,8 +152,8 @@ def normalize_env(env, keys, force=False):
Note: the environment is copied."""
normenv = {}
if env:
- for k in list(env.keys()):
- normenv[k] = copy.deepcopy(env[k])
+ for k, v in env.items():
+ normenv[k] = copy.deepcopy(v)
for k in keys:
if k in os.environ and (force or k not in normenv):
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 14306ab..76a0913 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -1130,7 +1130,7 @@ class ToolInitializer(object):
so we no longer copy and re-bind them when the construction
environment gets cloned.
"""
- for method in list(self.methods.values()):
+ for method in self.methods.values():
env.RemoveMethod(method)
def apply_tools(self, env):
@@ -1312,6 +1312,8 @@ def tool_list(platform, env):
'tar', 'zip',
# File builders (text)
'textfile',
+ # Python scanner tool
+ 'python',
], env)
tools = ([linker, c_compiler, cxx_compiler,
diff --git a/src/engine/SCons/Tool/c++.xml b/src/engine/SCons/Tool/c++.xml
index b59816b..019821c 100644
--- a/src/engine/SCons/Tool/c++.xml
+++ b/src/engine/SCons/Tool/c++.xml
@@ -47,6 +47,7 @@ Sets construction variables for generic POSIX C++ compilers.
</sets>
<uses>
<item>CXXCOMSTR</item>
+<item>SHCXXCOMSTR</item>
</uses>
</tool>
@@ -54,6 +55,7 @@ Sets construction variables for generic POSIX C++ compilers.
<summary>
<para>
The C++ compiler.
+See also &cv-link-SHCXX; for compiling to shared objects..
</para>
</summary>
</cvar>
@@ -65,6 +67,7 @@ The command line used to compile a C++ source file to an object file.
Any options specified in the &cv-link-CXXFLAGS; and
&cv-link-CPPFLAGS; construction variables
are included on this command line.
+See also &cv-link-SHCXXCOM; for compiling to shared objects..
</para>
</summary>
</cvar>
@@ -72,9 +75,10 @@ are included on this command line.
<cvar name="CXXCOMSTR">
<summary>
<para>
-The string displayed when a C++ source file
+If set, the string displayed when a C++ source file
is compiled to a (static) object file.
-If this is not set, then &cv-link-CXXCOM; (the command line) is displayed.
+If not set, then &cv-link-CXXCOM; (the command line) is displayed.
+See also &cv-link-SHCXXCOMSTR; for compiling to shared objects..
</para>
<example_commands>
@@ -91,6 +95,7 @@ By default, this includes the value of &cv-link-CCFLAGS;,
so that setting &cv-CCFLAGS; affects both C and C++ compilation.
If you want to add C++-specific flags,
you must set or override the value of &cv-link-CXXFLAGS;.
+See also &cv-link-SHCXXFLAGS; for compiling to shared objects..
</para>
</summary>
</cvar>
@@ -99,6 +104,7 @@ you must set or override the value of &cv-link-CXXFLAGS;.
<summary>
<para>
The C++ compiler used for generating shared-library objects.
+See also &cv-link-CXX; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -111,6 +117,7 @@ to a shared-library object file.
Any options specified in the &cv-link-SHCXXFLAGS; and
&cv-link-CPPFLAGS; construction variables
are included on this command line.
+See also &cv-link-CXXCOM; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -118,9 +125,10 @@ are included on this command line.
<cvar name="SHCXXCOMSTR">
<summary>
<para>
-The string displayed when a C++ source file
+If set, the string displayed when a C++ source file
is compiled to a shared object file.
-If this is not set, then &cv-link-SHCXXCOM; (the command line) is displayed.
+If not set, then &cv-link-SHCXXCOM; (the command line) is displayed.
+See also &cv-link-CXXCOMSTR; for compiling to static objects.
</para>
<example_commands>
@@ -134,6 +142,7 @@ env = Environment(SHCXXCOMSTR = "Compiling shared object $TARGET")
<para>
Options that are passed to the C++ compiler
to generate shared-library objects.
+See also &cv-link-CXXFLAGS; for compiling to static objects.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/cc.xml b/src/engine/SCons/Tool/cc.xml
index 06e73ff..e47cf2d 100644
--- a/src/engine/SCons/Tool/cc.xml
+++ b/src/engine/SCons/Tool/cc.xml
@@ -51,6 +51,8 @@ Sets construction variables for generic POSIX C compilers.
</sets>
<uses>
<item>PLATFORM</item>
+<item>CCCOMSTR</item>
+<item>SHCCCOMSTR</item>
</uses>
</tool>
@@ -67,8 +69,8 @@ The C compiler.
<para>
The command line used to compile a C source file to a (static) object
file. Any options specified in the &cv-link-CFLAGS;, &cv-link-CCFLAGS; and
-&cv-link-CPPFLAGS; construction variables are included on this command
-line.
+&cv-link-CPPFLAGS; construction variables are included on this command line.
+See also &cv-link-SHCCCOM; for compiling to shared objects.
</para>
</summary>
</cvar>
@@ -76,9 +78,10 @@ line.
<cvar name="CCCOMSTR">
<summary>
<para>
-The string displayed when a C source file
+If set, the string displayed when a C source file
is compiled to a (static) object file.
-If this is not set, then &cv-link-CCCOM; (the command line) is displayed.
+If not set, then &cv-link-CCCOM; (the command line) is displayed.
+See also &cv-link-SHCCCOMSTR; for compiling to shared objects.
</para>
<example_commands>
@@ -91,6 +94,7 @@ env = Environment(CCCOMSTR = "Compiling static object $TARGET")
<summary>
<para>
General options that are passed to the C and C++ compilers.
+See also &cv-link-SHCCFLAGS; for compiling to shared objects.
</para>
</summary>
</cvar>
@@ -99,6 +103,7 @@ General options that are passed to the C and C++ compilers.
<summary>
<para>
General options that are passed to the C compiler (C only; not C++).
+See also &cv-link-SHCFLAGS; for compiling to shared objects.
</para>
</summary>
</cvar>
@@ -156,6 +161,7 @@ The default list is:
<summary>
<para>
The C compiler used for generating shared-library objects.
+See also &cv-link-CC; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -169,6 +175,7 @@ Any options specified in the &cv-link-SHCFLAGS;,
&cv-link-SHCCFLAGS; and
&cv-link-CPPFLAGS; construction variables
are included on this command line.
+See also &cv-link-CCCOM; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -176,9 +183,10 @@ are included on this command line.
<cvar name="SHCCCOMSTR">
<summary>
<para>
-The string displayed when a C source file
+If set, the string displayed when a C source file
is compiled to a shared object file.
-If this is not set, then &cv-link-SHCCCOM; (the command line) is displayed.
+If not set, then &cv-link-SHCCCOM; (the command line) is displayed.
+See also &cv-link-CCCOMSTR; for compiling to static objects.
</para>
<example_commands>
@@ -192,6 +200,7 @@ env = Environment(SHCCCOMSTR = "Compiling shared object $TARGET")
<para>
Options that are passed to the C and C++ compilers
to generate shared-library objects.
+See also &cv-link-CCFLAGS; for compiling to static objects.
</para>
</summary>
</cvar>
@@ -201,6 +210,7 @@ to generate shared-library objects.
<para>
Options that are passed to the C compiler (only; not C++)
to generate shared-library objects.
+See also &cv-link-CFLAGS; for compiling to static objects.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/f03.xml b/src/engine/SCons/Tool/f03.xml
index c020b81..61c02ef 100644
--- a/src/engine/SCons/Tool/f03.xml
+++ b/src/engine/SCons/Tool/f03.xml
@@ -77,9 +77,9 @@ for all Fortran versions.
<cvar name="F03COMSTR">
<summary>
<para>
-The string displayed when a Fortran 03 source file
+If set, the string displayed when a Fortran 03 source file
is compiled to an object file.
-If this is not set, then &cv-link-F03COM; or &cv-link-FORTRANCOM;
+If not set, then &cv-link-F03COM; or &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -217,10 +217,10 @@ for all Fortran versions.
<cvar name="F03PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 03 source file
+If set, the string displayed when a Fortran 03 source file
is compiled to an object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-F03PPCOM; or &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-F03PPCOM; or &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -256,9 +256,9 @@ for all Fortran versions.
<cvar name="SHF03COMSTR">
<summary>
<para>
-The string displayed when a Fortran 03 source file
+If set, the string displayed when a Fortran 03 source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHF03COM; or &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHF03COM; or &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -299,10 +299,10 @@ for all Fortran versions.
<cvar name="SHF03PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 03 source file
+If set, the string displayed when a Fortran 03 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHF03PPCOM; or &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHF03PPCOM; or &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/f08.xml b/src/engine/SCons/Tool/f08.xml
index 802e4cc..a56d60b 100644
--- a/src/engine/SCons/Tool/f08.xml
+++ b/src/engine/SCons/Tool/f08.xml
@@ -77,9 +77,9 @@ for all Fortran versions.
<cvar name="F08COMSTR">
<summary>
<para>
-The string displayed when a Fortran 08 source file
+If set, the string displayed when a Fortran 08 source file
is compiled to an object file.
-If this is not set, then &cv-link-F08COM; or &cv-link-FORTRANCOM;
+If not set, then &cv-link-F08COM; or &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -217,10 +217,10 @@ for all Fortran versions.
<cvar name="F08PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 08 source file
+If set, the string displayed when a Fortran 08 source file
is compiled to an object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-F08PPCOM; or &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-F08PPCOM; or &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -256,9 +256,9 @@ for all Fortran versions.
<cvar name="SHF08COMSTR">
<summary>
<para>
-The string displayed when a Fortran 08 source file
+If set, the string displayed when a Fortran 08 source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHF08COM; or &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHF08COM; or &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -299,10 +299,10 @@ for all Fortran versions.
<cvar name="SHF08PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 08 source file
+If set, the string displayed when a Fortran 08 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHF08PPCOM; or &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHF08PPCOM; or &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/f77.xml b/src/engine/SCons/Tool/f77.xml
index abfc4a2..70ec721 100644
--- a/src/engine/SCons/Tool/f77.xml
+++ b/src/engine/SCons/Tool/f77.xml
@@ -108,9 +108,9 @@ F77 dialect will be used. By default, this is empty
<cvar name="F77COMSTR">
<summary>
<para>
-The string displayed when a Fortran 77 source file
+If set, the string displayed when a Fortran 77 source file
is compiled to an object file.
-If this is not set, then &cv-link-F77COM; or &cv-link-FORTRANCOM;
+If not set, then &cv-link-F77COM; or &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -230,10 +230,10 @@ for all Fortran versions.
<cvar name="F77PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 77 source file
+If set, the string displayed when a Fortran 77 source file
is compiled to an object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-F77PPCOM; or &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-F77PPCOM; or &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -269,9 +269,9 @@ for all Fortran versions.
<cvar name="SHF77COMSTR">
<summary>
<para>
-The string displayed when a Fortran 77 source file
+If set, the string displayed when a Fortran 77 source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHF77COM; or &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHF77COM; or &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -312,10 +312,10 @@ for all Fortran versions.
<cvar name="SHF77PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 77 source file
+If set, the string displayed when a Fortran 77 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHF77PPCOM; or &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHF77PPCOM; or &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/f90.xml b/src/engine/SCons/Tool/f90.xml
index 94249a3..64dc6e1 100644
--- a/src/engine/SCons/Tool/f90.xml
+++ b/src/engine/SCons/Tool/f90.xml
@@ -77,9 +77,9 @@ for all Fortran versions.
<cvar name="F90COMSTR">
<summary>
<para>
-The string displayed when a Fortran 90 source file
+If set, the string displayed when a Fortran 90 source file
is compiled to an object file.
-If this is not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM;
+If not set, then &cv-link-F90COM; or &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -217,9 +217,9 @@ for all Fortran versions.
<cvar name="F90PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 90 source file
+If set, the string displayed when a Fortran 90 source file
is compiled after first running the file through the C preprocessor.
-If this is not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-F90PPCOM; or &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -255,9 +255,9 @@ for all Fortran versions.
<cvar name="SHF90COMSTR">
<summary>
<para>
-The string displayed when a Fortran 90 source file
+If set, the string displayed when a Fortran 90 source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHF90COM; or &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -298,10 +298,10 @@ for all Fortran versions.
<cvar name="SHF90PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 90 source file
+If set, the string displayed when a Fortran 90 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHF90PPCOM; or &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/f95.xml b/src/engine/SCons/Tool/f95.xml
index 4a4db46..4bda653 100644
--- a/src/engine/SCons/Tool/f95.xml
+++ b/src/engine/SCons/Tool/f95.xml
@@ -77,9 +77,9 @@ for all Fortran versions.
<cvar name="F95COMSTR">
<summary>
<para>
-The string displayed when a Fortran 95 source file
+If set, the string displayed when a Fortran 95 source file
is compiled to an object file.
-If this is not set, then &cv-link-F95COM; or &cv-link-FORTRANCOM;
+If not set, then &cv-link-F95COM; or &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -217,10 +217,10 @@ for all Fortran versions.
<cvar name="F95PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 95 source file
+If set, the string displayed when a Fortran 95 source file
is compiled to an object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-F95PPCOM; or &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-F95PPCOM; or &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -256,9 +256,9 @@ for all Fortran versions.
<cvar name="SHF95COMSTR">
<summary>
<para>
-The string displayed when a Fortran 95 source file
+If set, the string displayed when a Fortran 95 source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHF95COM; or &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHF95COM; or &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -299,10 +299,10 @@ for all Fortran versions.
<cvar name="SHF95PPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran 95 source file
+If set, the string displayed when a Fortran 95 source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHF95PPCOM; or &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHF95PPCOM; or &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/fortran.xml b/src/engine/SCons/Tool/fortran.xml
index 53bcfb1..7b3c51f 100644
--- a/src/engine/SCons/Tool/fortran.xml
+++ b/src/engine/SCons/Tool/fortran.xml
@@ -73,9 +73,9 @@ are included on this command line.
<cvar name="FORTRANCOMSTR">
<summary>
<para>
-The string displayed when a Fortran source file
+If set, the string displayed when a Fortran source file
is compiled to an object file.
-If this is not set, then &cv-link-FORTRANCOM;
+If not set, then &cv-link-FORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -285,10 +285,10 @@ construction variables are included on this command line.
<cvar name="FORTRANPPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran source file
+If set, the string displayed when a Fortran source file
is compiled to an object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-FORTRANPPCOM;
+If not set, then &cv-link-FORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
@@ -330,9 +330,9 @@ to a shared-library object file.
<cvar name="SHFORTRANCOMSTR">
<summary>
<para>
-The string displayed when a Fortran source file
+If set, the string displayed when a Fortran source file
is compiled to a shared-library object file.
-If this is not set, then &cv-link-SHFORTRANCOM;
+If not set, then &cv-link-SHFORTRANCOM;
(the command line) is displayed.
</para>
</summary>
@@ -364,10 +364,10 @@ are included on this command line.
<cvar name="SHFORTRANPPCOMSTR">
<summary>
<para>
-The string displayed when a Fortran source file
+If set, the string displayed when a Fortran source file
is compiled to a shared-library object file
after first running the file through the C preprocessor.
-If this is not set, then &cv-link-SHFORTRANPPCOM;
+If not set, then &cv-link-SHFORTRANPPCOM;
(the command line) is displayed.
</para>
</summary>
diff --git a/src/engine/SCons/Tool/install.xml b/src/engine/SCons/Tool/install.xml
index 150308b..ce70d91 100644
--- a/src/engine/SCons/Tool/install.xml
+++ b/src/engine/SCons/Tool/install.xml
@@ -50,10 +50,24 @@ a builder.
</para>
<example_commands>
-env.Install('/usr/local/bin', source = ['foo', 'bar'])
+env.Install(target='/usr/local/bin', source=['foo', 'bar'])
</example_commands>
<para>
+Note that if target paths chosen for the
+&Install; builder (and the related &InstallAs; and
+&InstallVersionedLib; builders) are outside the
+project tree, such as in the example above,
+they may not be selected for "building" by default,
+since in the absence of other instructions
+&scons; builds targets that are underneath the top directory
+(the directory that contains the &SConstruct; file,
+usually the current directory).
+Use command line targets or the &Default; function
+in this case.
+</para>
+
+<para>
If the <option>--install-sandbox</option> command line
option is given, the target directory will be prefixed
by the directory path specified.
@@ -86,12 +100,16 @@ arguments list different numbers of files or directories.
</para>
<example_commands>
-env.InstallAs(target = '/usr/local/bin/foo',
- source = 'foo_debug')
-env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'],
- source = ['libFOO.a', 'libBAR.a'])
+env.InstallAs(target='/usr/local/bin/foo',
+ source='foo_debug')
+env.InstallAs(target=['../lib/libfoo.a', '../lib/libbar.a'],
+ source=['libFOO.a', 'libBAR.a'])
</example_commands>
+<para>
+See the note under &Install;.
+</para>
+
</summary>
</builder>
@@ -103,9 +121,14 @@ architecture will be generated based on symlinks of the source library.
</para>
<example_commands>
-env.InstallVersionedLib(target = '/usr/local/bin/foo',
- source = 'libxyz.1.5.2.so')
+env.InstallVersionedLib(target='/usr/local/bin/foo',
+ source='libxyz.1.5.2.so')
</example_commands>
+
+<para>
+See the note under &Install;.
+</para>
+
</summary>
</builder>
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
index 5a101b4..778cba1 100644
--- a/src/engine/SCons/Tool/intelc.py
+++ b/src/engine/SCons/Tool/intelc.py
@@ -495,15 +495,15 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
'LIB' : libdir,
'PATH' : bindir,
'LD_LIBRARY_PATH' : libdir}
- for p in list(paths.keys()):
- env.PrependENVPath(p, os.path.join(topdir, paths[p]))
+ for p, v in paths.items():
+ env.PrependENVPath(p, os.path.join(topdir, v))
if is_mac:
paths={'INCLUDE' : 'include',
'LIB' : libdir,
'PATH' : bindir,
'LD_LIBRARY_PATH' : libdir}
- for p in list(paths.keys()):
- env.PrependENVPath(p, os.path.join(topdir, paths[p]))
+ for p, v in paths.items():
+ env.PrependENVPath(p, os.path.join(topdir, v))
if is_windows:
# env key reg valname default subdir of top
paths=(('INCLUDE', 'IncludeDir', 'Include'),
diff --git a/src/engine/SCons/Tool/javac.xml b/src/engine/SCons/Tool/javac.xml
index bc89342..893130b 100644
--- a/src/engine/SCons/Tool/javac.xml
+++ b/src/engine/SCons/Tool/javac.xml
@@ -95,9 +95,9 @@ See its __doc__ string for a discussion of the format.
</para>
<example_commands>
- env.Java(target = 'classes', source = 'src')
- env.Java(target = 'classes', source = ['src1', 'src2'])
- env.Java(target = 'classes', source = ['File1.java', 'File2.java'])
+env.Java(target = 'classes', source = 'src')
+env.Java(target = 'classes', source = ['src1', 'src2'])
+env.Java(target = 'classes', source = ['File1.java', 'File2.java'])
</example_commands>
<para>
@@ -114,8 +114,8 @@ See its __doc__ string for a discussion of the format.
</para>
<example_commands>
- env = Environment()
- env['ENV']['LANG'] = 'en_GB.UTF-8'
+env = Environment()
+env['ENV']['LANG'] = 'en_GB.UTF-8'
</example_commands>
</summary>
</builder>
@@ -174,7 +174,7 @@ See its __doc__ string for a discussion of the format.
</para>
<example_commands>
- env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES")
+env = Environment(JAVACCOMSTR = "Compiling class files $TARGETS from $SOURCES")
</example_commands>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/link.xml b/src/engine/SCons/Tool/link.xml
index 654dafc..281e147 100644
--- a/src/engine/SCons/Tool/link.xml
+++ b/src/engine/SCons/Tool/link.xml
@@ -32,9 +32,6 @@ based on the types of source files.
</para>
</summary>
<sets>
-<item>SHLINK</item>
-<item>SHLINKFLAGS</item>
-<item>SHLINKCOM</item>
<item>LINK</item>
<item>LINKFLAGS</item>
<item>LINKCOM</item>
@@ -42,6 +39,9 @@ based on the types of source files.
<item>LIBDIRSUFFIX</item>
<item>LIBLINKPREFIX</item>
<item>LIBLINKSUFFIX</item>
+<item>SHLINK</item>
+<item>SHLINKFLAGS</item>
+<item>SHLINKCOM</item>
<item>SHLIBSUFFIX</item>
<item>__SHLIBVERSIONFLAGS</item>
<item>LDMODULE</item>
@@ -55,8 +55,8 @@ based on the types of source files.
<item>__LDMODULEVERSIONFLAGS</item>
</sets>
<uses>
-<item>SHLINKCOMSTR</item>
<item>LINKCOMSTR</item>
+<item>SHLINKCOMSTR</item>
<item>LDMODULECOMSTR</item>
</uses>
</tool>
@@ -184,8 +184,8 @@ On other systems, this is the same as &cv-link-SHLINK;.
<cvar name="LDMODULECOMSTR">
<summary>
<para>
-The string displayed when building loadable modules.
-If this is not set, then &cv-link-LDMODULECOM; (the command line) is displayed.
+If set, the string displayed when building loadable modules.
+If not set, then &cv-link-LDMODULECOM; (the command line) is displayed.
</para>
</summary>
</cvar>
@@ -243,6 +243,7 @@ set.
<summary>
<para>
The linker.
+See also &cv-link-SHLINK; for linking shared objects.
</para>
</summary>
</cvar>
@@ -251,6 +252,7 @@ The linker.
<summary>
<para>
The command line used to link object files into an executable.
+See also &cv-link-SHLINKCOM; for linking shared objects.
</para>
</summary>
</cvar>
@@ -258,9 +260,10 @@ The command line used to link object files into an executable.
<cvar name="LINKCOMSTR">
<summary>
<para>
-The string displayed when object files
+If set, the string displayed when object files
are linked into an executable.
-If this is not set, then &cv-link-LINKCOM; (the command line) is displayed.
+If not set, then &cv-link-LINKCOM; (the command line) is displayed.
+See also &cv-link-SHLINKCOMSTR;. for linking shared objects.
</para>
<example_commands>
@@ -290,6 +293,7 @@ and
&cv-link-_LIBDIRFLAGS;
above,
for the variable that expands to library search path options.
+See also &cv-link-SHLINKFLAGS;. for linking shared objects.
</para>
</summary>
</cvar>
@@ -317,6 +321,7 @@ set.
<summary>
<para>
The linker for programs that use shared libraries.
+See also &cv-link-LINK; for linking static objects.
</para>
</summary>
</cvar>
@@ -325,6 +330,7 @@ The linker for programs that use shared libraries.
<summary>
<para>
The command line used to link programs using shared libraries.
+See also &cv-link-LINKCOM; for linking static objects.
</para>
</summary>
</cvar>
@@ -334,6 +340,7 @@ The command line used to link programs using shared libraries.
<para>
The string displayed when programs using shared libraries are linked.
If this is not set, then &cv-link-SHLINKCOM; (the command line) is displayed.
+See also &cv-link-LINKCOMSTR; for linking static objects.
</para>
<example_commands>
@@ -363,6 +370,7 @@ and
&cv-link-_LIBDIRFLAGS;
above,
for the variable that expands to library search path options.
+See also &cv-link-LINKFLAGS; for linking static objects.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index 929e558..9952ccc 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -220,7 +220,7 @@ class _UserGenerator(object):
for var, src in dbg_settings.items():
# Update only expected keys
trg = {}
- for key in [k for k in list(self.usrdebg.keys()) if k in src]:
+ for key in [k for k in self.usrdebg.keys() if k in src]:
trg[key] = str(src[key])
self.configs[var].debug = trg
@@ -544,7 +544,7 @@ class _DSPGenerator(object):
if t[1] in self.env:
if SCons.Util.is_List(self.env[t[1]]):
for i in self.env[t[1]]:
- if not i in self.sources[t[0]]:
+ if i not in self.sources[t[0]]:
self.sources[t[0]].append(i)
else:
if not self.env[t[1]] in self.sources[t[0]]:
@@ -578,11 +578,10 @@ class _DSPGenerator(object):
for i in range(len(variants)):
AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs[i], cppdefines[i], cpppaths[i])
- self.platforms = []
- for key in list(self.configs.keys()):
- platform = self.configs[key].platform
- if platform not in self.platforms:
- self.platforms.append(platform)
+ seen = set()
+ self.platforms = [p.platform for p in self.configs.values()
+ if not (p.platform in seen or seen.add(p.platform))]
+
def Build(self):
pass
@@ -702,7 +701,7 @@ class _GenerateV6DSP(_DSPGenerator):
'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe',
'Other Files': ''}
- for kind in sorted(list(categories.keys()), key=lambda a: a.lower()):
+ for kind in sorted(categories.keys(), key=lambda a: a.lower()):
if not self.sources[kind]:
continue # skip empty groups
@@ -1003,7 +1002,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User):
self.file.write('\t<Files>\n')
- cats = sorted([k for k in list(categories.keys()) if self.sources[k]],
+ cats = sorted([k for k in categories.keys() if self.sources[k]],
key=lambda a: a.lower())
for kind in cats:
if len(cats) > 1:
@@ -1348,7 +1347,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User):
'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe',
'Other Files': ''}
- cats = sorted([k for k in list(categories.keys()) if self.sources[k]],
+ cats = sorted([k for k in categories.keys() if self.sources[k]],
key = lambda a: a.lower())
# print vcxproj.filters file first
@@ -1505,11 +1504,9 @@ class _GenerateV7DSW(_DSWGenerator):
for variant in env['variant']:
AddConfig(self, variant)
- self.platforms = []
- for key in list(self.configs.keys()):
- platform = self.configs[key].platform
- if platform not in self.platforms:
- self.platforms.append(platform)
+ seen = set()
+ self.platforms = [p.platform for p in self.configs.values()
+ if not (p.platform in seen or seen.add(p.platform))]
def GenerateProjectFilesInfo(self):
for dspfile in self.dspfiles:
diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py
index cc4f717..38a100f 100644
--- a/src/engine/SCons/Tool/msvsTests.py
+++ b/src/engine/SCons/Tool/msvsTests.py
@@ -405,20 +405,20 @@ class DummyEnv(object):
return self.dict
return self.dict[key]
- def __setitem__(self,key,value):
+ def __setitem__(self, key, value):
self.dict[key] = value
- def __getitem__(self,key):
+ def __getitem__(self, key):
return self.dict[key]
- def __contains__(self,key):
+ def __contains__(self, key):
return key in self.dict
- def has_key(self,name):
+ def has_key(self, name):
return name in self.dict
def get(self, name, value=None):
- if self.has_key(name):
+ if name in self.dict:
return self.dict[name]
else:
return value
@@ -771,8 +771,8 @@ class msvsTestCase(unittest.TestCase):
# Check expected result
self.assertListEqual(list(genDSP.configs.keys()), list(expected_configs.keys()))
- for key in list(genDSP.configs.keys()):
- self.assertDictEqual(genDSP.configs[key].__dict__, expected_configs[key])
+ for key, v in genDSP.configs.items():
+ self.assertDictEqual(v.__dict__, expected_configs[key])
genDSP.Build()
diff --git a/src/engine/SCons/Tool/packaging.xml b/src/engine/SCons/Tool/packaging.xml
index 8ab4912..55fecec 100644
--- a/src/engine/SCons/Tool/packaging.xml
+++ b/src/engine/SCons/Tool/packaging.xml
@@ -34,7 +34,7 @@ A framework for building binary and source packages.
<builder name="Package">
<summary>
<para>
-Builds a Binary Package of the given source files.
+Builds a Binary Package of the given source files.
</para>
<example_commands>
@@ -43,68 +43,4 @@ env.Package(source = FindInstalledFiles())
</summary>
</builder>
-<cvar name="JAR">
-<summary>
-<para>
-The Java archive tool.
-</para>
-</summary>
-</cvar>
-
-<cvar name="JARCHDIR">
-<summary>
-<para>
-The directory to which the Java archive tool should change
-(using the
-<option>-C</option>
-option).
-</para>
-</summary>
-</cvar>
-
-<cvar name="JARCOM">
-<summary>
-<para>
-The command line used to call the Java archive tool.
-</para>
-</summary>
-</cvar>
-
-<cvar name="JARCOMSTR">
-<summary>
-<para>
-The string displayed when the Java archive tool
-is called
-If this is not set, then &cv-JARCOM; (the command line) is displayed.
-</para>
-
-<example_commands>
-env = Environment(JARCOMSTR = "JARchiving $SOURCES into $TARGET")
-</example_commands>
-</summary>
-</cvar>
-
-<cvar name="JARFLAGS">
-<summary>
-<para>
-General options passed to the Java archive tool.
-By default this is set to
-<option>cf</option>
-to create the necessary
-<command>jar</command>
-file.
-</para>
-</summary>
-</cvar>
-
-<cvar name="JARSUFFIX">
-<summary>
-<para>
-The suffix for Java archives:
-<filename>.jar</filename>
-by default.
-</para>
-</summary>
-</cvar>
-
</sconsdoc>
diff --git a/src/engine/SCons/Tool/packaging/__init__.xml b/src/engine/SCons/Tool/packaging/__init__.xml
index 31c6eed..66a7aa0 100644
--- a/src/engine/SCons/Tool/packaging/__init__.xml
+++ b/src/engine/SCons/Tool/packaging/__init__.xml
@@ -62,24 +62,25 @@ option or with the &cv-PACKAGETYPE; construction variable. Currently
the following packagers available:
</para>
-<para>
- * msi - Microsoft Installer
- * rpm - RPM Package Manger
- * ipkg - Itsy Package Management System
- * tarbz2 - bzip2 compressed tar
- * targz - gzip compressed tar
- * tarxz - xz compressed tar
- * zip - zip file
- * src_tarbz2 - bzip2 compressed tar source
- * src_targz - gzip compressed tar source
- * src_tarxz - xz compressed tar source
- * src_zip - zip file source
-</para>
+<para><literal>msi</literal> - Microsoft Installer</para>
+<para><literal>rpm</literal> - RPM Package Manger</para>
+<para><literal>ipkg</literal> - Itsy Package Management System</para>
+<para><literal>tarbz2</literal> - bzip2 compressed tar</para>
+<para><literal>targz</literal> - gzip compressed tar</para>
+<para><literal>tarxz</literal> - xz compressed tar</para>
+<para><literal>zip</literal> - zip file</para>
+<para><literal>src_tarbz2</literal> - bzip2 compressed tar source</para>
+<para><literal>src_targz</literal> - gzip compressed tar source</para>
+<para><literal>src_tarxz</literal> - xz compressed tar source</para>
+<para><literal>src_zip</literal> - zip file source</para>
<para>
-An updated list is always available under the "package_type" option when
-running "scons --help" on a project that has packaging activated.
+An updated list is always available under the
+<replaceable>package_type</replaceable> option when
+running <command>scons --help</command>
+on a project that has packaging activated.
</para>
+
<example_commands>
env = Environment(tools=['default', 'packaging'])
env.Install('/bin/', 'my_program')
@@ -198,20 +199,21 @@ placed if applicable. The default value is "$NAME-$VERSION".
Selects the package type to build. Currently these are available:
</para>
-<para>
- * msi - Microsoft Installer
- * rpm - Redhat Package Manger
- * ipkg - Itsy Package Management System
- * tarbz2 - compressed tar
- * targz - compressed tar
- * zip - zip file
- * src_tarbz2 - compressed tar source
- * src_targz - compressed tar source
- * src_zip - zip file source
-</para>
+<para><literal>msi</literal> - Microsoft Installer</para>
+<para><literal>rpm</literal> - RPM Package Manger</para>
+<para><literal>ipkg</literal> - Itsy Package Management System</para>
+<para><literal>tarbz2</literal> - bzip2 compressed tar</para>
+<para><literal>targz</literal> - gzip compressed tar</para>
+<para><literal>tarxz</literal> - xz compressed tar</para>
+<para><literal>zip</literal> - zip file</para>
+<para><literal>src_tarbz2</literal> - bzip2 compressed tar source</para>
+<para><literal>src_targz</literal> - gzip compressed tar source</para>
+<para><literal>src_tarxz</literal> - xz compressed tar source</para>
+<para><literal>src_zip</literal> - zip file source</para>
<para>
-This may be overridden with the "package_type" command line option.
+This may be overridden with the <option>package_type</option>
+command line option.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py
index fe3f49b..ac8b992 100644
--- a/src/engine/SCons/Tool/packaging/ipk.py
+++ b/src/engine/SCons/Tool/packaging/ipk.py
@@ -173,7 +173,7 @@ Description: $X_IPK_DESCRIPTION
#
# close all opened files
- for f in list(opened_files.values()):
+ for f in opened_files.values():
f.close()
# call a user specified function
diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py
index ebaa701..db8ae24 100644
--- a/src/engine/SCons/Tool/packaging/rpm.py
+++ b/src/engine/SCons/Tool/packaging/rpm.py
@@ -284,7 +284,7 @@ def build_specfile_filesection(spec, files):
for file in files:
# build the tagset
tags = {}
- for k in list(supported_tags.keys()):
+ for k in supported_tags.keys():
try:
v = file.GetTag(k)
if v:
diff --git a/src/engine/SCons/Tool/python.py b/src/engine/SCons/Tool/python.py
new file mode 100644
index 0000000..c61fc8d
--- /dev/null
+++ b/src/engine/SCons/Tool/python.py
@@ -0,0 +1,49 @@
+"""SCons.Tool.python
+
+Registers the Python scanner for the supported Python source file suffixes.
+
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import SCons.Tool
+from SCons.Scanner.Python import PythonScanner, PythonSuffixes
+
+
+def generate(env):
+ """Hook the python builder and scanner into the environment."""
+ for suffix in PythonSuffixes:
+ SCons.Tool.SourceFileScanner.add_scanner(suffix, PythonScanner)
+
+
+def exists(env):
+ return True
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/python.xml b/src/engine/SCons/Tool/python.xml
new file mode 100644
index 0000000..e3f7da3
--- /dev/null
+++ b/src/engine/SCons/Tool/python.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+
+<!DOCTYPE sconsdoc [
+<!ENTITY % scons SYSTEM '../../../../doc/scons.mod'>
+%scons;
+<!ENTITY % builders-mod SYSTEM '../../../../doc/generated/builders.mod'>
+%builders-mod;
+<!ENTITY % functions-mod SYSTEM '../../../../doc/generated/functions.mod'>
+%functions-mod;
+<!ENTITY % tools-mod SYSTEM '../../../../doc/generated/tools.mod'>
+%tools-mod;
+<!ENTITY % variables-mod SYSTEM '../../../../doc/generated/variables.mod'>
+%variables-mod;
+]>
+
+<sconsdoc xmlns="http://www.scons.org/dbxsd/v1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.scons.org/dbxsd/v1.0 http://www.scons.org/dbxsd/v1.0/scons.xsd">
+
+<tool name="python">
+<summary>
+<para>
+Loads the Python scanner scanner into the invoking environment. When loaded, the scanner will
+attempt to find implicit dependencies for any Python source files in the list of sources
+provided to an actual that uses this environment.
+</para>
+</summary>
+</tool>
+
+</sconsdoc>
diff --git a/src/engine/SCons/Tool/suncxx.py b/src/engine/SCons/Tool/suncxx.py
index c155484..1c35612 100644
--- a/src/engine/SCons/Tool/suncxx.py
+++ b/src/engine/SCons/Tool/suncxx.py
@@ -39,7 +39,6 @@ import os
import re
import subprocess
-from SCons.Util import PY3
import SCons.Tool.cxx
cplusplus = SCons.Tool.cxx
# cplusplus = __import__('c++', globals(), locals(), [])
@@ -53,10 +52,7 @@ def get_package_info(package_name, pkginfo, pkgchk):
except KeyError:
version = None
pathname = None
- try:
- from subprocess import DEVNULL # py3k
- except ImportError:
- DEVNULL = open(os.devnull, 'wb')
+ from subprocess import DEVNULL
try:
with open('/var/sadm/install/contents', 'r') as f:
@@ -72,16 +68,14 @@ def get_package_info(package_name, pkginfo, pkgchk):
try:
popen_args = {'stdout': subprocess.PIPE,
'stderr': DEVNULL}
- if PY3:
- popen_args['universal_newlines'] = True
+ popen_args['universal_newlines'] = True
p = subprocess.Popen([pkginfo, '-l', package_name],
**popen_args)
except EnvironmentError:
pass
else:
pkginfo_contents = p.communicate()[0]
- if not PY3:
- pkginfo_contents.decode()
+ pkginfo_contents.decode()
version_re = re.compile(r'^ *VERSION:\s*(.*)$', re.M)
version_match = version_re.search(pkginfo_contents)
if version_match:
@@ -91,16 +85,14 @@ def get_package_info(package_name, pkginfo, pkgchk):
try:
popen_args = {'stdout': subprocess.PIPE,
'stderr': DEVNULL}
- if PY3:
- popen_args['universal_newlines'] = True
+ popen_args['universal_newlines'] = True
p = subprocess.Popen([pkgchk, '-l', package_name],
**popen_args)
except EnvironmentError:
pass
else:
pkgchk_contents = p.communicate()[0]
- if not PY3:
- pkgchk_contents.decode()
+ pkgchk_contents.decode()
pathname_re = re.compile(r'^Pathname:\s*(.*/bin/CC)$', re.M)
pathname_match = pathname_re.search(pkgchk_contents)
if pathname_match:
diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py
index 9e2327a..48a2904 100644
--- a/src/engine/SCons/Tool/textfile.py
+++ b/src/engine/SCons/Tool/textfile.py
@@ -53,13 +53,10 @@ import re
from SCons.Node import Node
from SCons.Node.Python import Value
-from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes, PY3
+from SCons.Util import is_String, is_Sequence, is_Dict, to_bytes
-if PY3:
- TEXTFILE_FILE_WRITE_MODE = 'w'
-else:
- TEXTFILE_FILE_WRITE_MODE = 'wb'
+TEXTFILE_FILE_WRITE_MODE = 'w'
LINESEP = '\n'
@@ -126,10 +123,7 @@ def _action(target, source, env):
# write the file
try:
- if SCons.Util.PY3:
- target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE, newline='')
- else:
- target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE)
+ target_file = open(target[0].get_path(), TEXTFILE_FILE_WRITE_MODE, newline='')
except (OSError, IOError):
raise SCons.Errors.UserError("Can't write target file %s" % target[0])
diff --git a/src/engine/SCons/Tool/textfile.xml b/src/engine/SCons/Tool/textfile.xml
index 957e18c..878eb9f 100644
--- a/src/engine/SCons/Tool/textfile.xml
+++ b/src/engine/SCons/Tool/textfile.xml
@@ -59,7 +59,7 @@ see the &b-Substfile; description for details.
<para>
The prefix and suffix specified by the &cv-TEXTFILEPREFIX;
and &cv-TEXTFILESUFFIX; construction variables
-(the null string and <filename>.txt</filename> by default, respectively)
+(an empty string and <filename>.txt</filename> by default, respectively)
are automatically added to the target if they are not already present.
Examples:
</para>
@@ -124,7 +124,7 @@ the suffix is stripped and the remainder is used as the default target name.
<para>
The prefix and suffix specified by the &cv-SUBSTFILEPREFIX;
and &cv-SUBSTFILESUFFIX; construction variables
-(the null string by default in both cases)
+(an empty string by default in both cases)
are automatically added to the target if they are not already present.
</para>
@@ -218,7 +218,7 @@ lists of tuples are also acceptable.
<summary>
<para>
The prefix used for &b-Substfile; file names,
-the null string by default.
+an empty string by default.
</para>
</summary>
</cvar>
@@ -227,7 +227,7 @@ the null string by default.
<summary>
<para>
The suffix used for &b-Substfile; file names,
-the null string by default.
+an empty string by default.
</para>
</summary>
</cvar>
@@ -236,7 +236,7 @@ the null string by default.
<summary>
<para>
The prefix used for &b-Textfile; file names,
-the null string by default.
+an empty string by default.
</para>
</summary>
</cvar>
diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py
index 11ca32f..7aba08d 100644
--- a/src/engine/SCons/Tool/xgettext.py
+++ b/src/engine/SCons/Tool/xgettext.py
@@ -70,7 +70,7 @@ class _CmdRunner(object):
self.out, self.err = proc.communicate()
self.status = proc.wait()
if self.err:
- sys.stderr.write(SCons.Util.UnicodeType(self.err))
+ sys.stderr.write(str(self.err))
return self.status
def strfunction(self, target, source, env):
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index d930dde..130cc5e 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -39,18 +39,8 @@ PY3 = sys.version_info[0] == 3
PYPY = hasattr(sys, 'pypy_translation_info')
-try:
- from collections import UserDict, UserList, UserString
-except ImportError:
- from UserDict import UserDict
- from UserList import UserList
- from UserString import UserString
-
-try:
- from collections.abc import Iterable, MappingView
-except ImportError:
- from collections import Iterable
-
+from collections import UserDict, UserList, UserString
+from collections.abc import Iterable, MappingView
from collections import OrderedDict
# Don't "from types import ..." these because we need to get at the
@@ -62,13 +52,6 @@ from collections import OrderedDict
MethodType = types.MethodType
FunctionType = types.FunctionType
-try:
- _ = type(unicode)
-except NameError:
- UnicodeType = str
-else:
- UnicodeType = unicode
-
def dictify(keys, values, result={}):
for k, v in zip(keys, values):
result[k] = v
@@ -210,14 +193,16 @@ def get_environment_var(varstr):
else:
return None
+
class DisplayEngine(object):
print_it = True
+
def __call__(self, text, append_newline=1):
if not self.print_it:
return
if append_newline: text = text + '\n'
try:
- sys.stdout.write(UnicodeType(text))
+ sys.stdout.write(str(text))
except IOError:
# Stdout might be connected to a pipe that has been closed
# by now. The most likely reason for the pipe being closed
@@ -1582,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')
@@ -1594,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 e2dd57f..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='')
diff --git a/src/engine/SCons/Variables/ListVariableTests.py b/src/engine/SCons/Variables/ListVariableTests.py
index ef4832c..8f79e07 100644
--- a/src/engine/SCons/Variables/ListVariableTests.py
+++ b/src/engine/SCons/Variables/ListVariableTests.py
@@ -42,7 +42,7 @@ class ListVariableTestCase(unittest.TestCase):
assert o.help == 'test option help\n (all|none|comma-separated list of names)\n allowed names: one two three', repr(o.help)
assert o.default == 'all', o.default
assert o.validator is None, o.validator
- assert not o.converter is None, o.converter
+ assert o.converter is not None, o.converter
opts = SCons.Variables.Variables()
opts.Add(SCons.Variables.ListVariable('test2', 'test2 help',
diff --git a/src/engine/SCons/Variables/PackageVariableTests.py b/src/engine/SCons/Variables/PackageVariableTests.py
index cda3a4a..a7e6b0d 100644
--- a/src/engine/SCons/Variables/PackageVariableTests.py
+++ b/src/engine/SCons/Variables/PackageVariableTests.py
@@ -80,10 +80,10 @@ class PackageVariableTestCase(unittest.TestCase):
# False when we give it str(False). This assures consistent operation
# through a cycle of Variables.Save(<file>) -> Variables(<file>).
x = o.converter(str(True))
- assert x == True, "converter returned a string when given str(True)"
+ assert x, "converter returned a string when given str(True)"
x = o.converter(str(False))
- assert x == False, "converter returned a string when given str(False)"
+ assert not x, "converter returned a string when given str(False)"
def test_validator(self):
"""Test the PackageVariable validator"""
diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py
index 5b35390..0c20c94 100644
--- a/src/engine/SCons/cpp.py
+++ b/src/engine/SCons/cpp.py
@@ -89,7 +89,7 @@ del op_list
override = {
'if' : 'if(?!n?def)',
}
-l = [override.get(x, x) for x in list(Table.keys())]
+l = [override.get(x, x) for x in Table.keys()]
# Turn the list of expressions into one big honkin' regular expression
@@ -268,7 +268,7 @@ class PreProcessor(object):
d = {
'scons_current_file' : self.scons_current_file
}
- for op in list(Table.keys()):
+ for op in Table.keys():
d[op] = getattr(self, 'do_' + op)
self.default_table = d
diff --git a/src/test_interrupts.py b/src/test_interrupts.py
index de18a54..8e1b379 100644
--- a/src/test_interrupts.py
+++ b/src/test_interrupts.py
@@ -105,7 +105,7 @@ for f in files:
indent_list.append( (line_num, match.group('try_or_except') ) )
try_except_lines[match.group('indent')] = indent_list
uncaught_this_file = []
- for indent in list(try_except_lines.keys()):
+ for indent in try_except_lines.keys():
exc_keyboardint_seen = 0
exc_all_seen = 0
for (l,statement) in try_except_lines[indent] + [(-1,indent + 'try')]: