From: gregnoel <gregnoel@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Date: Thu, 25 Mar 2010 04:14:28 +0000 (+0000)
Subject: Move 2.0 changes collected in branches/pending back to trunk for further
X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=11e8e47454040247b5524a7d00358eb767e7c3c0;p=scons.git

Move 2.0 changes collected in branches/pending back to trunk for further
development.  Note that this set of changes is NOT backward-compatible;
the trunk no longer works with Python 1.5.2, 2.0, or 2.1.


git-svn-id: http://scons.tigris.org/svn/scons/trunk@4729 fdb21ef1-2011-0410-befe-b5e4ea1792b1
---

diff --git a/QMTest/SConscript b/QMTest/SConscript
index e141a514..8e5585fd 100644
--- a/QMTest/SConscript
+++ b/QMTest/SConscript
@@ -26,7 +26,6 @@
 #
 
 import os.path
-import string
 
 Import('build_dir', 'env')
 
@@ -50,7 +49,7 @@ def copy(target, source, env):
     # Note:  We construct the __ VERSION __ substitution string at
     # run-time so it doesn't get replaced when this file gets copied
     # into the tree for packaging.
-    c = string.replace(c, '__' + 'VERSION' + '__', env['VERSION'])
+    c = c.replace('__' + 'VERSION' + '__', env['VERSION'])
     open(t, 'wb').write(c)
 
 for file in files:
diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py
index 029c1d05..163a78d8 100644
--- a/QMTest/TestCmd.py
+++ b/QMTest/TestCmd.py
@@ -213,6 +213,7 @@ version.
 # PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
 # AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
 __revision__ = "TestCmd.py 0.37.D001 2010/01/11 16:55:50 knight"
@@ -224,7 +225,6 @@ import os.path
 import re
 import shutil
 import stat
-import string
 import sys
 import tempfile
 import time
@@ -282,7 +282,7 @@ _chain_to_exitfunc = None
 
 def _clean():
     global _Cleanup
-    cleanlist = filter(None, _Cleanup)
+    cleanlist = [_f for _f in _Cleanup if _f]
     del _Cleanup[:]
     cleanlist.reverse()
     for test in cleanlist:
@@ -307,16 +307,16 @@ try:
 except NameError:
     def zip(*lists):
         result = []
-        for i in xrange(min(map(len, lists))):
-            result.append(tuple(map(lambda l, i=i: l[i], lists)))
+        for i in xrange(min(list(map(len, lists)))):
+            result.append(tuple([l[i] for l in lists]))
         return result
 
 class Collector:
     def __init__(self, top):
         self.entries = [top]
     def __call__(self, arg, dirname, names):
-        pathjoin = lambda n, d=dirname: os.path.join(d, n)
-        self.entries.extend(map(pathjoin, names))
+        pathjoin = lambda n: os.path.join(dirname, n)
+        self.entries.extend(list(map(pathjoin, names)))
 
 def _caller(tblist, skip):
     string = ""
@@ -407,9 +407,9 @@ def match_exact(lines = None, matches = None):
     """
     """
     if not is_List(lines):
-        lines = string.split(lines, "\n")
+        lines = lines.split("\n")
     if not is_List(matches):
-        matches = string.split(matches, "\n")
+        matches = matches.split("\n")
     if len(lines) != len(matches):
         return
     for i in range(len(lines)):
@@ -421,9 +421,9 @@ def match_re(lines = None, res = None):
     """
     """
     if not is_List(lines):
-        lines = string.split(lines, "\n")
+        lines = lines.split("\n")
     if not is_List(res):
-        res = string.split(res, "\n")
+        res = res.split("\n")
     if len(lines) != len(res):
         return
     for i in range(len(lines)):
@@ -441,9 +441,9 @@ def match_re_dotall(lines = None, res = None):
     """
     """
     if not type(lines) is type(""):
-        lines = string.join(lines, "\n")
+        lines = "\n".join(lines)
     if not type(res) is type(""):
-        res = string.join(res, "\n")
+        res = "\n".join(res)
     s = "^" + res + "$"
     try:
         expr = re.compile(s, re.DOTALL)
@@ -472,15 +472,15 @@ else:
         for op, a1, a2, b1, b2 in sm.get_opcodes():
             if op == 'delete':
                 result.append("%sd%d" % (comma(a1, a2), b1))
-                result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+                result.extend(['< ' + l for l in a[a1:a2]])
             elif op == 'insert':
                 result.append("%da%s" % (a1, comma(b1, b2)))
-                result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+                result.extend(['> ' + l for l in b[b1:b2]])
             elif op == 'replace':
                 result.append("%sc%s" % (comma(a1, a2), comma(b1, b2)))
-                result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+                result.extend(['< ' + l for l in a[a1:a2]])
                 result.append('---')
-                result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+                result.extend(['> ' + l for l in b[b1:b2]])
         return result
 
 def diff_re(a, b, fromfile='', tofile='',
@@ -530,13 +530,13 @@ if sys.platform == 'win32':
         if path is None:
             path = os.environ['PATH']
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if pathext is None:
             pathext = os.environ['PATHEXT']
         if is_String(pathext):
-            pathext = string.split(pathext, os.pathsep)
+            pathext = pathext.split(os.pathsep)
         for ext in pathext:
-            if string.lower(ext) == string.lower(file[-len(ext):]):
+            if ext.lower() == file[-len(ext):].lower():
                 pathext = ['']
                 break
         for dir in path:
@@ -553,7 +553,7 @@ else:
         if path is None:
             path = os.environ['PATH']
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         for dir in path:
             f = os.path.join(dir, file)
             if os.path.isfile(f):
@@ -649,14 +649,14 @@ except ImportError:
             universal_newlines = 1
             def __init__(self, command, **kw):
                 if kw.get('stderr') == 'STDOUT':
-                    apply(popen2.Popen4.__init__, (self, command, 1))
+                    popen2.Popen4.__init__(self, command, 1)
                 else:
-                    apply(popen2.Popen3.__init__, (self, command, 1))
+                    popen2.Popen3.__init__(self, command, 1)
                 self.stdin = self.tochild
                 self.stdout = self.fromchild
                 self.stderr = self.childerr
             def wait(self, *args, **kw):
-                resultcode = apply(popen2.Popen3.wait, (self,)+args, kw)
+                resultcode = popen2.Popen3.wait(self, *args, **kw)
                 if os.WIFEXITED(resultcode):
                     return os.WEXITSTATUS(resultcode)
                 elif os.WIFSIGNALED(resultcode):
@@ -879,7 +879,7 @@ class TestCmd(object):
                 #self.diff_function = difflib.unified_diff
         self._dirlist = []
         self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0}
-        if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '':
+        if 'PRESERVE' in os.environ and not os.environ['PRESERVE'] is '':
             self._preserve['pass_test'] = os.environ['PRESERVE']
             self._preserve['fail_test'] = os.environ['PRESERVE']
             self._preserve['no_result'] = os.environ['PRESERVE']
@@ -924,9 +924,9 @@ class TestCmd(object):
             slash = '\\'
             special = '"$'
 
-            arg = string.replace(arg, slash, slash+slash)
+            arg = arg.replace(slash, slash+slash)
             for c in special:
-                arg = string.replace(arg, c, slash+c)
+                arg = arg.replace(c, slash+c)
 
             if re_space.search(arg):
                 arg = '"' + arg + '"'
@@ -944,7 +944,7 @@ class TestCmd(object):
 
     def canonicalize(self, path):
         if is_List(path):
-            path = apply(os.path.join, tuple(path))
+            path = os.path.join(*tuple(path))
         if not os.path.isabs(path):
             path = os.path.join(self.workdir, path)
         return path
@@ -1012,7 +1012,7 @@ class TestCmd(object):
             cmd = list(interpreter) + cmd
         if arguments:
             if type(arguments) == type(''):
-                arguments = string.split(arguments)
+                arguments = arguments.split()
             cmd.extend(arguments)
         return cmd
 
@@ -1033,7 +1033,7 @@ class TestCmd(object):
         def diff(self, a, b, name, *args, **kw):
             print self.banner(name)
             args = (a.splitlines(), b.splitlines()) + args
-            lines = apply(self.diff_function, args, kw)
+            lines = self.diff_function(*args, **kw)
             for l in lines:
                 print l
 
@@ -1149,7 +1149,7 @@ class TestCmd(object):
         prepended unless it is enclosed in a [list].
         """
         cmd = self.command_args(program, interpreter, arguments)
-        cmd_string = string.join(map(self.escape, cmd), ' ')
+        cmd_string = ' '.join(map(self.escape, cmd))
         if self.verbose:
             sys.stderr.write(cmd_string + "\n")
         if universal_newlines is None:
@@ -1314,7 +1314,7 @@ class TestCmd(object):
             if sub is None:
                 continue
             if is_List(sub):
-                sub = apply(os.path.join, tuple(sub))
+                sub = os.path.join(*tuple(sub))
             new = os.path.join(self.workdir, sub)
             try:
                 os.mkdir(new)
@@ -1362,7 +1362,7 @@ class TestCmd(object):
         # letters is pretty much random on win32:
         drive,rest = os.path.splitdrive(path)
         if drive:
-            path = string.upper(drive) + rest
+            path = drive.upper() + rest
 
         #
         self._dirlist.append(path)
@@ -1404,7 +1404,7 @@ class TestCmd(object):
         """Find an executable file.
         """
         if is_List(file):
-            file = apply(os.path.join, tuple(file))
+            file = os.path.join(*tuple(file))
         if not os.path.isabs(file):
             file = where_is(file, path, pathext)
         return file
@@ -1426,7 +1426,7 @@ class TestCmd(object):
         the temporary working directory name with the specified
         arguments using the os.path.join() method.
         """
-        return apply(os.path.join, (self.workdir,) + tuple(args))
+        return os.path.join(self.workdir, *tuple(args))
 
     def readable(self, top, read=1):
         """Make the specified directory tree readable (read == 1)
diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py
index 4aa7185a..e9ae6a40 100644
--- a/QMTest/TestCommon.py
+++ b/QMTest/TestCommon.py
@@ -87,6 +87,7 @@ The TestCommon module also provides the following variables
 # PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
 # AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
 __revision__ = "TestCommon.py 0.37.D001 2010/01/11 16:55:50 knight"
@@ -96,7 +97,6 @@ import copy
 import os
 import os.path
 import stat
-import string
 import sys
 import types
 import UserList
@@ -134,7 +134,7 @@ elif sys.platform == 'cygwin':
     lib_suffix   = '.a'
     dll_prefix   = ''
     dll_suffix   = '.dll'
-elif string.find(sys.platform, 'irix') != -1:
+elif sys.platform.find('irix') != -1:
     exe_suffix   = ''
     obj_suffix   = '.o'
     shobj_suffix = '.o'
@@ -143,7 +143,7 @@ elif string.find(sys.platform, 'irix') != -1:
     lib_suffix   = '.a'
     dll_prefix   = 'lib'
     dll_suffix   = '.so'
-elif string.find(sys.platform, 'darwin') != -1:
+elif sys.platform.find('darwin') != -1:
     exe_suffix   = ''
     obj_suffix   = '.o'
     shobj_suffix = '.os'
@@ -152,7 +152,7 @@ elif string.find(sys.platform, 'darwin') != -1:
     lib_suffix   = '.a'
     dll_prefix   = 'lib'
     dll_suffix   = '.dylib'
-elif string.find(sys.platform, 'sunos') != -1:
+elif sys.platform.find('sunos') != -1:
     exe_suffix   = ''
     obj_suffix   = '.o'
     shobj_suffix = '.os'
@@ -217,7 +217,7 @@ class TestCommon(TestCmd):
         calling the base class initialization, and then changing directory
         to the workdir.
         """
-        apply(TestCmd.__init__, [self], kw)
+        TestCmd.__init__(self, **kw)
         os.chdir(self.workdir)
 
     def must_be_writable(self, *files):
@@ -227,20 +227,20 @@ class TestCommon(TestCmd):
         them.  Exits FAILED if any of the files does not exist or is
         not writable.
         """
-        files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
+        files = [is_List(x) and os.path.join(*x) or x for x in files]
         existing, missing = separate_files(files)
-        unwritable = filter(lambda x, iw=is_writable: not iw(x), existing)
+        unwritable = [x for x in existing if not is_writable(x)]
         if missing:
-            print "Missing files: `%s'" % string.join(missing, "', `")
+            print "Missing files: `%s'" % "', `".join(missing)
         if unwritable:
-            print "Unwritable files: `%s'" % string.join(unwritable, "', `")
+            print "Unwritable files: `%s'" % "', `".join(unwritable)
         self.fail_test(missing + unwritable)
 
     def must_contain(self, file, required, mode = 'rb'):
         """Ensures that the specified file contains the required text.
         """
         file_contents = self.read(file, mode)
-        contains = (string.find(file_contents, required) != -1)
+        contains = (file_contents.find(required) != -1)
         if not contains:
             print "File `%s' does not contain required string." % file
             print self.banner('Required string ')
@@ -261,7 +261,7 @@ class TestCommon(TestCmd):
         for lines in the output.
         """
         if find is None:
-            find = lambda o, l: string.find(o, l) != -1
+            find = lambda o, l: o.find(l) != -1
         missing = []
         for line in lines:
             if not find(output, line):
@@ -289,7 +289,7 @@ class TestCommon(TestCmd):
         for lines in the output.
         """
         if find is None:
-            find = lambda o, l: string.find(o, l) != -1
+            find = lambda o, l: o.find(l) != -1
         for line in lines:
             if find(output, line):
                 return
@@ -313,10 +313,10 @@ class TestCommon(TestCmd):
         pathname will be constructed by concatenating them.  Exits FAILED
         if any of the files does not exist.
         """
-        files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
-        missing = filter(lambda x: not os.path.exists(x), files)
+        files = [is_List(x) and os.path.join(*x) or x for x in files]
+        missing = [x for x in files if not os.path.exists(x)]
         if missing:
-            print "Missing files: `%s'" % string.join(missing, "', `")
+            print "Missing files: `%s'" % "', `".join(missing)
             self.fail_test(missing)
 
     def must_match(self, file, expect, mode = 'rb'):
@@ -339,7 +339,7 @@ class TestCommon(TestCmd):
         """Ensures that the specified file doesn't contain the banned text.
         """
         file_contents = self.read(file, mode)
-        contains = (string.find(file_contents, banned) != -1)
+        contains = (file_contents.find(banned) != -1)
         if contains:
             print "File `%s' contains banned string." % file
             print self.banner('Banned string ')
@@ -360,7 +360,7 @@ class TestCommon(TestCmd):
         for lines in the output.
         """
         if find is None:
-            find = lambda o, l: string.find(o, l) != -1
+            find = lambda o, l: o.find(l) != -1
         unexpected = []
         for line in lines:
             if find(output, line):
@@ -385,10 +385,10 @@ class TestCommon(TestCmd):
         which case the pathname will be constructed by concatenating them.
         Exits FAILED if any of the files exists.
         """
-        files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
-        existing = filter(os.path.exists, files)
+        files = [is_List(x) and os.path.join(*x) or x for x in files]
+        existing = list(filter(os.path.exists, files))
         if existing:
-            print "Unexpected files exist: `%s'" % string.join(existing, "', `")
+            print "Unexpected files exist: `%s'" % "', `".join(existing)
             self.fail_test(existing)
 
 
@@ -399,13 +399,13 @@ class TestCommon(TestCmd):
         them.  Exits FAILED if any of the files does not exist or is
         writable.
         """
-        files = map(lambda x: is_List(x) and apply(os.path.join, x) or x, files)
+        files = [is_List(x) and os.path.join(*x) or x for x in files]
         existing, missing = separate_files(files)
-        writable = filter(is_writable, existing)
+        writable = list(filter(is_writable, existing))
         if missing:
-            print "Missing files: `%s'" % string.join(missing, "', `")
+            print "Missing files: `%s'" % "', `".join(missing)
         if writable:
-            print "Writable files: `%s'" % string.join(writable, "', `")
+            print "Writable files: `%s'" % "', `".join(writable)
         self.fail_test(missing + writable)
 
     def _complete(self, actual_stdout, expected_stdout,
@@ -458,9 +458,8 @@ class TestCommon(TestCmd):
                 else:
                     arguments = options + " " + arguments
         try:
-            return apply(TestCmd.start,
-                         (self, program, interpreter, arguments, universal_newlines),
-                         kw)
+            return TestCmd.start(self, program, interpreter, arguments, universal_newlines,
+                         **kw)
         except KeyboardInterrupt:
             raise
         except Exception, e:
@@ -496,7 +495,7 @@ class TestCommon(TestCmd):
                         command.  A value of None means don't
                         test exit status.
         """
-        apply(TestCmd.finish, (self, popen,), kw)
+        TestCmd.finish(self, popen, **kw)
         match = kw.get('match', self.match)
         self._complete(self.stdout(), stdout,
                        self.stderr(), stderr, status, match)
@@ -538,7 +537,7 @@ class TestCommon(TestCmd):
             del kw['match']
         except KeyError:
             match = self.match
-        apply(TestCmd.run, [self], kw)
+        TestCmd.run(self, **kw)
         self._complete(self.stdout(), stdout,
                        self.stderr(), stderr, status, match)
 
diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py
index 679a6aba..11f8ab2e 100644
--- a/QMTest/TestRuntest.py
+++ b/QMTest/TestRuntest.py
@@ -19,7 +19,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import os
 import os.path
 import re
-import string
 import shutil
 import sys
 
@@ -39,7 +38,7 @@ if re.search('\s', python):
     pythonstring = _python_
 else:
     pythonstring = python
-pythonstring = string.replace(pythonstring, '\\', '\\\\')
+pythonstring = pythonstring.replace('\\', '\\\\')
 
 
 failing_test_template = """\
@@ -108,14 +107,14 @@ class TestRuntest(TestCommon):
         appears in a normal workspace.
         """
         set_workpath_runtest = None
-        if not kw.has_key('program'):
+        if 'program' not in kw:
             kw['program'] = 'runtest.py'
             set_workpath_runtest = 1
-        if not kw.has_key('interpreter'):
+        if 'interpreter' not in kw:
             kw['interpreter'] = [python, '-tt']
-        if not kw.has_key('match'):
+        if 'match' not in kw:
             kw['match'] = match_exact
-        if not kw.has_key('workdir'):
+        if 'workdir' not in kw:
             kw['workdir'] = ''
 
         try:
@@ -126,7 +125,7 @@ class TestRuntest(TestCommon):
             del kw['noqmtest']
 
         orig_cwd = os.getcwd()
-        apply(TestCommon.__init__, [self], kw)
+        TestCommon.__init__(self, **kw)
   
         if not noqmtest:
             qmtest = self.where_is('qmtest')
@@ -141,7 +140,7 @@ class TestRuntest(TestCommon):
         dirs = [os.environ.get('SCONS_RUNTEST_DIR', orig_cwd)]
         
         spe = os.environ.get('SCONS_SOURCE_PATH_EXECUTABLE', orig_cwd)
-        for d in string.split(spe, os.pathsep):
+        for d in spe.split(os.pathsep):
             dirs.append(os.path.join(d, 'build'))
             dirs.append(d)
 
diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py
index 506f7084..38f2c926 100644
--- a/QMTest/TestSCons.py
+++ b/QMTest/TestSCons.py
@@ -13,13 +13,13 @@ attributes defined in this subclass.
 """
 
 # __COPYRIGHT__
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import re
 import shutil
-import string
 import sys
 import time
 
@@ -30,7 +30,7 @@ except AttributeError:
     def zip(*lists):
         result = []
         for i in xrange(len(lists[0])):
-            result.append(tuple(map(lambda l, i=i: l[i], lists)))
+            result.append(tuple([l[i] for l in lists]))
         return result
     __builtin__.zip = zip
 
@@ -123,7 +123,7 @@ def gccFortranLibs():
         stderr = p.stderr
 
     for l in stderr.readlines():
-        list = string.split(l)
+        list = l.split()
         if len(list) > 3 and list[:2] == ['gcc', 'version']:
             if list[2][:3] in ('4.1','4.2','4.3'):
                 libs = ['gfortranbegin']
@@ -148,7 +148,7 @@ if sys.platform == 'win32':
     fortran_lib = gccFortranLibs()
 elif sys.platform == 'cygwin':
     fortran_lib = gccFortranLibs()
-elif string.find(sys.platform, 'irix') != -1:
+elif sys.platform.find('irix') != -1:
     fortran_lib = ['ftn']
 else:
     fortran_lib = gccFortranLibs()
@@ -161,7 +161,7 @@ file_expr = r"""File "[^"]*", line \d+, in .+
 # re.escape escapes too much.
 def re_escape(str):
     for c in ['.', '[', ']', '(', ')', '*', '+', '?']:  # Not an exhaustive list.
-        str = string.replace(str, c, '\\' + c)
+        str = str.replace(c, '\\' + c)
     return str
 
 
@@ -170,12 +170,12 @@ try:
     sys.version_info
 except AttributeError:
     # Pre-1.6 Python has no sys.version_info
-    version_string = string.split(sys.version)[0]
-    version_ints = map(int, string.split(version_string, '.'))
+    version_string = sys.version.split()[0]
+    version_ints = list(map(int, version_string.split('.')))
     sys.version_info = tuple(version_ints + ['final', 0])
 
 def python_version_string():
-    return string.split(sys.version)[0]
+    return sys.version.split()[0]
 
 def python_minor_version_string():
     return sys.version[:3]
@@ -234,7 +234,7 @@ class TestSCons(TestCommon):
             pass
         else:
             os.chdir(script_dir)
-        if not kw.has_key('program'):
+        if 'program' not in kw:
             kw['program'] = os.environ.get('SCONS')
             if not kw['program']:
                 if os.path.exists('scons'):
@@ -243,11 +243,11 @@ class TestSCons(TestCommon):
                     kw['program'] = 'scons.py'
             elif not os.path.isabs(kw['program']):
                 kw['program'] = os.path.join(self.orig_cwd, kw['program'])
-        if not kw.has_key('interpreter') and not os.environ.get('SCONS_EXEC'):
+        if 'interpreter' not in kw and not os.environ.get('SCONS_EXEC'):
             kw['interpreter'] = [python, '-tt']
-        if not kw.has_key('match'):
+        if 'match' not in kw:
             kw['match'] = match_exact
-        if not kw.has_key('workdir'):
+        if 'workdir' not in kw:
             kw['workdir'] = ''
 
         # Term causing test failures due to bogus readline init
@@ -266,9 +266,9 @@ class TestSCons(TestCommon):
             else:
                 sconsflags = []
             sconsflags = sconsflags + ['--warn=no-python-version']
-            os.environ['SCONSFLAGS'] = string.join(sconsflags)
+            os.environ['SCONSFLAGS'] = ' '.join(sconsflags)
 
-        apply(TestCommon.__init__, [self], kw)
+        TestCommon.__init__(self, **kw)
 
         import SCons.Node.FS
         if SCons.Node.FS.default_fs is None:
@@ -284,7 +284,7 @@ class TestSCons(TestCommon):
         if not ENV is None:
             kw['ENV'] = ENV
         try:
-            return apply(SCons.Environment.Environment, args, kw)
+            return SCons.Environment.Environment(*args, **kw)
         except (SCons.Errors.UserError, SCons.Errors.InternalError):
             return None
 
@@ -307,7 +307,7 @@ class TestSCons(TestCommon):
             return None
         result = env.WhereIs(prog)
         if norm and os.sep != '/':
-            result = string.replace(result, os.sep, '/')
+            result = result.replace(os.sep, '/')
         return result
 
     def detect_tool(self, tool, prog=None, ENV=None):
@@ -376,16 +376,16 @@ class TestSCons(TestCommon):
         # support the --warn=no-visual-c-missing warning.)
         sconsflags = sconsflags + [os.environ.get('TESTSCONS_SCONSFLAGS',
                                                   '--warn=no-visual-c-missing')]
-        os.environ['SCONSFLAGS'] = string.join(sconsflags)
+        os.environ['SCONSFLAGS'] = ' '.join(sconsflags)
         try:
-            result = apply(TestCommon.run, (self,)+args, kw)
+            result = TestCommon.run(self, *args, **kw)
         finally:
             sconsflags = save_sconsflags
         return result
 
     def up_to_date(self, options = None, arguments = None, read_str = "", **kw):
         s = ""
-        for arg in string.split(arguments):
+        for arg in arguments.split():
             s = s + "scons: `%s' is up to date.\n" % arg
             if options:
                 arguments = options + " " + arguments
@@ -395,7 +395,7 @@ class TestSCons(TestCommon):
         # up-to-date output is okay.
         kw['stdout'] = re.escape(stdout) + '.*'
         kw['match'] = self.match_re_dotall
-        apply(self.run, [], kw)
+        self.run(**kw)
 
     def not_up_to_date(self, options = None, arguments = None, **kw):
         """Asserts that none of the targets listed in arguments is
@@ -403,16 +403,16 @@ class TestSCons(TestCommon):
         This function is most useful in conjunction with the -n option.
         """
         s = ""
-        for arg in string.split(arguments):
+        for arg in arguments.split():
             s = s + "(?!scons: `%s' is up to date.)" % re.escape(arg)
             if options:
                 arguments = options + " " + arguments
         s = '('+s+'[^\n]*\n)*'
         kw['arguments'] = arguments
         stdout = re.escape(self.wrap_stdout(build_str='ARGUMENTSGOHERE'))
-        kw['stdout'] = string.replace(stdout, 'ARGUMENTSGOHERE', s)
+        kw['stdout'] = stdout.replace('ARGUMENTSGOHERE', s)
         kw['match'] = self.match_re_dotall
-        apply(self.run, [], kw)
+        self.run(**kw)
 
     def option_not_yet_implemented(self, option, arguments=None, **kw):
         """
@@ -430,7 +430,7 @@ class TestSCons(TestCommon):
                 kw['arguments'] = option + ' ' + arguments
         # TODO(1.5)
         #return self.run(**kw)
-        return apply(self.run, (), kw)
+        return self.run(**kw)
 
     def diff_substr(self, expect, actual, prelen=20, postlen=40):
         i = 0
@@ -461,9 +461,9 @@ class TestSCons(TestCommon):
         places, abstracting out the version difference.
         """
         exec 'import traceback; x = traceback.format_stack()[-1]'
-        x = string.lstrip(x)
-        x = string.replace(x, '<string>', file)
-        x = string.replace(x, 'line 1,', 'line %s,' % line)
+        x = x.lstrip()
+        x = x.replace('<string>', file)
+        x = x.replace('line 1,', 'line %s,' % line)
         return x
 
     def normalize_pdf(self, s):
@@ -486,12 +486,12 @@ class TestSCons(TestCommon):
             end_marker = 'endstream\nendobj'
 
             encoded = []
-            b = string.find(s, begin_marker, 0)
+            b = s.find(begin_marker, 0)
             while b != -1:
                 b = b + len(begin_marker)
-                e = string.find(s, end_marker, b)
+                e = s.find(end_marker, b)
                 encoded.append((b, e))
-                b = string.find(s, begin_marker, e + len(end_marker))
+                b = s.find(begin_marker, e + len(end_marker))
 
             x = 0
             r = []
@@ -507,7 +507,7 @@ class TestSCons(TestCommon):
                 r.append(d)
                 x = e
             r.append(s[x:])
-            s = string.join(r, '')
+            s = ''.join(r)
 
         return s
 
@@ -553,7 +553,7 @@ class TestSCons(TestCommon):
             ]
             java_path = self.paths(patterns) + [env['ENV']['PATH']]
 
-        env['ENV']['PATH'] = string.join(java_path, os.pathsep)
+        env['ENV']['PATH'] = os.pathsep.join(java_path)
         return env['ENV']
 
     def java_where_includes(self,version=None):
@@ -634,7 +634,7 @@ class TestSCons(TestCommon):
                  stderr=None,
                  status=None)
         if version:
-            if string.find(self.stderr(), 'javac %s' % version) == -1:
+            if self.stderr().find('javac %s' % version) == -1:
                 fmt = "Could not find javac for Java version %s, skipping test(s).\n"
                 self.skip_test(fmt % version)
         else:
@@ -673,7 +673,6 @@ class TestSCons(TestCommon):
         self.write([dir, 'bin', 'mymoc.py'], """\
 import getopt
 import sys
-import string
 import re
 # -w and -z are fake options used in test/QT/QTFLAGS.py
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'io:wz', [])
@@ -687,11 +686,11 @@ for opt, arg in cmd_opts:
 output.write("/* mymoc.py%s */\\n" % opt_string)
 for a in args:
     contents = open(a, 'rb').read()
-    a = string.replace(a, '\\\\', '\\\\\\\\')
+    a = a.replace('\\\\', '\\\\\\\\')
     subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }'
     if impl:
         contents = re.sub( r'#include.*', '', contents )
-    output.write(string.replace(contents, 'Q_OBJECT', subst))
+    output.write(contents.replace('Q_OBJECT', subst))
 output.close()
 sys.exit(0)
 """)
@@ -700,7 +699,6 @@ sys.exit(0)
 import os.path
 import re
 import sys
-import string
 output_arg = 0
 impl_arg = 0
 impl = None
@@ -773,7 +771,7 @@ else:
 
     def Qt_create_SConstruct(self, place):
         if type(place) is type([]):
-            place = apply(test.workpath, place)
+            place = test.workpath(*place)
         self.write(place, """\
 if ARGUMENTS.get('noqtdir', 0): QTDIR=None
 else: QTDIR=r'%s'
@@ -845,7 +843,7 @@ SConscript( sconscript )
             lastEnd = 0
             logfile = self.read(self.workpath(logfile))
             if (doCheckLog and
-                string.find( logfile, "scons: warning: The stored build "
+                logfile.find( "scons: warning: The stored build "
                              "information has an unexpected class." ) >= 0):
                 self.fail_test()
             sconf_dir = sconf_dir
@@ -957,7 +955,7 @@ print os.path.join(sys.prefix, 'lib', py_ver, 'config')
 print py_ver
 """)
 
-        return [python] + string.split(string.strip(self.stdout()), '\n')
+        return [python] + self.stdout().strip().split('\n')
 
     def start(self, *args, **kw):
         """
@@ -967,9 +965,9 @@ print py_ver
         use standard input without forcing every .start() call in the
         individual tests to do so explicitly.
         """
-        if not kw.has_key('stdin'):
+        if 'stdin' not in kw:
             kw['stdin'] = True
-        return apply(TestCommon.start, (self,) + args, kw)
+        return TestCommon.start(self, *args, **kw)
 
     def wait_for(self, fname, timeout=10.0, popen=None):
         """
@@ -1058,12 +1056,12 @@ class TimeSCons(TestSCons):
 
         self.calibrate = os.environ.get('TIMESCONS_CALIBRATE', '0') != '0'
 
-        if not kw.has_key('verbose') and not self.calibrate:
+        if 'verbose' not in kw and not self.calibrate:
             kw['verbose'] = True
 
         # TODO(1.5)
         #TestSCons.__init__(self, *args, **kw)
-        apply(TestSCons.__init__, (self,)+args, kw)
+        TestSCons.__init__(self, *args, **kw)
 
         # TODO(sgk):    better way to get the script dir than sys.argv[0]
         test_dir = os.path.dirname(sys.argv[0])
@@ -1090,7 +1088,7 @@ class TimeSCons(TestSCons):
         The elapsed time to execute each build is printed after
         it has finished.
         """
-        if not kw.has_key('options') and self.variables:
+        if 'options' not in kw and self.variables:
             options = []
             for variable, value in self.variables.items():
                 options.append('%s=%s' % (variable, value))
@@ -1098,16 +1096,16 @@ class TimeSCons(TestSCons):
         if self.calibrate:
             # TODO(1.5)
             #self.calibration(*args, **kw)
-            apply(self.calibration, args, kw)
+            self.calibration(*args, **kw)
         else:
             self.uptime()
             # TODO(1.5)
             #self.startup(*args, **kw)
             #self.full(*args, **kw)
             #self.null(*args, **kw)
-            apply(self.startup, args, kw)
-            apply(self.full, args, kw)
-            apply(self.null, args, kw)
+            self.startup(*args, **kw)
+            self.full(*args, **kw)
+            self.null(*args, **kw)
 
     def trace(self, graph, name, value, units, sort=None):
         fmt = "TRACE: graph=%s name=%s value=%s units=%s"
@@ -1127,7 +1125,7 @@ class TimeSCons(TestSCons):
         for name, args in stats.items():
             # TODO(1.5)
             #self.trace(name, trace, *args)
-            apply(self.trace, (name, trace), args)
+            self.trace(name, trace, **args)
 
     def uptime(self):
         try:
@@ -1168,7 +1166,7 @@ class TimeSCons(TestSCons):
         kw['status'] = None
         # TODO(1.5)
         #self.run(*args, **kw)
-        apply(self.run, args, kw)
+        self.run(*args, **kw)
         sys.stdout.write(self.stdout())
         stats = self.collect_stats(self.stdout())
         # Delete the time-commands, since no commands are ever
@@ -1182,7 +1180,7 @@ class TimeSCons(TestSCons):
         """
         # TODO(1.5)
         #self.run(*args, **kw)
-        apply(self.run, args, kw)
+        self.run(*args, **kw)
         sys.stdout.write(self.stdout())
         stats = self.collect_stats(self.stdout())
         self.report_traces('full', stats)
@@ -1190,9 +1188,9 @@ class TimeSCons(TestSCons):
         #self.trace('full-memory', 'initial', **stats['memory-initial'])
         #self.trace('full-memory', 'prebuild', **stats['memory-prebuild'])
         #self.trace('full-memory', 'final', **stats['memory-final'])
-        apply(self.trace, ('full-memory', 'initial'), stats['memory-initial'])
-        apply(self.trace, ('full-memory', 'prebuild'), stats['memory-prebuild'])
-        apply(self.trace, ('full-memory', 'final'), stats['memory-final'])
+        self.trace('full-memory', 'initial', **stats['memory-initial'])
+        self.trace('full-memory', 'prebuild', **stats['memory-prebuild'])
+        self.trace('full-memory', 'final', **stats['memory-final'])
 
     def calibration(self, *args, **kw):
         """
@@ -1202,7 +1200,7 @@ class TimeSCons(TestSCons):
         """
         # TODO(1.5)
         #self.run(*args, **kw)
-        apply(self.run, args, kw)
+        self.run(*args, **kw)
         if self.variables:
             for variable, value in self.variables.items():
                 sys.stdout.write('VARIABLE: %s=%s\n' % (variable, value))
@@ -1218,7 +1216,7 @@ class TimeSCons(TestSCons):
         #self.up_to_date(arguments='.', **kw)
         kw = kw.copy()
         kw['arguments'] = '.'
-        apply(self.up_to_date, (), kw)
+        self.up_to_date(**kw)
         sys.stdout.write(self.stdout())
         stats = self.collect_stats(self.stdout())
         # time-commands should always be 0.0 on a null build, because
@@ -1233,9 +1231,9 @@ class TimeSCons(TestSCons):
         #self.trace('null-memory', 'initial', **stats['memory-initial'])
         #self.trace('null-memory', 'prebuild', **stats['memory-prebuild'])
         #self.trace('null-memory', 'final', **stats['memory-final'])
-        apply(self.trace, ('null-memory', 'initial'), stats['memory-initial'])
-        apply(self.trace, ('null-memory', 'prebuild'), stats['memory-prebuild'])
-        apply(self.trace, ('null-memory', 'final'), stats['memory-final'])
+        self.trace('null-memory', 'initial', **stats['memory-initial'])
+        self.trace('null-memory', 'prebuild', **stats['memory-prebuild'])
+        self.trace('null-memory', 'final', **stats['memory-final'])
 
     def elapsed_time(self):
         """
@@ -1257,7 +1255,7 @@ class TimeSCons(TestSCons):
         try:
             # TODO(1.5)
             #result = TestSCons.run(self, *args, **kw)
-            result = apply(TestSCons.run, (self,)+args, kw)
+            result = TestSCons.run(self, *args, **kw)
         finally:
             self.endTime = time.time()
         return result
@@ -1278,8 +1276,8 @@ class TimeSCons(TestSCons):
             #dirs = [ d for d in dirs if not d.startswith('TimeSCons-') ]
             #files = [ f for f in files if not f.startswith('TimeSCons-') ]
             not_timescons_entries = lambda s: not s.startswith('TimeSCons-')
-            dirs = filter(not_timescons_entries, dirs)
-            files = filter(not_timescons_entries, files)
+            dirs = list(filter(not_timescons_entries, dirs))
+            files = list(filter(not_timescons_entries, files))
             for dirname in dirs:
                 source = os.path.join(root, dirname)
                 destination = source.replace(source_dir, dest_dir)
diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py
index 0f6fc6f3..ac10cd36 100644
--- a/QMTest/TestSConsMSVS.py
+++ b/QMTest/TestSConsMSVS.py
@@ -18,7 +18,6 @@ in this subclass.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 from TestSCons import *
@@ -596,7 +595,7 @@ print "self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions())
         replace = 'sys.path = [ %s, join(sys' % enginepath
 
         contents = self.read(fname)
-        contents = string.replace(contents, orig, replace)
+        contents = contents.replace(orig, replace)
         self.write(fname, contents)
 
     def msvs_substitute(self, input, msvs_ver,
@@ -620,18 +619,18 @@ print "self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions())
         if project_guid is None:
             project_guid = "{E5466E26-0003-F18B-8F8A-BCD76C86388D}"
 
-        if os.environ.has_key('SCONS_LIB_DIR'):
+        if 'SCONS_LIB_DIR' in os.environ:
             exec_script_main = "from os.path import join; import sys; sys.path = [ r'%s' ] + sys.path; import SCons.Script; SCons.Script.main()" % os.environ['SCONS_LIB_DIR']
         else:
             exec_script_main = "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-%s'), join(sys.prefix, 'scons-%s'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()" % (self.scons_version, self.scons_version)
-        exec_script_main_xml = string.replace(exec_script_main, "'", "&apos;")
-
-        result = string.replace(input, r'<WORKPATH>', workpath)
-        result = string.replace(result, r'<PYTHON>', python)
-        result = string.replace(result, r'<SCONSCRIPT>', sconscript)
-        result = string.replace(result, r'<SCONS_SCRIPT_MAIN>', exec_script_main)
-        result = string.replace(result, r'<SCONS_SCRIPT_MAIN_XML>', exec_script_main_xml)
-        result = string.replace(result, r'<PROJECT_GUID>', project_guid)
+        exec_script_main_xml = exec_script_main.replace("'", "&apos;")
+
+        result = input.replace(r'<WORKPATH>', workpath)
+        result = result.replace(r'<PYTHON>', python)
+        result = result.replace(r'<SCONSCRIPT>', sconscript)
+        result = result.replace(r'<SCONS_SCRIPT_MAIN>', exec_script_main)
+        result = result.replace(r'<SCONS_SCRIPT_MAIN_XML>', exec_script_main_xml)
+        result = result.replace(r'<PROJECT_GUID>', project_guid)
         return result
 
     def get_msvs_executable(self, version):
@@ -655,9 +654,9 @@ print "self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions())
         else:
             sconsflags = []
         sconsflags = sconsflags + ['--warn=no-deprecated']
-        os.environ['SCONSFLAGS'] = string.join(sconsflags)
+        os.environ['SCONSFLAGS'] = ' '.join(sconsflags)
         try:
-            result = apply(TestSCons.run, (self,)+args, kw)
+            result = TestSCons.run(self, *args, **kw)
         finally:
             os.environ['SCONSFLAGS'] = save_sconsflags or ''
         return result
diff --git a/QMTest/TestSCons_time.py b/QMTest/TestSCons_time.py
index f9a639eb..e846ab59 100644
--- a/QMTest/TestSCons_time.py
+++ b/QMTest/TestSCons_time.py
@@ -17,7 +17,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import sys
 
 from TestCommon import *
@@ -168,7 +167,7 @@ class TestSCons_time(TestCommon):
             pass
         else:
             os.chdir(script_dir)
-        if not kw.has_key('program'):
+        if 'program' not in kw:
             p = os.environ.get('SCONS_TIME')
             if not p:
                 p = 'scons-time'
@@ -176,16 +175,16 @@ class TestSCons_time(TestCommon):
                     p = 'scons-time.py'
             kw['program'] = p
 
-        if not kw.has_key('interpreter'):
+        if 'interpreter' not in kw:
             kw['interpreter'] = [python, '-tt']
 
-        if not kw.has_key('match'):
+        if 'match' not in kw:
             kw['match'] = match_exact
 
-        if not kw.has_key('workdir'):
+        if 'workdir' not in kw:
             kw['workdir'] = ''
 
-        apply(TestCommon.__init__, [self], kw)
+        TestCommon.__init__(self, **kw)
 
         # Now that the testing object has been set up, check if we should
         # skip the test due to the Python version.  We need to be able to
@@ -196,14 +195,14 @@ class TestSCons_time(TestCommon):
         try:
             import __future__
         except ImportError:
-            version = string.split(sys.version)[0]
+            version = sys.version.split()[0]
             msg = 'scons-time does not work on Python version %s\n' % version
             self.skip_test(msg)
 
         try:
             eval('[x for x in [1, 2]]')
         except SyntaxError:
-            version = string.split(sys.version)[0]
+            version = sys.version.split()[0]
             msg = 'scons-time does not work on Python version %s\n' % version
             self.skip_test(msg)
 
@@ -247,9 +246,9 @@ class TestSCons_time(TestCommon):
             tempdir = realpath(tempdir)
 
         args = (tempdir, 'scons-time-',) + args
-        x = apply(os.path.join, args)
+        x = os.path.join(*args)
         x = re.escape(x)
-        x = string.replace(x, 'time\\-', 'time\\-[^%s]*' % sep)
+        x = x.replace('time\\-', 'time\\-[^%s]*' % sep)
         return x
 
     def write_fake_aegis_py(self, name):
diff --git a/QMTest/TestSConsign.py b/QMTest/TestSConsign.py
index 29d8b2ce..700c242c 100644
--- a/QMTest/TestSConsign.py
+++ b/QMTest/TestSConsign.py
@@ -19,7 +19,6 @@ in this subclass.
 
 import os
 import os.path
-import string
 import sys
 
 from TestSCons import *
@@ -48,13 +47,13 @@ class TestSConsign(TestSCons):
             os.chdir(script_dir)
         self.script_dir = os.getcwd()
 
-        apply(TestSCons.__init__, (self,)+args, kw)
+        TestSCons.__init__(self, *args, **kw)
 
         self.my_kw = {
             'interpreter' : python,     # imported from TestSCons
         }
 
-        if not kw.has_key('program'):
+        if 'program' not in kw:
             kw['program'] = os.environ.get('SCONS')
             if not kw['program']:
                 if os.path.exists('scons'):
@@ -81,7 +80,7 @@ class TestSConsign(TestSCons):
 
     def run_sconsign(self, *args, **kw):
         kw.update(self.my_kw)
-        return apply(self.run, args, kw)
+        return self.run(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py
index b725d3fc..73e84308 100644
--- a/QMTest/scons_tdb.py
+++ b/QMTest/scons_tdb.py
@@ -22,13 +22,14 @@
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
 
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
 """
 QMTest classes to support SCons' testing and Aegis-inspired workflow.
 
 Thanks to Stefan Seefeld for the initial code.
 """
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 ########################################################################
 # Imports
@@ -96,7 +97,7 @@ def get_explicit_arguments(e):
         # Do not record computed fields.
         if field.IsComputed():
             continue
-        if e.__dict__.has_key(name):
+        if name in e.__dict__:
             explicit_arguments[name] = e.__dict__[name]
 
     return explicit_arguments
@@ -153,10 +154,10 @@ sys_attributes = [
 
 def get_sys_values():
     sys_attributes.sort()
-    result = map(lambda k: (k, getattr(sys, k, _null)), sys_attributes)
-    result = filter(lambda t: not t[1] is _null, result)
-    result = map(lambda t: t[0] + '=' + repr(t[1]), result)
-    return string.join(result, '\n ')
+    result = [(k, getattr(sys, k, _null)) for k in sys_attributes]
+    result = [t for t in result if not t[1] is _null]
+    result = [t[0] + '=' + repr(t[1]) for t in result]
+    return '\n '.join(result)
 
 module_attributes = [
     '__version__',
@@ -168,10 +169,10 @@ module_attributes = [
 
 def get_module_info(module):
     module_attributes.sort()
-    result = map(lambda k: (k, getattr(module, k, _null)), module_attributes)
-    result = filter(lambda t: not t[1] is _null, result)
-    result = map(lambda t: t[0] + '=' + repr(t[1]), result)
-    return string.join(result, '\n ')
+    result = [(k, getattr(module, k, _null)) for k in module_attributes]
+    result = [t for t in result if not t[1] is _null]
+    result = [t[0] + '=' + repr(t[1]) for t in result]
+    return '\n '.join(result)
 
 environ_keys = [
    'PATH',
@@ -214,10 +215,10 @@ environ_keys = [
 
 def get_environment():
     environ_keys.sort()
-    result = map(lambda k: (k, os.environ.get(k, _null)), environ_keys)
-    result = filter(lambda t: not t[1] is _null, result)
-    result = map(lambda t: t[0] + '-' + t[1], result)
-    return string.join(result, '\n ')
+    result = [(k, os.environ.get(k, _null)) for k in environ_keys]
+    result = [t for t in result if not t[1] is _null]
+    result = [t[0] + '-' + t[1] for t in result]
+    return '\n '.join(result)
 
 class SConsXMLResultStream(XMLResultStream):
     def __init__(self, *args, **kw):
@@ -400,7 +401,7 @@ class AegisBatchStream(FileResultStream):
         file_names.sort()
         for file_name in file_names:
             exit_status = self._outcomes[file_name]
-            file_name = string.replace(file_name, '\\', '/')
+            file_name = file_name.replace('\\', '/')
             self.file.write('    { file_name = "%s";\n' % file_name)
             self.file.write('      exit_status = %s; },\n' % exit_status)
         self.file.write('];\n')
diff --git a/QMTest/unittest.py b/QMTest/unittest.py
index c74a4c76..e5a86686 100644
--- a/QMTest/unittest.py
+++ b/QMTest/unittest.py
@@ -28,6 +28,7 @@ PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
 AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
 SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 """
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __author__ = "Steve Purcell (stephen_purcell@yahoo.com)"
 __version__ = "$ Revision: 1.23 $"[11:-2]
@@ -35,15 +36,14 @@ __version__ = "$ Revision: 1.23 $"[11:-2]
 import time
 import sys
 import traceback
-import string
 import os
 
 ##############################################################################
 # A platform-specific concession to help the code work for JPython users
 ##############################################################################
 
-plat = string.lower(sys.platform)
-_isJPython = string.find(plat, 'java') >= 0 or string.find(plat, 'jdk') >= 0
+plat = sys.platform.lower()
+_isJPython = plat.find('java') >= 0 or plat.find('jdk') >= 0
 del plat
 
 
@@ -149,7 +149,7 @@ class TestCase:
         the specified test method's docstring.
         """
         doc = self.__testMethod.__doc__
-        return doc and string.strip(string.split(doc, "\n")[0]) or None
+        return doc and doc.split("\n")[0].strip() or None
 
     def id(self):
         return "%s.%s" % (self.__class__, self.__testMethod.__name__)
@@ -205,7 +205,7 @@ class TestCase:
 
     def failIf(self, expr, msg=None):
         "Fail the test if the expression is true."
-        apply(self.assert_,(not expr,msg))
+        self.assert_(not expr,msg)
 
     def assertRaises(self, excClass, callableObj, *args, **kwargs):
         """Assert that an exception of class excClass is thrown
@@ -216,7 +216,7 @@ class TestCase:
            unexpected exception.
         """
         try:
-            apply(callableObj, args, kwargs)
+            callableObj(*args, **kwargs)
         except excClass:
             return
         else:
@@ -326,7 +326,7 @@ class FunctionTestCase(TestCase):
     def shortDescription(self):
         if self.__description is not None: return self.__description
         doc = self.__testFunc.__doc__
-        return doc and string.strip(string.split(doc, "\n")[0]) or None
+        return doc and doc.split("\n")[0].strip() or None
 
 
 
@@ -339,8 +339,7 @@ def getTestCaseNames(testCaseClass, prefix, sortUsing=cmp):
        and its base classes that start with the given prefix. This is used
        by makeSuite().
     """
-    testFnNames = filter(lambda n,p=prefix: n[:len(p)] == p,
-                         dir(testCaseClass))
+    testFnNames = [n for n in dir(testCaseClass) if n[:len(prefix)] == prefix]
     for baseclass in testCaseClass.__bases__:
         testFnNames = testFnNames + \
                       getTestCaseNames(baseclass, prefix, sortUsing=None)
@@ -355,8 +354,8 @@ def makeSuite(testCaseClass, prefix='test', sortUsing=cmp):
        prefix. The cases are sorted by their function names
        using the supplied comparison function, which defaults to 'cmp'.
     """
-    cases = map(testCaseClass,
-                getTestCaseNames(testCaseClass, prefix, sortUsing))
+    cases = list(map(testCaseClass,
+                getTestCaseNames(testCaseClass, prefix, sortUsing)))
     return TestSuite(cases)
 
 
@@ -376,18 +375,18 @@ def createTestInstance(name, module=None):
         -- returns result of calling makeSuite(ListTestCase, prefix="check")
     """
           
-    spec = string.split(name, ':')
+    spec = name.split(':')
     if len(spec) > 2: raise ValueError, "illegal test name: %s" % name
     if len(spec) == 1:
         testName = spec[0]
         caseName = None
     else:
         testName, caseName = spec
-    parts = string.split(testName, '.')
+    parts = testName.split('.')
     if module is None:
         if len(parts) < 2:
             raise ValueError, "incomplete test name: %s" % name
-        constructor = __import__(string.join(parts[:-1],'.'))
+        constructor = __import__('.'.join(parts[:-1]))
         parts = parts[1:]
     else:
         constructor = module
@@ -429,7 +428,7 @@ class _WritelnDecorator:
         return getattr(self.stream,attr)
 
     def writeln(self, *args):
-        if args: apply(self.write, args)
+        if args: self.write(*args)
         self.write(self.linesep)
 
  
@@ -468,7 +467,7 @@ class _JUnitTextTestResult(TestResult):
                                 (len(errors), errFlavour))
         i = 1
         for test,error in errors:
-            errString = string.join(apply(traceback.format_exception,error),"")
+            errString = "".join(traceback.format_exception(*error))
             self.stream.writeln("%i) %s" % (i, test))
             self.stream.writeln(errString)
             i = i + 1
@@ -567,8 +566,8 @@ class _VerboseTextTestResult(TestResult):
             self.stream.writeln(separator1)
         self.stream.writeln("\t%s" % flavour)
         self.stream.writeln(separator2)
-        for line in apply(traceback.format_exception, err):
-            for l in string.split(line,"\n")[:-1]:
+        for line in traceback.format_exception(*err):
+            for l in line.split("\n")[:-1]:
                 self.stream.writeln("\t%s" % l)
         self.stream.writeln(separator1)
 
@@ -597,9 +596,10 @@ class VerboseTextTestRunner:
         self.stream.writeln()
         if not result.wasSuccessful():
             self.stream.write("FAILED (")
-            failed, errored = map(len, (result.failures, result.errors))
+            failed = len(result.failures)
             if failed:
                 self.stream.write("failures=%d" % failed)
+            errored = len(result.errors)
             if errored:
                 if failed: self.stream.write(", ")
                 self.stream.write("errors=%d" % errored)
@@ -635,7 +635,7 @@ Examples:
                  argv=None, testRunner=None):
         if type(module) == type(''):
             self.module = __import__(module)
-            for part in string.split(module,'.')[1:]:
+            for part in module.split('.')[1:]:
                 self.module = getattr(self.module, part)
         else:
             self.module = module
diff --git a/SConstruct b/SConstruct
index dc2036b5..b90ae5a7 100644
--- a/SConstruct
+++ b/SConstruct
@@ -3,6 +3,7 @@
 #
 # See the README file for an overview of how SCons is built and tested.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 # When this gets changed, you must also change the copyright_years string
 # in QMTest/TestSCons.py so the test scripts look for the right string.
@@ -40,7 +41,6 @@ import os
 import os.path
 import re
 import stat
-import string
 import sys
 import tempfile
 
@@ -60,7 +60,7 @@ def whereis(file):
     exts = ['']
     if platform == "win32":
         exts += ['.exe']
-    for dir in string.split(os.environ['PATH'], os.pathsep):
+    for dir in os.environ['PATH'].split(os.pathsep):
         f = os.path.join(dir, file)
         for ext in exts:
             f_ext = f + ext
@@ -106,7 +106,7 @@ if not developer:
 build_system = ARGUMENTS.get('BUILD_SYSTEM')
 if not build_system:
     import socket
-    build_system = string.split(socket.gethostname(), '.')[0]
+    build_system = socket.gethostname().split('.')[0]
 
 version = ARGUMENTS.get('VERSION', '')
 if not version:
@@ -137,7 +137,7 @@ if not revision and hg:
             revision = b.group(1) + ':' + revision
         def generate_build_id(revision):
             result = revision
-            if filter(lambda l: l[0] in 'AMR!', hg_status_lines):
+            if [l for l in hg_status_lines if l[0] in 'AMR!']:
                 result = result + '[MODIFIED]'
             return result
 
@@ -148,7 +148,7 @@ if not revision and svn:
         revision = m.group(1)
         def generate_build_id(revision):
             result = 'r' + revision
-            if filter(lambda l: l[0] in 'ACDMR', svn_status_lines):
+            if [l for l in svn_status_lines if l[0] in 'ACDMR']:
                 result = result + '[MODIFIED]'
             return result
 
@@ -175,7 +175,7 @@ python_ver = sys.version[0:3]
 
 ENV = { 'PATH' : os.environ['PATH'] }
 for key in ['LOGNAME', 'PYTHONPATH', 'LD_LIBRARY_PATH']:
-    if os.environ.has_key(key):
+    if key in os.environ:
         ENV[key] = os.environ[key]
 
 build_dir = ARGUMENTS.get('BUILDDIR', 'build')
@@ -365,16 +365,16 @@ def SCons_revision(target, source, env):
     # Note:  We construct the __*__ substitution strings here
     # so that they don't get replaced when this file gets
     # copied into the tree for packaging.
-    contents = string.replace(contents, '__BUILD'     + '__', env['BUILD'])
-    contents = string.replace(contents, '__BUILDSYS'  + '__', env['BUILDSYS'])
-    contents = string.replace(contents, '__COPYRIGHT' + '__', env['COPYRIGHT'])
-    contents = string.replace(contents, '__DATE'      + '__', env['DATE'])
-    contents = string.replace(contents, '__DEVELOPER' + '__', env['DEVELOPER'])
-    contents = string.replace(contents, '__FILE'      + '__', str(source[0]))
-    contents = string.replace(contents, '__MONTH_YEAR'+ '__', env['MONTH_YEAR'])
-    contents = string.replace(contents, '__REVISION'  + '__', env['REVISION'])
-    contents = string.replace(contents, '__VERSION'   + '__', env['VERSION'])
-    contents = string.replace(contents, '__NULL'      + '__', '')
+    contents = contents.replace('__BUILD'     + '__', env['BUILD'])
+    contents = contents.replace('__BUILDSYS'  + '__', env['BUILDSYS'])
+    contents = contents.replace('__COPYRIGHT' + '__', env['COPYRIGHT'])
+    contents = contents.replace('__DATE'      + '__', env['DATE'])
+    contents = contents.replace('__DEVELOPER' + '__', env['DEVELOPER'])
+    contents = contents.replace('__FILE'      + '__', str(source[0]))
+    contents = contents.replace('__MONTH_YEAR'+ '__', env['MONTH_YEAR'])
+    contents = contents.replace('__REVISION'  + '__', env['REVISION'])
+    contents = contents.replace('__VERSION'   + '__', env['VERSION'])
+    contents = contents.replace('__NULL'      + '__', '')
     open(t, 'wb').write(contents)
     os.chmod(t, os.stat(s)[0])
 
@@ -708,7 +708,7 @@ for p in [ scons ]:
     pkg_version = "%s-%s" % (pkg, version)
 
     src = 'src'
-    if p.has_key('src_subdir'):
+    if 'src_subdir' in p:
         src = os.path.join(src, p['src_subdir'])
 
     build = os.path.join(build_dir, pkg)
@@ -747,15 +747,14 @@ for p in [ scons ]:
     # destination files.
     #
     manifest_in = File(os.path.join(src, 'MANIFEST.in')).rstr()
-    src_files = map(lambda x: x[:-1],
-                    open(manifest_in).readlines())
+    src_files = [x[:-1] for x in open(manifest_in).readlines()]
     raw_files = src_files[:]
     dst_files = src_files[:]
     rpm_files = []
 
     MANIFEST_in_list = []
 
-    if p.has_key('subpkgs'):
+    if 'subpkgs' in p:
         #
         # This package includes some sub-packages.  Read up their
         # MANIFEST.in files, and add them to our source and destination
@@ -767,9 +766,9 @@ for p in [ scons ]:
             isubdir = p['subinst_dirs'][sp['pkg']]
             MANIFEST_in = File(os.path.join(src, ssubdir, 'MANIFEST.in')).rstr()
             MANIFEST_in_list.append(MANIFEST_in)
-            files = map(lambda x: x[:-1], open(MANIFEST_in).readlines())
+            files = [x[:-1] for x in open(MANIFEST_in).readlines()]
             raw_files.extend(files)
-            src_files.extend(map(lambda x, s=ssubdir: os.path.join(s, x), files))
+            src_files.extend([os.path.join(subdir, x) for x in files])
             for f in files:
                 r = os.path.join(sp['rpm_dir'], f)
                 rpm_files.append(r)
@@ -778,7 +777,7 @@ for p in [ scons ]:
             for f in sp.get('extra_rpm_files', []):
                 r = os.path.join(sp['rpm_dir'], f)
                 rpm_files.append(r)
-            files = map(lambda x, i=isubdir: os.path.join(i, x), files)
+            files = [os.path.join(isubdir, x) for x in files]
             dst_files.extend(files)
             for k, f in sp['filemap'].items():
                 if f:
@@ -832,8 +831,8 @@ for p in [ scons ]:
     #
     # Now go through and arrange to create whatever packages we can.
     #
-    build_src_files = map(lambda x, b=build: os.path.join(b, x), src_files)
-    apply(Local, build_src_files, {})
+    build_src_files = [os.path.join(build, x) for x in src_files]
+    Local(*build_src_files)
 
     distutils_formats = []
 
@@ -870,9 +869,8 @@ for p in [ scons ]:
         # but that gives heartburn to Cygwin's tar, so work around it
         # with separate zcat-tar-rm commands.
         #
-        unpack_tar_gz_files = map(lambda x, u=unpack_tar_gz_dir, pv=pkg_version:
-                                         os.path.join(u, pv, x),
-                                  src_files)
+        unpack_tar_gz_files = [os.path.join(unpack_tar_gz_dir, pkg_version, x)
+                               for x in src_files]
         env.Command(unpack_tar_gz_files, dist_tar_gz, [
                     Delete(os.path.join(unpack_tar_gz_dir, pkg_version)),
                     "$ZCAT $SOURCES > .temp",
@@ -893,7 +891,7 @@ for p in [ scons ]:
         # like this because we put a preamble in it that will chdir()
         # to the directory in which setup.py exists.
         #
-        dfiles = map(lambda x, d=test_tar_gz_dir: os.path.join(d, x), dst_files)
+        dfiles = [os.path.join(test_tar_gz_dir, x) for x in dst_files]
         env.Command(dfiles, unpack_tar_gz_files, [
             Delete(os.path.join(unpack_tar_gz_dir, pkg_version, 'build')),
             Delete("$TEST_TAR_GZ_DIR"),
@@ -910,21 +908,9 @@ for p in [ scons ]:
         env.Command(ebuild, os.path.join('gentoo', 'scons.ebuild.in'), SCons_revision)
         def Digestify(target, source, env):
             import md5
-            def hexdigest(s):
-                """Return a signature as a string of hex characters.
-                """
-                # NOTE:  This routine is a method in the Python 2.0 interface
-                # of the native md5 module, but we want SCons to operate all
-                # the way back to at least Python 1.5.2, which doesn't have it.
-                h = string.hexdigits
-                r = ''
-                for c in s:
-                    i = ord(c)
-                    r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
-                return r
             src = source[0].rfile()
             contents = open(str(src)).read()
-            sig = hexdigest(md5.new(contents).digest())
+            sig = md5.new(contents).hexdigest()
             bytes = os.stat(str(src))[6]
             open(str(target[0]), 'w').write("MD5 %s %s %d\n" % (sig,
                                                                 src.name,
@@ -951,9 +937,8 @@ for p in [ scons ]:
         # Unpack the zip archive created by the distutils into
         # build/unpack-zip/scons-{version}.
         #
-        unpack_zip_files = map(lambda x, u=unpack_zip_dir, pv=pkg_version:
-                                      os.path.join(u, pv, x),
-                               src_files)
+        unpack_zip_files = [os.path.join(unpack_zip_dir, pkg_version, x)
+                                         for x in src_files]
 
         env.Command(unpack_zip_files, dist_zip, [
             Delete(os.path.join(unpack_zip_dir, pkg_version)),
@@ -973,7 +958,7 @@ for p in [ scons ]:
         # like this because we put a preamble in it that will chdir()
         # to the directory in which setup.py exists.
         #
-        dfiles = map(lambda x, d=test_zip_dir: os.path.join(d, x), dst_files)
+        dfiles = [os.path.join(test_zip_dir, x) for x in dst_files]
         env.Command(dfiles, unpack_zip_files, [
             Delete(os.path.join(unpack_zip_dir, pkg_version, 'build')),
             Delete("$TEST_ZIP_DIR"),
@@ -1010,12 +995,12 @@ for p in [ scons ]:
             maintain multiple lists.
             """
             c = open(str(source[0]), 'rb').read()
-            c = string.replace(c, '__VERSION' + '__', env['VERSION'])
-            c = string.replace(c, '__RPM_FILES' + '__', env['RPM_FILES'])
+            c = c.replace('__VERSION' + '__', env['VERSION'])
+            c = c.replace('__RPM_FILES' + '__', env['RPM_FILES'])
             open(str(target[0]), 'wb').write(c)
 
         rpm_files.sort()
-        rpm_files_str = string.join(rpm_files, "\n") + "\n"
+        rpm_files_str = "\n".join(rpm_files) + "\n"
         rpm_spec_env = env.Clone(RPM_FILES = rpm_files_str)
         rpm_spec_action = Action(spec_function, varlist=['RPM_FILES'])
         rpm_spec_env.Command(specfile, specfile_in, rpm_spec_action)
@@ -1036,8 +1021,7 @@ for p in [ scons ]:
         AddPostAction(dist_noarch_rpm, Chmod(dist_noarch_rpm, 0644))
         AddPostAction(dist_src_rpm, Chmod(dist_src_rpm, 0644))
 
-        dfiles = map(lambda x, d=test_rpm_dir: os.path.join(d, 'usr', x),
-                     dst_files)
+        dfiles = [os.path.join(test_rpm_dir, 'usr', x) for x in dst_files]
         env.Command(dfiles,
                     dist_noarch_rpm,
                     "$RPM2CPIO $SOURCES | (cd $TEST_RPM_DIR && cpio -id)")
@@ -1060,8 +1044,7 @@ for p in [ scons ]:
             if s[:len(old)] == old:
                 s = new + s[len(old):]
             return os.path.join('usr', s)
-        dfiles = map(lambda x, t=test_deb_dir: os.path.join(t, x),
-                     map(xxx, dst_files))
+        dfiles = [os.path.join(test_deb_dir, xxx(x)) for x in dst_files]
         env.Command(dfiles,
                     deb,
                     "dpkg --fsys-tarfile $SOURCES | (cd $TEST_DEB_DIR && tar -xf -)")
@@ -1084,7 +1067,7 @@ for p in [ scons ]:
             commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_dumb -f %s" % format)
 
         commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY sdist --formats=%s" %  \
-                            string.join(distutils_formats, ','))
+                            ','.join(distutils_formats))
 
     commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst")
 
@@ -1117,11 +1100,11 @@ for p in [ scons ]:
         local_script = os.path.join(build_dir_local, script)
         commands.append(Move(local_script + '.py', local_script))
 
-    rf = filter(lambda x: not x in scripts, raw_files)
-    rf = map(lambda x, slv=s_l_v: os.path.join(slv, x), rf)
+    rf = [x for x in raw_files if not x in scripts]
+    rf = [os.path.join(s_l_v, x) for x in rf]
     for script in scripts:
         rf.append("%s.py" % script)
-    local_targets = map(lambda x, s=build_dir_local: os.path.join(s, x), rf)
+    local_targets = [os.path.join(build_dir_local, x) for x in rf]
 
     env.Command(local_targets, build_src_files, commands)
 
@@ -1140,9 +1123,7 @@ for p in [ scons ]:
                     local_targets,
                     "cd %s && tar czf $( ${TARGET.abspath} $) *" % build_dir_local)
 
-        unpack_targets = map(lambda x, d=test_local_tar_gz_dir:
-                                    os.path.join(d, x),
-                             rf)
+        unpack_targets = [os.path.join(test_local_tar_gz_dir, x) for x in rf]
         commands = [Delete(test_local_tar_gz_dir),
                     Mkdir(test_local_tar_gz_dir),
                     "cd %s && tar xzf $( ${SOURCE.abspath} $)" % test_local_tar_gz_dir]
@@ -1153,9 +1134,7 @@ for p in [ scons ]:
         env.Command(dist_local_zip, local_targets, zipit,
                     CD = build_dir_local, PSV = '.')
 
-        unpack_targets = map(lambda x, d=test_local_zip_dir:
-                                    os.path.join(d, x),
-                             rf)
+        unpack_targets = [os.path.join(test_local_zip_dir, x) for x in rf]
         commands = [Delete(test_local_zip_dir),
                     Mkdir(test_local_zip_dir),
                     unzipit]
@@ -1208,12 +1187,12 @@ SConscript('doc/SConscript')
 
 sfiles = None
 if hg_status_lines:
-    slines = filter(lambda l: l[0] in 'ACM', hg_status_lines)
-    sfiles = map(lambda l: l.split()[-1], slines)
+    slines = [l for l in hg_status_lines if l[0] in 'ACM']
+    sfiles = [l.split()[-1] for l in slines]
 elif svn_status_lines:
-    slines = filter(lambda l: l[0] in ' MA', svn_status_lines)
-    sentries = map(lambda l: l.split()[-1], slines)
-    sfiles = filter(os.path.isfile, sentries)
+    slines = [l for l in svn_status_lines if l[0] in ' MA']
+    sentries = [l.split()[-1] for l in slines]
+    sfiles = list(filter(os.path.isfile, sentries))
 else:
    "Not building in a Mercurial or Subversion tree; skipping building src package."
 
@@ -1228,7 +1207,7 @@ if sfiles:
     ]
 
     for p in remove_patterns:
-        sfiles = filter(lambda s, p=p: not fnmatch.fnmatch(s, p), sfiles)
+        sfiles = [s for s in sfiles if not fnmatch.fnmatch(s, p)]
 
     if sfiles:
         ps = "%s-src" % project
@@ -1245,7 +1224,7 @@ if sfiles:
         for file in sfiles:
             env.SCons_revision(os.path.join(b_ps, file), file)
 
-        b_ps_files = map(lambda x, d=b_ps: os.path.join(d, x), sfiles)
+        b_ps_files = [os.path.join(b_ps, x) for x in sfiles]
         cmds = [
             Delete(b_psv),
             Copy(b_psv, b_ps),
@@ -1254,7 +1233,7 @@ if sfiles:
 
         env.Command(b_psv_stamp, src_deps + b_ps_files, cmds)
 
-        apply(Local, b_ps_files, {})
+        Local(*b_ps_files)
 
         if gzip:
 
@@ -1264,9 +1243,8 @@ if sfiles:
             #
             # Unpack the archive into build/unpack/scons-{version}.
             #
-            unpack_tar_gz_files = map(lambda x, u=unpack_tar_gz_dir, psv=psv:
-                                             os.path.join(u, psv, x),
-                                      sfiles)
+            unpack_tar_gz_files = [os.path.join(unpack_tar_gz_dir, psv, x)
+                                   for x in sfiles]
 
             #
             # We'd like to replace the last three lines with the following:
@@ -1295,8 +1273,7 @@ if sfiles:
             # like this because we put a preamble in it that will chdir()
             # to the directory in which setup.py exists.
             #
-            dfiles = map(lambda x, d=test_src_tar_gz_dir: os.path.join(d, x),
-                            dst_files)
+            dfiles = [os.path.join(test_src_tar_gz_dir, x) for x in dst_files]
             scons_lib_dir = os.path.join(unpack_tar_gz_dir, psv, 'src', 'engine')
             ENV = env.Dictionary('ENV').copy()
             ENV['SCONS_LIB_DIR'] = scons_lib_dir
@@ -1329,9 +1306,8 @@ if sfiles:
             #
             # Unpack the archive into build/unpack/scons-{version}.
             #
-            unpack_zip_files = map(lambda x, u=unpack_zip_dir, psv=psv:
-                                             os.path.join(u, psv, x),
-                                      sfiles)
+            unpack_zip_files = [os.path.join(unpack_zip_dir, psv, x)
+                                for x in sfiles]
 
             env.Command(unpack_zip_files, src_zip, [
                 Delete(os.path.join(unpack_zip_dir, psv)),
@@ -1351,8 +1327,7 @@ if sfiles:
             # like this because we put a preamble in it that will chdir()
             # to the directory in which setup.py exists.
             #
-            dfiles = map(lambda x, d=test_src_zip_dir: os.path.join(d, x),
-                            dst_files)
+            dfiles = [os.path.join(test_src_zip_dir, x) for x in dst_files]
             scons_lib_dir = os.path.join(unpack_zip_dir, psv, 'src', 'engine')
             ENV = env.Dictionary('ENV').copy()
             ENV['SCONS_LIB_DIR'] = scons_lib_dir
diff --git a/bench/bench.py b/bench/bench.py
index ef605350..e076e43a 100644
--- a/bench/bench.py
+++ b/bench/bench.py
@@ -23,6 +23,7 @@
 #
 # This will allow (as much as possible) us to time just the code itself,
 # not Python function call overhead.
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import getopt
 import sys
@@ -93,10 +94,10 @@ exec(open(args[0], 'rU').read())
 try:
     FunctionList
 except NameError:
-    function_names = filter(lambda x: x[:4] == FunctionPrefix, locals().keys())
+    function_names = [x for x in locals().keys() if x[:4] == FunctionPrefix]
     function_names.sort()
-    l = map(lambda f, l=locals(): l[f], function_names)
-    FunctionList = filter(lambda f: type(f) == types.FunctionType, l)
+    l = [locals()[f] for f in function_names]
+    FunctionList = [f for f in l if type(f) == types.FunctionType]
 
 IterationList = [None] * Iterations
 
@@ -104,7 +105,7 @@ def timer(func, *args, **kw):
     results = []
     for i in range(Runs):
         start = Now()
-        apply(func, args, kw)
+        func(*args, **kw)
         finish = Now()
         results.append((finish - start) / Iterations)
     return results
@@ -119,7 +120,7 @@ for func in FunctionList:
     print func.__name__ + d + ':'
 
     for label, args, kw in Data:
-        r = apply(timer, (func,)+args, kw)
+        r = timer(func, *args, **kw)
         display(label, r)
 
 # Local Variables:
diff --git a/bench/env.__setitem__.py b/bench/env.__setitem__.py
index d20785ae..61d8c1eb 100644
--- a/bench/env.__setitem__.py
+++ b/bench/env.__setitem__.py
@@ -6,7 +6,6 @@
 
 import os.path
 import re
-import string
 import sys
 import timeit
 
@@ -174,7 +173,7 @@ class env_global_regex_is_valid(Environment):
 class env_special_set_has_key(Environment):
     """_special_set.get():  use _special_set.has_key() instead"""
     def __setitem__(self, key, value):
-        if self._special_set.has_key(key):
+        if key in self._special_set:
             self._special_set[key](self, key, value)
         else:
             if not SCons.Environment.is_valid_construction_var(key):
@@ -232,7 +231,7 @@ class env_not_has_key(Environment):
         if special:
             special(self, key, value)
         else:
-            if not self._dict.has_key(key) \
+            if key not in self._dict \
                 and not SCons.Environment.is_valid_construction_var(key):
                     raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
             self._dict[key] = value
@@ -243,7 +242,7 @@ class env_Best_attribute(Environment):
         if key in self._special_set_keys:
             self._special_set[key](self, key, value)
         else:
-            if not self._dict.has_key(key) \
+            if key not in self._dict \
                and not global_valid_var.match(key):
                     raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
             self._dict[key] = value
@@ -251,10 +250,10 @@ class env_Best_attribute(Environment):
 class env_Best_has_key(Environment):
     """Best __setitem__(), with has_key"""
     def __setitem__(self, key, value):
-        if self._special_set.has_key(key):
+        if key in self._special_set:
             self._special_set[key](self, key, value)
         else:
-            if not self._dict.has_key(key) \
+            if key not in self._dict \
                and not global_valid_var.match(key):
                     raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
             self._dict[key] = value
@@ -265,7 +264,7 @@ class env_Best_list(Environment):
         if key in ['BUILDERS', 'SCANNERS', 'TARGET', 'TARGETS', 'SOURCE', 'SOURCES']:
             self._special_set[key](self, key, value)
         else:
-            if not self._dict.has_key(key) \
+            if key not in self._dict \
                and not global_valid_var.match(key):
                     raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
             self._dict[key] = value
@@ -278,7 +277,7 @@ else:
     class env_isalnum(Environment):
         """Greg's Folly: isalnum instead of probe"""
         def __setitem__(self, key, value):
-            if self._special_set.has_key(key):
+            if key in self._special_set:
                 self._special_set[key](self, key, value)
             else:
                 if not key.isalnum() and not global_valid_var.match(key):
@@ -324,7 +323,7 @@ common_import_variables = ['do_it'] + class_names
 
 common_imports = """
 from __main__ import %s
-""" % string.join(common_import_variables, ', ')
+""" % ', '.join(common_import_variables)
 
 # The test data (lists of variable names) that we'll use for the runs.
 
@@ -340,10 +339,10 @@ def run_it(title, init):
       s['num'] = iterations
       s['title'] = title
       s['init'] = init
-      apply(times,(),s)
+      times(**s)
 
 print 'Environment __setitem__ benchmark using',
-print 'Python', string.split(sys.version)[0],
+print 'Python', sys.version.split()[0],
 print 'on', sys.platform, os.name
 
 run_it('Results for re-adding an existing variable name 100 times:',
diff --git a/bench/is_types.py b/bench/is_types.py
index d2254657..f9f76770 100644
--- a/bench/is_types.py
+++ b/bench/is_types.py
@@ -29,11 +29,11 @@ except ImportError:
         def __complex__(self): return complex(self.data)
         def __hash__(self): return hash(self.data)
 
-        def __cmp__(self, string):
-            if isinstance(string, UserString):
-                return cmp(self.data, string.data)
+        def __cmp__(self, s):
+            if isinstance(s, UserString):
+                return cmp(self.data, s.data)
             else:
-                return cmp(self.data, string)
+                return cmp(self.data, s)
         def __contains__(self, char):
             return char in self.data
 
diff --git a/bench/lvars-gvars.py b/bench/lvars-gvars.py
index 724b7a2e..bdb09ef8 100644
--- a/bench/lvars-gvars.py
+++ b/bench/lvars-gvars.py
@@ -19,7 +19,7 @@ def Func1(var, gvars, lvars):
 def Func2(var, gvars, lvars):
     """lvars has_key(), gvars try:-except:"""
     for i in IterationList:
-        if lvars.has_key(var):
+        if var in lvars:
             x = lvars[var]
         else:
             try:
@@ -30,9 +30,9 @@ def Func2(var, gvars, lvars):
 def Func3(var, gvars, lvars):
     """lvars has_key(), gvars has_key()"""
     for i in IterationList:
-        if lvars.has_key(var):
+        if var in lvars:
             x = lvars[var]
-        elif gvars.has_key(var):
+        elif var in gvars:
             x = gvars[var]
         else:
             x = ''
diff --git a/bench/timeit.py b/bench/timeit.py
index cc087e1b..ca7e4706 100644
--- a/bench/timeit.py
+++ b/bench/timeit.py
@@ -70,8 +70,6 @@ except ImportError:
     # Must be an older Python version (see timeit() below)
     itertools = None
 
-import string
-
 __all__ = ["Timer"]
 
 dummy_src_name = "<timeit-src>"
@@ -100,7 +98,7 @@ def inner(_it, _timer):
 
 def reindent(src, indent):
     """Helper to reindent a multi-line statement."""
-    return string.replace(src, "\n", "\n" + " "*indent)
+    return src.replace("\n", "\n" + " "*indent)
 
 class Timer:
     """Class for timing execution speed of small code snippets.
@@ -226,7 +224,7 @@ def main(args=None):
         print "use -h/--help for command line help"
         return 2
     timer = default_timer
-    stmt = string.join(args, "\n") or "pass"
+    stmt = "\n".join(args) or "pass"
     number = 0 # auto-determine
     setup = []
     repeat = default_repeat
@@ -252,7 +250,7 @@ def main(args=None):
         if o in ("-h", "--help"):
             print __doc__,
             return 0
-    setup = string.join(setup, "\n") or "pass"
+    setup = "\n".join(setup) or "pass"
     # Include the current directory, so that local imports work (sys.path
     # contains the directory of this script, rather than the current
     # directory)
@@ -279,7 +277,7 @@ def main(args=None):
         return 1
     best = min(r)
     if verbose:
-        print "raw times:", string.join(map(lambda x, p=precision: "%.*g" % (p, x), r))
+        print "raw times:", ' '.join(["%.*g" % (precision, x) for x in r])
     print "%d loops," % number,
     usec = best * 1e6 / number
     if usec < 1000:
diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py
index 3f64a258..d164d11e 100644
--- a/bin/SConsDoc.py
+++ b/bin/SConsDoc.py
@@ -2,6 +2,7 @@
 #
 # Module for handling SCons documentation processing.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __doc__ = """
 This module parses home-brew XML files that document various things
@@ -218,8 +219,8 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
         self._start_dispatch = {}
         self._end_dispatch = {}
         keys = self.__class__.__dict__.keys()
-        start_tag_method_names = filter(lambda k: k[:6] == 'start_', keys)
-        end_tag_method_names = filter(lambda k: k[:4] == 'end_', keys)
+        start_tag_method_names = [k for k in keys if k[:6] == 'start_']
+        end_tag_method_names = [k for k in keys if k[:4] == 'end_']
         for method_name in start_tag_method_names:
             tag = method_name[6:]
             self._start_dispatch[tag] = getattr(self, method_name)
diff --git a/bin/import-test.py b/bin/import-test.py
index 839d2ad3..fe5ea2fd 100644
--- a/bin/import-test.py
+++ b/bin/import-test.py
@@ -78,7 +78,7 @@ def print_files(dir):
         if not d:
             l = dir.path + [n]
             sys.stdout.write('\ntest.write(%s, """\\\n' % l)
-            p = os.path.join(*([directory] + l))
+            p = os.path.join(directory, *l)
             sys.stdout.write(open(p, 'r').read())
             sys.stdout.write('""")\n')
     dir.call_for_each_entry(print_a_file)
diff --git a/bin/linecount.py b/bin/linecount.py
index 33f9f737..715d2072 100644
--- a/bin/linecount.py
+++ b/bin/linecount.py
@@ -22,11 +22,11 @@
 # non-comment lines.  The last figure (non-comment) lines is the most
 # interesting one for most purposes.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 fmt = "%-16s  %5s  %7s  %9s  %11s  %11s"
 
@@ -85,8 +85,8 @@ sources = Collection('sources', pred=is_source)
 def t(arg, dirname, names):
     try: names.remove('.svn')
     except ValueError: pass
-    names = filter(arg, names)
-    arg.extend(map(lambda n, d=dirname: os.path.join(d, n), names))
+    names = list(filter(arg, names))
+    arg.extend([os.path.join(dirname, n) for n in names])
 
 os.path.walk('src', t, src_Tests_py_tests)
 os.path.walk('src', t, src_test_tests)
diff --git a/bin/memoicmp.py b/bin/memoicmp.py
index f45ecb09..812af665 100644
--- a/bin/memoicmp.py
+++ b/bin/memoicmp.py
@@ -1,21 +1,24 @@
 #!/usr/bin/env python
 #
-# A script to compare the --debug=memoizer output found int
+# A script to compare the --debug=memoizer output found in
 # two different files.
 
-import sys,string
+import sys
 
 def memoize_output(fname):
-        mout = {}
-        lines=filter(lambda words:
-                     len(words) == 5 and
-                     words[1] == 'hits' and words[3] == 'misses',
-                     map(string.split, open(fname,'r').readlines()))
-        for line in lines:
-                mout[line[-1]] = ( int(line[0]), int(line[2]) )
-        return mout
+    mout = {}
+    #lines=filter(lambda words:
+    #             len(words) == 5 and
+    #             words[1] == 'hits' and words[3] == 'misses',
+    #             map(string.split, open(fname,'r').readlines()))
+    #for line in lines:
+    #    mout[line[-1]] = ( int(line[0]), int(line[2]) )
+    for line in open(fname,'r').readlines():
+        words = line.split()
+        if len(words) == 5 and words[1] == 'hits' and words[3] == 'misses':
+            mout[words[-1]] = ( int(words[0]), int(words[2]) )
+    return mout
 
-        
 def memoize_cmp(filea, fileb):
         ma = memoize_output(filea)
         mb = memoize_output(fileb)
diff --git a/bin/objcounts.py b/bin/objcounts.py
index ca814b44..c1f2dd56 100644
--- a/bin/objcounts.py
+++ b/bin/objcounts.py
@@ -40,7 +40,7 @@ def fetch_counts(fname):
     list = [l.split() for l in lines if re.match('\s+\d', l)]
     d = {}
     for l in list:
-        d[l[-1]] = map(int, l[:-1])
+        d[l[-1]] = list(map(int, l[:-1]))
     return d
 
 c1 = fetch_counts(sys.argv[1])
diff --git a/bin/scons-diff.py b/bin/scons-diff.py
index 7c603083..d1e48cf5 100644
--- a/bin/scons-diff.py
+++ b/bin/scons-diff.py
@@ -97,15 +97,15 @@ def simple_diff(a, b, fromfile='', tofile='',
     for op, a1, a2, b1, b2 in sm.get_opcodes():
         if op == 'delete':
             result.append("%sd%d\n" % (comma(a1, a2), b1))
-            result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+            result.extend(['< ' + l for l in a[a1:a2]])
         elif op == 'insert':
             result.append("%da%s\n" % (a1, comma(b1, b2)))
-            result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+            result.extend(['> ' + l for l in b[b1:b2]])
         elif op == 'replace':
             result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2)))
-            result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+            result.extend(['< ' + l for l in a[a1:a2]])
             result.append('---\n')
-            result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+            result.extend(['> ' + l for l in b[b1:b2]])
     return result
 
 diff_map = {
diff --git a/bin/scons-doc.py b/bin/scons-doc.py
index e385b081..f140743e 100644
--- a/bin/scons-doc.py
+++ b/bin/scons-doc.py
@@ -88,12 +88,12 @@
 # Error output gets passed through to your error output so you
 # can see if there are any problems executing the command.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import optparse
 import os
 import re
 import sgmllib
-import string
 import sys
 import time
 
@@ -185,7 +185,6 @@ Prompt = {
 Stdin = """\
 import os
 import re
-import string
 import SCons.Action
 import SCons.Defaults
 import SCons.Node.FS
@@ -231,7 +230,7 @@ class Curry:
         else:
             kw = kwargs or self.kwargs
 
-        return apply(self.fun, self.pending + args, kw)
+        return self.fun(*self.pending + args, **kw)
 
 def Str(target, source, env, cmd=""):
     result = []
@@ -304,7 +303,7 @@ def JavaCCom(target, source, env):
     #   public class FooBar
     # lines in the source file(s) and spits those out
     # to .class files named after the class.
-    tlist = map(str, target)
+    tlist = list(map(str, target))
     not_copied = {}
     for t in tlist:
        not_copied[t] = 1
@@ -312,7 +311,7 @@ def JavaCCom(target, source, env):
         contents = open(src, "rb").read()
         classes = public_class_re.findall(contents)
         for c in classes:
-            for t in filter(lambda x: string.find(x, c) != -1, tlist):
+            for t in [x for x in tlist if x.find(c) != -1]:
                 open(t, "wb").write(contents)
                 del not_copied[t]
     for t in not_copied.keys():
@@ -326,7 +325,7 @@ def JavaHCom(target, source, env):
 
 def find_class_files(arg, dirname, names):
     class_files = filter(lambda n: n[-6:] == '.class', names)
-    paths = map(lambda n, d=dirname: os.path.join(d, n), class_files)
+    paths = map(lambda n: os.path.join(dirname, n), class_files)
     arg.extend(paths)
 
 def JarCom(target, source, env):
@@ -382,9 +381,9 @@ ToolList = {
 toollist = ToolList[platform]
 filter_tools = string.split('%(tools)s')
 if filter_tools:
-    toollist = filter(lambda x, ft=filter_tools: x[0] in ft, toollist)
+    toollist = [x for x in toollist if x[0] in filter_tools]
 
-toollist = map(lambda t: apply(ToolSurrogate, t), toollist)
+toollist = [ToolSurrogate(*t) for t in toollist]
 
 toollist.append('install')
 
@@ -413,8 +412,8 @@ def command_scons(args, c, test, dict):
     except AttributeError:
         pass
     else:
-        for arg in string.split(c.environment):
-            key, val = string.split(arg, '=')
+        for arg in c.environment.split():
+            key, val = arg.split('=')
             try:
                 save_vals[key] = os.environ[key]
             except KeyError:
@@ -427,17 +426,17 @@ def command_scons(args, c, test, dict):
              # warnings that come from the new revamped VS support so
              # we can build doc on (Linux) systems that don't have
              # Visual C installed.
-             arguments = '--warn=no-visual-c-missing -f - ' + string.join(args),
+             arguments = '--warn=no-visual-c-missing -f - ' + ' '.join(args),
              chdir = test.workpath('WORK'),
              stdin = Stdin % dict)
     os.environ.update(save_vals)
     for key in delete_keys:
         del(os.environ[key])
     out = test.stdout()
-    out = string.replace(out, test.workpath('ROOT'), '')
-    out = string.replace(out, test.workpath('WORK/SConstruct'),
+    out = out.replace(test.workpath('ROOT'), '')
+    out = out.replace(test.workpath('WORK/SConstruct'),
                               '/home/my/project/SConstruct')
-    lines = string.split(out, '\n')
+    lines = out.split('\n')
     if lines:
         while lines[-1] == '':
             lines = lines[:-1]
@@ -479,9 +478,9 @@ def command_edit(args, c, test, dict):
 def command_ls(args, c, test, dict):
     def ls(a):
         files = os.listdir(a)
-        files = filter(lambda x: x[0] != '.', files)
+        files = [x for x in files if x[0] != '.']
         files.sort()
-        return [string.join(files, '  ')]
+        return ['  '.join(files)]
     if args:
         l = []
         for a in args:
@@ -569,7 +568,7 @@ class MySGML(sgmllib.SGMLParser):
     # handle the begin-end tags of our SCons examples.
 
     def start_scons_example(self, attrs):
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if t:
             name = t[0][1]
             try:
@@ -585,7 +584,7 @@ class MySGML(sgmllib.SGMLParser):
 
     def end_scons_example(self):
         e = self.e
-        files = filter(lambda f: f.printme, e.files)
+        files = [f for f in e.files if f.printme]
         if files:
             self.outfp.write('<programlisting>')
             for f in files:
@@ -593,9 +592,9 @@ class MySGML(sgmllib.SGMLParser):
                     i = len(f.data) - 1
                     while f.data[i] == ' ':
                         i = i - 1
-                    output = string.replace(f.data[:i+1], '__ROOT__', '')
-                    output = string.replace(output, '<', '&lt;')
-                    output = string.replace(output, '>', '&gt;')
+                    output = f.data[:i+1].replace('__ROOT__', '')
+                    output = output.replace('<', '&lt;')
+                    output = output.replace('>', '&gt;')
                     self.outfp.write(output)
             if e.data and e.data[0] == '\n':
                 e.data = e.data[1:]
@@ -608,7 +607,7 @@ class MySGML(sgmllib.SGMLParser):
             e = self.e
         except AttributeError:
             self.error("<file> tag outside of <scons_example>")
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if not t:
             self.error("no <file> name attribute found")
         try:
@@ -632,7 +631,7 @@ class MySGML(sgmllib.SGMLParser):
             e = self.e
         except AttributeError:
             self.error("<directory> tag outside of <scons_example>")
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if not t:
             self.error("no <directory> name attribute found")
         try:
@@ -651,7 +650,7 @@ class MySGML(sgmllib.SGMLParser):
         self.afunclist = self.afunclist[:-1]
 
     def start_scons_example_file(self, attrs):
-        t = filter(lambda t: t[0] == 'example', attrs)
+        t = [t for t in attrs if t[0] == 'example']
         if not t:
             self.error("no <scons_example_file> example attribute found")
         exname = t[0][1]
@@ -659,11 +658,11 @@ class MySGML(sgmllib.SGMLParser):
             e = self.examples[exname]
         except KeyError:
             self.error("unknown example name '%s'" % exname)
-        fattrs = filter(lambda t: t[0] == 'name', attrs)
+        fattrs = [t for t in attrs if t[0] == 'name']
         if not fattrs:
             self.error("no <scons_example_file> name attribute found")
         fname = fattrs[0][1]
-        f = filter(lambda f, fname=fname: f.name == fname, e.files)
+        f = [f for f in e.files if f.name == fname]
         if not f:
             self.error("example '%s' does not have a file named '%s'" % (exname, fname))
         self.f = f[0]
@@ -675,7 +674,7 @@ class MySGML(sgmllib.SGMLParser):
         delattr(self, 'f')
 
     def start_scons_output(self, attrs):
-        t = filter(lambda t: t[0] == 'example', attrs)
+        t = [t for t in attrs if t[0] == 'example']
         if not t:
             self.error("no <scons_output> example attribute found")
         exname = t[0][1]
@@ -704,7 +703,7 @@ class MySGML(sgmllib.SGMLParser):
         if o.preserve:
             t.preserve()
         t.subdir('ROOT', 'WORK')
-        t.rootpath = string.replace(t.workpath('ROOT'), '\\', '\\\\')
+        t.rootpath = t.workpath('ROOT').replace('\\', '\\\\')
 
         for d in e.dirs:
             dir = t.workpath('WORK', d.name)
@@ -715,19 +714,19 @@ class MySGML(sgmllib.SGMLParser):
             i = 0
             while f.data[i] == '\n':
                 i = i + 1
-            lines = string.split(f.data[i:], '\n')
+            lines = f.data[i:].split('\n')
             i = 0
             while lines[0][i] == ' ':
                 i = i + 1
-            lines = map(lambda l, i=i: l[i:], lines)
-            path = string.replace(f.name, '__ROOT__', t.rootpath)
+            lines = [l[i:] for l in lines]
+            path = f.name.replace('__ROOT__', t.rootpath)
             if not os.path.isabs(path):
                 path = t.workpath('WORK', path)
             dir, name = os.path.split(path)
             if dir and not os.path.exists(dir):
                 os.makedirs(dir)
-            content = string.join(lines, '\n')
-            content = string.replace(content, '__ROOT__', t.rootpath)
+            content = '\n'.join(lines)
+            content = content.replace('__ROOT__', t.rootpath)
             path = t.workpath('WORK', path)
             t.write(path, content)
             if hasattr(f, 'chmod'):
@@ -761,24 +760,24 @@ class MySGML(sgmllib.SGMLParser):
 
         for c in o.commandlist:
             self.outfp.write(p + Prompt[o.os])
-            d = string.replace(c.data, '__ROOT__', '')
+            d = c.data.replace('__ROOT__', '')
             self.outfp.write('<userinput>' + d + '</userinput>\n')
 
-            e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
-            args = string.split(e)
+            e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+            args = e.split()
             lines = ExecuteCommand(args, c, t, {'osname':o.os, 'tools':o.tools})
             content = None
             if c.output:
                 content = c.output
             elif lines:
-                content = string.join(lines, '\n' + p)
+                content = ( '\n' + p).join(lines)
             if content:
                 content = address_re.sub(r' at 0x700000&gt;', content)
                 content = engine_re.sub(r' File "bootstrap/src/engine/SCons/', content)
                 content = file_re.sub(r'\1 <module>', content)
                 content = nodelist_re.sub(r"\1 'NodeList' object \2", content)
-                content = string.replace(content, '<', '&lt;')
-                content = string.replace(content, '>', '&gt;')
+                content = content.replace('<', '&lt;')
+                content = content.replace('>', '&gt;')
                 self.outfp.write(p + content + '\n')
 
         if o.data[0] == '\n':
@@ -815,7 +814,7 @@ class MySGML(sgmllib.SGMLParser):
     def end_sconstruct(self):
         f = self.f
         self.outfp.write('<programlisting>')
-        output = string.replace(f.data, '__ROOT__', '')
+        output = f.data.replace('__ROOT__', '')
         self.outfp.write(output + '</programlisting>')
         delattr(self, 'f')
         self.afunclist = self.afunclist[:-1]
diff --git a/bin/scons-proc.py b/bin/scons-proc.py
index 15f22b76..52d326c0 100644
--- a/bin/scons-proc.py
+++ b/bin/scons-proc.py
@@ -13,7 +13,6 @@
 import getopt
 import os.path
 import re
-import string
 import StringIO
 import sys
 import xml.sax
@@ -140,7 +139,7 @@ class SCons_XML:
 
 class SCons_XML_to_XML(SCons_XML):
     def write(self, files):
-        gen, mod = string.split(files, ',')
+        gen, mod = files.split(',')
         g.write_gen(gen)
         g.write_mod(mod)
     def write_gen(self, filename):
@@ -157,12 +156,12 @@ class SCons_XML_to_XML(SCons_XML):
             for chunk in v.summary.body:
                 f.write(str(chunk))
             if v.sets:
-                s = map(lambda x: '&cv-link-%s;' % x, v.sets)
+                s = ['&cv-link-%s;' % x for x in v.sets]
                 f.write('<para>\n')
                 f.write('Sets:  ' + ', '.join(s) + '.\n')
                 f.write('</para>\n')
             if v.uses:
-                u = map(lambda x: '&cv-link-%s;' % x, v.uses)
+                u = ['&cv-link-%s;' % x for x in v.uses]
                 f.write('<para>\n')
                 f.write('Uses:  ' + ', '.join(u) + '.\n')
                 f.write('</para>\n')
@@ -216,15 +215,15 @@ class SCons_XML_to_man(SCons_XML):
         for v in self.values:
             chunks.extend(v.mansep())
             chunks.extend(v.initial_chunks())
-            chunks.extend(map(str, v.summary.body))
+            chunks.extend(list(map(str, v.summary.body)))
 
         body = ''.join(chunks)
-        body = string.replace(body, '<programlisting>', '.ES')
-        body = string.replace(body, '</programlisting>', '.EE')
-        body = string.replace(body, '\n</para>\n<para>\n', '\n\n')
-        body = string.replace(body, '<para>\n', '')
-        body = string.replace(body, '<para>', '\n')
-        body = string.replace(body, '</para>\n', '')
+        body = body.replace('<programlisting>', '.ES')
+        body = body.replace('</programlisting>', '.EE')
+        body = body.replace('\n</para>\n<para>\n', '\n\n')
+        body = body.replace('<para>\n', '')
+        body = body.replace('<para>', '\n')
+        body = body.replace('</para>\n', '')
 
         body = string.replace(body, '<variablelist>\n', '.RS 10\n')
         # Handling <varlistentry> needs to be rationalized and made
@@ -241,9 +240,9 @@ class SCons_XML_to_man(SCons_XML):
         body = string.replace(body, '\n.IP\n\'\\"', '\n\n\'\\"')
         body = re.sub('&(scons|SConstruct|SConscript|jar|Make|lambda);', r'\\fB\1\\fP', body)
         body = re.sub('&(TARGET|TARGETS|SOURCE|SOURCES);', r'\\fB$\1\\fP', body)
-        body = string.replace(body, '&Dir;', r'\fBDir\fP')
-        body = string.replace(body, '&target;', r'\fItarget\fP')
-        body = string.replace(body, '&source;', r'\fIsource\fP')
+        body = body.replace('&Dir;', r'\fBDir\fP')
+        body = body.replace('&target;', r'\fItarget\fP')
+        body = body.replace('&source;', r'\fIsource\fP')
         body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
         body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
         body = re.sub('&f(-link)?-env-([^;]*);', r'\\fBenv.\2\\fP()', body)
@@ -258,8 +257,8 @@ class SCons_XML_to_man(SCons_XML):
         body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP$', re.M).sub(r'.R\2 \1 \3', body)
         body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP([^\s\\]+)$', re.M).sub(r'.R\2 \1 \3 \4', body)
         body = re.compile(r'^(\.R[BI].*[\S])\s+$;', re.M).sub(r'\1', body)
-        body = string.replace(body, '&lt;', '<')
-        body = string.replace(body, '&gt;', '>')
+        body = body.replace('&lt;', '<')
+        body = body.replace('&gt;', '>')
         body = re.sub(r'\\([^f])', r'\\\\\1', body)
         body = re.compile("^'\\\\\\\\", re.M).sub("'\\\\", body)
         body = re.compile(r'^\.([BI]R?) --', re.M).sub(r'.\1 \-\-', body)
diff --git a/bin/scons-test.py b/bin/scons-test.py
index aa03d72e..8d1950f1 100644
--- a/bin/scons-test.py
+++ b/bin/scons-test.py
@@ -19,7 +19,6 @@ import getopt
 import imp
 import os
 import os.path
-import string
 import sys
 import tempfile
 import time
@@ -90,7 +89,7 @@ def outname(n, outdir=outdir):
         l.append(tail)
     l.append(outdir)
     l.reverse()
-    return apply(os.path.join, l)
+    return os.path.join(*l)
 
 for name in zf.namelist():
     dest = outname(name)
@@ -135,7 +134,7 @@ fp.close()
 if not args:
     runtest_args = '-a'
 else:
-    runtest_args = string.join(args)
+    runtest_args = ' '.join(args)
 
 if format == '--xml':
 
diff --git a/bin/scons-unzip.py b/bin/scons-unzip.py
index 28c73f88..c0eb8aa9 100644
--- a/bin/scons-unzip.py
+++ b/bin/scons-unzip.py
@@ -52,7 +52,7 @@ def outname(n, outdir=outdir):
         l.append(tail)
     l.append(outdir)
     l.reverse()
-    return apply(os.path.join, l)
+    return os.path.join(*l)
 
 for name in zf.namelist():
     dest = outname(name)
diff --git a/bin/sconsexamples.py b/bin/sconsexamples.py
index 0a409bcd..6f20ae96 100644
--- a/bin/sconsexamples.py
+++ b/bin/sconsexamples.py
@@ -67,12 +67,12 @@
 # Error output gets passed through to your error output so you
 # can see if there are any problems executing the command.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import os
 import os.path
 import re
 import sgmllib
-import string
 import sys
 
 sys.path.append(os.path.join(os.getcwd(), 'etc'))
@@ -156,7 +156,6 @@ Prompt = {
 # command output.
 
 Stdin = """\
-import string
 import SCons.Defaults
 
 platform = '%s'
@@ -174,13 +173,13 @@ class Curry:
         else:
             kw = kwargs or self.kwargs
 
-        return apply(self.fun, self.pending + args, kw)
+        return self.fun(*self.pending + args, **kw)
 
 def Str(target, source, env, cmd=""):
     result = []
     for cmd in env.subst_list(cmd, target=target, source=source):
-        result.append(string.join(map(str, cmd)))
-    return string.join(result, '\\n')
+        result.append(" ".join(map(str, cmd)))
+    return '\\n'.join(result)
 
 class ToolSurrogate:
     def __init__(self, tool, variable, func):
@@ -212,7 +211,7 @@ ToolList = {
                  ('mslink', 'LINKCOM', Cat)]
 }
 
-tools = map(lambda t: apply(ToolSurrogate, t), ToolList[platform])
+tools = map(lambda t: ToolSurrogate(*t), ToolList[platform])
 
 SCons.Defaults.ConstructionEnvironment.update({
     'PLATFORM' : platform,
@@ -270,7 +269,7 @@ class MySGML(sgmllib.SGMLParser):
         sys.stdout.write('&#' + ref + ';')
 
     def start_scons_example(self, attrs):
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if t:
             name = t[0][1]
             try:
@@ -286,7 +285,7 @@ class MySGML(sgmllib.SGMLParser):
 
     def end_scons_example(self):
         e = self.e
-        files = filter(lambda f: f.printme, e.files)
+        files = [f for f in e.files if f.printme]
         if files:
             sys.stdout.write('<programlisting>')
             for f in files:
@@ -294,7 +293,7 @@ class MySGML(sgmllib.SGMLParser):
                     i = len(f.data) - 1
                     while f.data[i] == ' ':
                         i = i - 1
-                    output = string.replace(f.data[:i+1], '__ROOT__', '')
+                    output = f.data[:i+1].replace('__ROOT__', '')
                     sys.stdout.write(output)
             if e.data and e.data[0] == '\n':
                 e.data = e.data[1:]
@@ -307,7 +306,7 @@ class MySGML(sgmllib.SGMLParser):
             e = self.e
         except AttributeError:
             self.error("<file> tag outside of <scons_example>")
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if not t:
             self.error("no <file> name attribute found")
         try:
@@ -331,7 +330,7 @@ class MySGML(sgmllib.SGMLParser):
             e = self.e
         except AttributeError:
             self.error("<directory> tag outside of <scons_example>")
-        t = filter(lambda t: t[0] == 'name', attrs)
+        t = [t for t in attrs if t[0] == 'name']
         if not t:
             self.error("no <directory> name attribute found")
         try:
@@ -350,7 +349,7 @@ class MySGML(sgmllib.SGMLParser):
         self.afunclist = self.afunclist[:-1]
 
     def start_scons_example_file(self, attrs):
-        t = filter(lambda t: t[0] == 'example', attrs)
+        t = [t for t in attrs if t[0] == 'example']
         if not t:
             self.error("no <scons_example_file> example attribute found")
         exname = t[0][1]
@@ -358,11 +357,11 @@ class MySGML(sgmllib.SGMLParser):
             e = self.examples[exname]
         except KeyError:
             self.error("unknown example name '%s'" % exname)
-        fattrs = filter(lambda t: t[0] == 'name', attrs)
+        fattrs = [t for t in attrs if t[0] == 'name']
         if not fattrs:
             self.error("no <scons_example_file> name attribute found")
         fname = fattrs[0][1]
-        f = filter(lambda f, fname=fname: f.name == fname, e.files)
+        f = [f for f in e.files if f.name == fname]
         if not f:
             self.error("example '%s' does not have a file named '%s'" % (exname, fname))
         self.f = f[0]
@@ -377,7 +376,7 @@ class MySGML(sgmllib.SGMLParser):
         delattr(self, 'f')
 
     def start_scons_output(self, attrs):
-        t = filter(lambda t: t[0] == 'example', attrs)
+        t = [t for t in attrs if t[0] == 'example']
         if not t:
             self.error("no <scons_output> example attribute found")
         exname = t[0][1]
@@ -408,20 +407,19 @@ class MySGML(sgmllib.SGMLParser):
             i = 0
             while f.data[i] == '\n':
                 i = i + 1
-            lines = string.split(f.data[i:], '\n')
+            lines = f.data[i:].split('\n')
             i = 0
             while lines[0][i] == ' ':
                 i = i + 1
-            lines = map(lambda l, i=i: l[i:], lines)
-            path = string.replace(f.name, '__ROOT__', t.workpath('ROOT'))
+            lines = [l[i:] for l in lines]
+            path = f.name.replace('__ROOT__', t.workpath('ROOT'))
             dir, name = os.path.split(f.name)
             if dir:
                 dir = t.workpath('WORK', dir)
                 if not os.path.exists(dir):
                     os.makedirs(dir)
-            content = string.join(lines, '\n')
-            content = string.replace(content,
-                                     '__ROOT__',
+            content = '\n'.join(lines)
+            content = content.replace('__ROOT__',
                                      t.workpath('ROOT'))
             t.write(t.workpath('WORK', f.name), content)
         i = len(o.prefix)
@@ -431,19 +429,19 @@ class MySGML(sgmllib.SGMLParser):
         p = o.prefix[i:]
         for c in o.commandlist:
             sys.stdout.write(p + Prompt[o.os])
-            d = string.replace(c.data, '__ROOT__', '')
+            d = c.data.replace('__ROOT__', '')
             sys.stdout.write('<userinput>' + d + '</userinput>\n')
-            e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
-            args = string.split(e)[1:]
+            e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+            args = e.split()[1:]
             os.environ['SCONS_LIB_DIR'] = scons_lib_dir
             t.run(interpreter = sys.executable,
                   program = scons_py,
-                  arguments = '-f - ' + string.join(args),
+                  arguments = '-f - ' + ' '.join(args),
                   chdir = t.workpath('WORK'),
                   stdin = Stdin % o.os)
-            out = string.replace(t.stdout(), t.workpath('ROOT'), '')
+            out = t.stdout().replace(t.workpath('ROOT'), '')
             if out:
-                lines = string.split(out, '\n')
+                lines = out.split('\n')
                 if lines:
                     while lines[-1] == '':
                         lines = lines[:-1]
diff --git a/bin/sfsum b/bin/sfsum
index a560b7da..22f43d77 100644
--- a/bin/sfsum
+++ b/bin/sfsum
@@ -25,7 +25,6 @@
 
 import xml.sax
 import xml.sax.saxutils
-import string
 import sys
 
 SFName = {
@@ -51,7 +50,7 @@ Artifacts = {}
 def nws(text):
     """Normalize white space.  This will become important if/when
     we enhance this to search for arbitrary fields."""
-    return string.join(string.split(text), ' ')
+    return ' '.join(text.split())
 
 class ClassifyArtifacts(xml.sax.saxutils.DefaultHandler):
     """
diff --git a/bootstrap.py b/bootstrap.py
index 4dad44d5..37e8e707 100644
--- a/bootstrap.py
+++ b/bootstrap.py
@@ -23,7 +23,6 @@
 
 import os
 import os.path
-import string
 import sys
 
 __doc__ = """bootstrap.py
@@ -171,15 +170,15 @@ def find(file, search=search):
         if os.path.exists(f):
             return os.path.normpath(f)
     sys.stderr.write("could not find `%s' in search path:\n" % file)
-    sys.stderr.write("\t" + string.join(search, "\n\t") + "\n")
+    sys.stderr.write("\t" + "\n\t".join(search) + "\n")
     sys.exit(2)
 
 scons_py = os.path.join('src', 'script', 'scons.py')
 src_engine = os.path.join('src', 'engine')
 MANIFEST_in = find(os.path.join(src_engine, 'MANIFEST.in'))
 
-files = [ scons_py ] + map(lambda x: os.path.join(src_engine, x[:-1]),
-                           open(MANIFEST_in).readlines())
+files = [ scons_py ] + [os.path.join(src_engine, x[:-1])
+                        for x in open(MANIFEST_in).readlines()]
 
 for file in files:
     src = find(file)
@@ -200,7 +199,7 @@ args = [
             os.path.join(bootstrap_dir, scons_py)
        ] + pass_through_args
 
-sys.stdout.write(string.join(args, " ") + '\n')
+sys.stdout.write(" ".join(args) + '\n')
 sys.stdout.flush()
 
 os.environ['SCONS_LIB_DIR'] = os.path.join(bootstrap_dir, src_engine)
diff --git a/doc/SConscript b/doc/SConscript
index b8fc5025..7af3d33c 100644
--- a/doc/SConscript
+++ b/doc/SConscript
@@ -24,10 +24,10 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import os.path
 import re
-import string
 
 Import('build_dir', 'env', 'whereis')
 
@@ -93,7 +93,7 @@ def scanxml(node, env, target):
                 if tail == 'doc':
                     break
                 a = [tail] + a
-            file = apply(os.path.join, a, {})
+            file = os.path.join(*a)
         includes.append(file)
 
     return includes
@@ -119,8 +119,8 @@ def chop(s): return s[:-1]
 #manifest_in = File('#src/engine/MANIFEST.in').rstr()
 
 manifest_xml_in = File('#src/engine/MANIFEST-xml.in').rstr()
-scons_doc_files = map(chop, open(manifest_xml_in).readlines())
-scons_doc_files = map(lambda x: File('#src/engine/'+x).rstr(), scons_doc_files)
+scons_doc_files = list(map(chop, open(manifest_xml_in).readlines()))
+scons_doc_files = [File('#src/engine/'+x).rstr() for x in scons_doc_files]
 
 if not jw:
     print "jw not found, skipping building User Guide."
@@ -240,7 +240,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
     # get included by the document XML files in the subdirectories.
     #
     manifest = File('MANIFEST').rstr()
-    src_files = map(lambda x: x[:-1], open(manifest).readlines())
+    src_files = [x[:-1] for x in open(manifest).readlines()]
     for s in src_files:
         base, ext = os.path.splitext(s)
         if ext in ['.fig', '.jpg']:
@@ -255,8 +255,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
     #
     for doc in docs.keys():
         manifest = File(os.path.join(doc, 'MANIFEST')).rstr()
-        src_files = map(lambda x: x[:-1],
-                        open(manifest).readlines())
+        src_files = [x[:-1] for x in open(manifest).readlines()]
         build_doc = docs[doc].get('scons-doc') and int(ARGUMENTS.get('BUILDDOC', 0))
         for s in src_files:
             doc_s = os.path.join(doc, s)
@@ -408,8 +407,7 @@ for m in man_page_list:
 
 man_i_files = ['builders.man', 'tools.man', 'variables.man']
 
-man_intermediate_files = map(lambda x: os.path.join(build, 'man', x),
-                             man_i_files)
+man_intermediate_files = [os.path.join(build, 'man', x) for x in man_i_files]
 
 cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)"
 man_intermediate_files = env.Command(man_intermediate_files,
@@ -444,12 +442,12 @@ for man_1 in man_page_list:
         def strip_to_first_html_tag(target, source, env):
             t = str(target[0])
             contents = open(t).read()
-            contents = contents[string.find(contents, '<HTML>'):]
+            contents = contents[contents.find('<HTML>'):]
             open(t, 'w').write(contents)
             return 0
 
         cmds = [
-            "( cd %s/man && cp %s .. )" % (build, string.join(man_i_files)),
+            "( cd %s/man && cp %s .. )" % (build, ' '.join(man_i_files)),
             "( cd ${SOURCE.dir} && man2html ${SOURCE.file} ) > $TARGET",
             Action(strip_to_first_html_tag),
         ]
@@ -469,15 +467,15 @@ else:
     # the SConstruct file.
     e = os.path.join('#src', 'engine')
     manifest_in = File(os.path.join(e, 'MANIFEST.in')).rstr()
-    sources = map(lambda x: x[:-1], open(manifest_in).readlines())
-    sources = filter(lambda x: string.find(x, 'Optik') == -1, sources)
-    sources = filter(lambda x: string.find(x, 'Platform') == -1, sources)
-    sources = filter(lambda x: string.find(x, 'Tool') == -1, sources)
+    sources = [x[:-1] for x in open(manifest_in).readlines()]
+    sources = [x for x in sources if x.find('Optik') == -1]
+    sources = [x for x in sources if x.find('Platform') == -1]
+    sources = [x for x in sources if x.find('Tool') == -1]
     # XXX
-    sources = filter(lambda x: string.find(x, 'Options') == -1, sources)
+    sources = [x for x in sources if x.find('Options') == -1]
 
     e = os.path.join(build, '..', 'scons', 'engine')
-    sources = map(lambda x, e=e: os.path.join(e, x), sources)
+    sources = [os.path.join(e, x) for x in sources]
 
     epydoc_commands = [
         Delete('$OUTDIR'),
@@ -519,8 +517,7 @@ else:
 # for easy distribution to the web site.
 #
 if tar_deps:
-    tar_list = string.join(map(lambda x, b=build+'/': string.replace(x, b, ''),
-                           tar_list))
+    tar_list = ' '.join([x.replace(build+'/', '') for x in tar_list])
     t = env.Command(dist_doc_tar_gz, tar_deps,
                 "tar cf${TAR_HFLAG} - -C %s %s | gzip > $TARGET" % (build, tar_list))
     AddPostAction(dist_doc_tar_gz, Chmod(dist_doc_tar_gz, 0644))
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index fa9b16c3..c8017c4a 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -1841,9 +1841,7 @@ and a same-named environment method
 that split a single string
 into a list, separated on
 strings of white-space characters.
-(These are similar to the
-string.split() method
-from the standard Python library,
+(These are similar to the split() member function of Python strings
 but work even if the input isn't a string.)
 
 Like all Python arguments,
@@ -1862,7 +1860,7 @@ env.Program('bar', env.Split('bar.c foo.c'))
 env.Program(source =  ['bar.c', 'foo.c'], target = 'bar')
 env.Program(target = 'bar', Split('bar.c foo.c'))
 env.Program(target = 'bar', env.Split('bar.c foo.c'))
-env.Program('bar', source = string.split('bar.c foo.c'))
+env.Program('bar', source = 'bar.c foo.c'.split())
 .EE
 
 Target and source file names
@@ -5534,7 +5532,7 @@ The following statements are equivalent:
 .ES
 env.SetDefault(FOO = 'foo')
 
-if not env.has_key('FOO'): env['FOO'] = 'foo'
+if 'FOO' not in env: env['FOO'] = 'foo'
 .EE
 
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -9901,7 +9899,7 @@ as follows:
 def pf(env, dir, target, source, arg):
     top_dir = Dir('#').abspath
     results = []
-    if env.has_key('MYPATH'):
+    if 'MYPATH' in env:
         for p in env['MYPATH']:
             results.append(top_dir + os.sep + p)
     return results
diff --git a/doc/user/less-simple.in b/doc/user/less-simple.in
index f7bd7d58..fcffa5e8 100644
--- a/doc/user/less-simple.in
+++ b/doc/user/less-simple.in
@@ -371,7 +371,7 @@
     you'll have realized that this is similar to the
     <function>split()</function> method
     in the Python standard <function>string</function> module.
-    Unlike the <function>string.split()</function> method,
+    Unlike the <function>split()</function> member function of strings,
     however, the &Split; function
     does not require a string as input
     and will wrap up a single non-string object in a list,
diff --git a/doc/user/less-simple.xml b/doc/user/less-simple.xml
index 0bc382ef..8b781ddc 100644
--- a/doc/user/less-simple.xml
+++ b/doc/user/less-simple.xml
@@ -360,7 +360,7 @@
     you'll have realized that this is similar to the
     <function>split()</function> method
     in the Python standard <function>string</function> module.
-    Unlike the <function>string.split()</function> method,
+    Unlike the <function>split()</function> member function of strings,
     however, the &Split; function
     does not require a string as input
     and will wrap up a single non-string object in a list,
diff --git a/doc/user/tasks.in b/doc/user/tasks.in
index c51ad36e..434871ff 100644
--- a/doc/user/tasks.in
+++ b/doc/user/tasks.in
@@ -74,9 +74,8 @@ if filename.find(old_prefix) == 0:
 <simpara>or in Python 1.5.2:</simpara>
 
 <programlisting>
-import string
-if string.find(filename, old_prefix) == 0:
-    filename = string.replace(filename, old_prefix, new_prefix)      
+if filename.find(old_prefix) == 0:
+    filename = filename.replace(old_prefix, new_prefix)      
 </programlisting>
 </example>
 
diff --git a/doc/user/tasks.xml b/doc/user/tasks.xml
index c51ad36e..434871ff 100644
--- a/doc/user/tasks.xml
+++ b/doc/user/tasks.xml
@@ -74,9 +74,8 @@ if filename.find(old_prefix) == 0:
 <simpara>or in Python 1.5.2:</simpara>
 
 <programlisting>
-import string
-if string.find(filename, old_prefix) == 0:
-    filename = string.replace(filename, old_prefix, new_prefix)      
+if filename.find(old_prefix) == 0:
+    filename = filename.replace(old_prefix, new_prefix)      
 </programlisting>
 </example>
 
diff --git a/runtest.py b/runtest.py
index a9279405..7fb505a3 100644
--- a/runtest.py
+++ b/runtest.py
@@ -84,14 +84,13 @@
 # you can find the appropriate code in the 0.04 version of this script,
 # rather than reinventing that wheel.)
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import getopt
 import glob
 import os
-import os.path
 import re
 import stat
-import string
 import sys
 import time
 
@@ -216,9 +215,9 @@ for o, a in opts:
     elif o in ['-q', '--quiet']:
         printcommand = 0
     elif o in ['--sp']:
-        sp = string.split(a, os.pathsep)
+        sp = a.split(os.pathsep)
     elif o in ['--spe']:
-        spe = string.split(a, os.pathsep)
+        spe = a.split(os.pathsep)
     elif o in ['-t', '--time']:
         print_times = 1
     elif o in ['--verbose']:
@@ -245,8 +244,8 @@ runtest.py:  No tests were specified.
 if sys.platform in ('win32', 'cygwin'):
 
     def whereis(file):
-        pathext = [''] + string.split(os.environ['PATHEXT'], os.pathsep)
-        for dir in string.split(os.environ['PATH'], os.pathsep):
+        pathext = [''] + os.environ['PATHEXT'].split(os.pathsep)
+        for dir in os.environ['PATH'].split(os.pathsep):
             f = os.path.join(dir, file)
             for ext in pathext:
                 fext = f + ext
@@ -257,7 +256,7 @@ if sys.platform in ('win32', 'cygwin'):
 else:
 
     def whereis(file):
-        for dir in string.split(os.environ['PATH'], os.pathsep):
+        for dir in os.environ['PATH'].split(os.pathsep):
             f = os.path.join(dir, file)
             if os.path.isfile(f):
                 try:
@@ -295,10 +294,10 @@ if format == '--aegis' and aegis:
     if change:
         if sp is None:
             paths = os.popen("aesub '$sp' 2>/dev/null", "r").read()[:-1]
-            sp = string.split(paths, os.pathsep)
+            sp = paths.split(os.pathsep)
         if spe is None:
             spe = os.popen("aesub '$spe' 2>/dev/null", "r").read()[:-1]
-            spe = string.split(spe, os.pathsep)
+            spe = spe.split(os.pathsep)
     else:
         aegis = None
 
@@ -316,7 +315,7 @@ _ws = re.compile('\s')
 def escape(s):
     if _ws.search(s):
         s = '"' + s + '"'
-    s = string.replace(s, '\\', '\\\\')
+    s = s.replace('\\', '\\\\')
     return s
 
 # Set up lowest-common-denominator spawning of a process on both Windows
@@ -334,7 +333,7 @@ except AttributeError:
 else:
     def spawn_it(command_args):
         command = command_args[0]
-        command_args = map(escape, command_args)
+        command_args = list(map(escape, command_args))
         return os.spawnv(os.P_WAIT, command, command_args)
 
 class Base:
@@ -447,7 +446,7 @@ if package:
         'deb'        : os.path.join('python2.1', 'site-packages')
     }
 
-    if not dir.has_key(package):
+    if package not in dir:
         sys.stderr.write("Unknown package '%s'\n" % package)
         sys.exit(2)
 
@@ -490,7 +489,7 @@ else:
     #                sd = d
     #                scons = f
     #    spe = map(lambda x: os.path.join(x, 'src', 'engine'), spe)
-    #    ld = string.join(spe, os.pathsep)
+    #    ld = os.pathsep.join(spe)
 
     if not baseline or baseline == '.':
         base = cwd
@@ -569,9 +568,9 @@ for dir in sp:
         q = os.path.join(dir, 'QMTest')
     pythonpaths.append(q)
 
-os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = string.join(spe, os.pathsep)
+os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = os.pathsep.join(spe)
 
-os.environ['PYTHONPATH'] = string.join(pythonpaths, os.pathsep)
+os.environ['PYTHONPATH'] = os.pathsep.join(pythonpaths)
 
 if old_pythonpath:
     os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + \
@@ -581,21 +580,21 @@ if old_pythonpath:
 tests = []
 
 def find_Tests_py(tdict, dirname, names):
-    for n in filter(lambda n: n[-8:] == "Tests.py", names):
+    for n in [n for n in names if n[-8:] == "Tests.py"]:
         tdict[os.path.join(dirname, n)] = 1
 
 def find_py(tdict, dirname, names):
-    tests = filter(lambda n: n[-3:] == ".py", names)
+    tests = [n for n in names if n[-3:] == ".py"]
     try:
         excludes = open(os.path.join(dirname,".exclude_tests")).readlines()
     except (OSError, IOError):
         pass
     else:
         for exclude in excludes:
-            exclude = string.split(exclude, '#' , 1)[0]
-            exclude = string.strip(exclude)
+            exclude = exclude.split('#' , 1)[0]
+            exclude = exclude.strip()
             if not exclude: continue
-            tests = filter(lambda n, ex = exclude: n != ex, tests)
+            tests = [n for n in tests if n != exclude]
     for n in tests:
         tdict[os.path.join(dirname, n)] = 1
 
@@ -627,8 +626,8 @@ if args:
                     tests.append(path)
 elif testlistfile:
     tests = open(testlistfile, 'r').readlines()
-    tests = filter(lambda x: x[0] != '#', tests)
-    tests = map(lambda x: x[:-1], tests)
+    tests = [x for x in tests if x[0] != '#']
+    tests = [x[:-1] for x in tests]
 elif all and not qmtest:
     # Find all of the SCons functional tests in the local directory
     # tree.  This is anything under the 'src' subdirectory that ends
@@ -647,16 +646,16 @@ elif all and not qmtest:
     if format == '--aegis' and aegis:
         cmd = "aegis -list -unf pf 2>/dev/null"
         for line in os.popen(cmd, "r").readlines():
-            a = string.split(line)
-            if a[0] == "test" and not tdict.has_key(a[-1]):
+            a = line.split()
+            if a[0] == "test" and a[-1] not in tdict:
                 tdict[a[-1]] = Test(a[-1], spe)
         cmd = "aegis -list -unf cf 2>/dev/null"
         for line in os.popen(cmd, "r").readlines():
-            a = string.split(line)
+            a = line.split()
             if a[0] == "test":
                 if a[1] == "remove":
                     del tdict[a[-1]]
-                elif not tdict.has_key(a[-1]):
+                elif a[-1] not in tdict:
                     tdict[a[-1]] = Test(a[-1], spe)
 
     tests = tdict.keys()
@@ -701,11 +700,11 @@ if qmtest:
         qmtest_args.append(rs)
 
     if format == '--aegis':
-        tests = map(lambda x: string.replace(x, cwd+os.sep, ''), tests)
+        tests = [x.replace(cwd+os.sep, '') for x in tests]
     else:
         os.environ['SCONS'] = os.path.join(cwd, 'src', 'script', 'scons.py')
 
-    cmd = string.join(qmtest_args + tests, ' ')
+    cmd = ' '.join(qmtest_args + tests)
     if printcommand:
         sys.stdout.write(cmd + '\n')
         sys.stdout.flush()
@@ -719,7 +718,7 @@ if qmtest:
 #except OSError:
 #    pass
 
-tests = map(Test, tests)
+tests = list(map(Test, tests))
 
 class Unbuffered:
     def __init__(self, file):
@@ -766,7 +765,7 @@ for t in tests:
         command_args.append(debug)
     command_args.append(t.path)
     t.command_args = [python] + command_args
-    t.command_str = string.join([escape(python)] + command_args, " ")
+    t.command_str = " ".join([escape(python)] + command_args)
     if printcommand:
         sys.stdout.write(t.command_str + "\n")
     test_start_time = time_func()
@@ -778,9 +777,9 @@ if len(tests) > 0:
     tests[0].total_time = time_func() - total_start_time
     print_time_func("Total execution time for all tests: %.1f seconds\n", tests[0].total_time)
 
-passed = filter(lambda t: t.status == 0, tests)
-fail = filter(lambda t: t.status == 1, tests)
-no_result = filter(lambda t: t.status == 2, tests)
+passed = [t for t in tests if t.status == 0]
+fail = [t for t in tests if t.status == 1]
+no_result = [t for t in tests if t.status == 2]
 
 if len(tests) != 1 and execute_tests:
     if passed and print_passed_summary:
@@ -788,22 +787,22 @@ if len(tests) != 1 and execute_tests:
             sys.stdout.write("\nPassed the following test:\n")
         else:
             sys.stdout.write("\nPassed the following %d tests:\n" % len(passed))
-        paths = map(lambda x: x.path, passed)
-        sys.stdout.write("\t" + string.join(paths, "\n\t") + "\n")
+        paths = [x.path for x in passed]
+        sys.stdout.write("\t" + "\n\t".join(paths) + "\n")
     if fail:
         if len(fail) == 1:
             sys.stdout.write("\nFailed the following test:\n")
         else:
             sys.stdout.write("\nFailed the following %d tests:\n" % len(fail))
-        paths = map(lambda x: x.path, fail)
-        sys.stdout.write("\t" + string.join(paths, "\n\t") + "\n")
+        paths = [x.path for x in fail]
+        sys.stdout.write("\t" + "\n\t".join(paths) + "\n")
     if no_result:
         if len(no_result) == 1:
             sys.stdout.write("\nNO RESULT from the following test:\n")
         else:
             sys.stdout.write("\nNO RESULT from the following %d tests:\n" % len(no_result))
-        paths = map(lambda x: x.path, no_result)
-        sys.stdout.write("\t" + string.join(paths, "\n\t") + "\n")
+        paths = [x.path for x in no_result]
+        sys.stdout.write("\t" + "\n\t".join(paths) + "\n")
 
 if outputfile:
     if outputfile == '-':
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 41c73add..35c7316d 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -96,6 +96,7 @@ way for wrapping up the functions.
 # 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.
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -103,7 +104,6 @@ import cPickle
 import dis
 import os
 import re
-import string
 import sys
 import subprocess
 
@@ -153,7 +153,7 @@ else:
             else:
                 result.append(c)
                 i = i+1
-        return string.join(result, '')
+        return ''.join(result)
 
 strip_quotes = re.compile('^[\'"](.*)[\'"]$')
 
@@ -249,19 +249,19 @@ def _code_contents(code):
     # Note that we also always ignore the first entry of co_consts
     # which contains the function doc string. We assume that the
     # function does not access its doc string.
-    contents.append(',(' + string.join(map(_object_contents,code.co_consts[1:]),',') + ')')
+    contents.append(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')')
 
     # The code contents depends on the variable names used to
     # accessed global variable, as changing the variable name changes
     # the variable actually accessed and therefore changes the
     # function result.
-    contents.append(',(' + string.join(map(_object_contents,code.co_names),',') + ')')
+    contents.append(',(' + ','.join(map(_object_contents,code.co_names)) + ')')
 
 
     # The code contents depends on its actual code!!!
     contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')')
 
-    return string.join(contents, '')
+    return ''.join(contents)
 
 
 def _function_contents(func):
@@ -271,7 +271,7 @@ def _function_contents(func):
 
     # The function contents depends on the value of defaults arguments
     if func.func_defaults:
-        contents.append(',(' + string.join(map(_object_contents,func.func_defaults),',') + ')')
+        contents.append(',(' + ','.join(map(_object_contents,func.func_defaults)) + ')')
     else:
         contents.append(',()')
 
@@ -284,12 +284,12 @@ def _function_contents(func):
 
     #xxx = [_object_contents(x.cell_contents) for x in closure]
     try:
-        xxx = map(lambda x: _object_contents(x.cell_contents), closure)
+        xxx = [_object_contents(x.cell_contents) for x in closure]
     except AttributeError:
         xxx = []
-    contents.append(',(' + string.join(xxx, ',') + ')')
+    contents.append(',(' + ','.join(xxx) + ')')
 
-    return string.join(contents, '')
+    return ''.join(contents)
 
 
 def _actionAppend(act1, act2):
@@ -354,7 +354,7 @@ def _do_create_action(act, kw):
 
     if is_List(act):
         #TODO(1.5) return CommandAction(act, **kw)
-        return apply(CommandAction, (act,), kw)
+        return CommandAction(act, **kw)
 
     if callable(act):
         try:
@@ -378,10 +378,10 @@ def _do_create_action(act, kw):
             # like a function or a CommandGenerator in that variable
             # instead of a string.
             return LazyAction(var, kw)
-        commands = string.split(str(act), '\n')
+        commands = str(act).split('\n')
         if len(commands) == 1:
             #TODO(1.5) return CommandAction(commands[0], **kw)
-            return apply(CommandAction, (commands[0],), kw)
+            return CommandAction(commands[0], **kw)
         # The list of string commands may include a LazyAction, so we
         # reprocess them via _do_create_list_action.
         return _do_create_list_action(commands, kw)
@@ -434,7 +434,7 @@ class ActionBase:
         if is_String(vl): vl = (vl,)
         for v in vl:
             result.append(env.subst('${'+v+'}'))
-        return string.join(result, '')
+        return ''.join(result)
 
     def __add__(self, other):
         return _actionAppend(self, other)
@@ -450,7 +450,7 @@ class ActionBase:
         # and CommandGeneratorAction will use this env
         # when it calls its _generate method.
         self.presub_env = env
-        lines = string.split(str(self), '\n')
+        lines = str(self).split('\n')
         self.presub_env = None      # don't need this any more
         return lines
 
@@ -534,8 +534,8 @@ class _ActionAction(ActionBase):
             if executor:
                 target = executor.get_all_targets()
                 source = executor.get_all_sources()
-            t = string.join(map(str, target), ' and ')
-            l = string.join(self.presub_lines(env), '\n  ')
+            t = ' and '.join(map(str, target))
+            l = '\n  '.join(self.presub_lines(env))
             out = "Building %s with action:\n  %s\n" % (t, l)
             sys.stdout.write(out)
         cmd = None
@@ -590,7 +590,7 @@ def _string_from_cmd_list(cmd_list):
         if ' ' in arg or '\t' in arg:
             arg = '"' + arg + '"'
         cl.append(arg)
-    return string.join(cl)
+    return ' '.join(cl)
 
 # A fiddlin' little function that has an 'import SCons.Environment' which
 # can't be moved to the top level without creating an import loop.  Since
@@ -642,7 +642,7 @@ def _subproc(env, cmd, error = 'ignore', **kw):
             # because that's a pretty common list-like value to stick
             # in an environment variable:
             value = SCons.Util.flatten_sequence(value)
-            new_env[key] = string.join(map(str, value), os.pathsep)
+            new_env[key] = os.pathsep.join(map(str, value))
         else:
             # It's either a string or something else.  If it's a string,
             # we still want to call str() because it might be a *Unicode*
@@ -655,7 +655,7 @@ def _subproc(env, cmd, error = 'ignore', **kw):
 
     try:
         #FUTURE return subprocess.Popen(cmd, **kw)
-        return apply(subprocess.Popen, (cmd,), kw)
+        return subprocess.Popen(cmd, **kw)
     except EnvironmentError, e:
         if error == 'raise': raise
         # return a dummy Popen instance that only returns error
@@ -685,16 +685,16 @@ class CommandAction(_ActionAction):
         if __debug__: logInstanceCreation(self, 'Action.CommandAction')
 
         #TODO(1.5) _ActionAction.__init__(self, **kw)
-        apply(_ActionAction.__init__, (self,), kw)
+        _ActionAction.__init__(self, **kw)
         if is_List(cmd):
-            if filter(is_List, cmd):
+            if list(filter(is_List, cmd)):
                 raise TypeError, "CommandAction should be given only " \
                       "a single command"
         self.cmd_list = cmd
 
     def __str__(self):
         if is_List(self.cmd_list):
-            return string.join(map(str, self.cmd_list), ' ')
+            return ' '.join(map(str, self.cmd_list))
         return str(self.cmd_list)
 
     def process(self, target, source, env, executor=None):
@@ -771,7 +771,7 @@ class CommandAction(_ActionAction):
                     # path list, because that's a pretty common list-like
                     # value to stick in an environment variable:
                     value = flatten_sequence(value)
-                    ENV[key] = string.join(map(str, value), os.pathsep)
+                    ENV[key] = os.pathsep.join(map(str, value))
                 else:
                     # If it isn't a string or a list, then we just coerce
                     # it to a string, which is the proper way to handle
@@ -782,7 +782,7 @@ class CommandAction(_ActionAction):
         if executor:
             target = executor.get_all_targets()
             source = executor.get_all_sources()
-        cmd_list, ignore, silent = self.process(target, map(rfile, source), env, executor)
+        cmd_list, ignore, silent = self.process(target, list(map(rfile, source)), env, executor)
 
         # Use len() to filter out any "command" that's zero-length.
         for cmd_line in filter(len, cmd_list):
@@ -806,7 +806,7 @@ class CommandAction(_ActionAction):
         from SCons.Subst import SUBST_SIG
         cmd = self.cmd_list
         if is_List(cmd):
-            cmd = string.join(map(str, cmd))
+            cmd = ' '.join(map(str, cmd))
         else:
             cmd = str(cmd)
         if executor:
@@ -860,7 +860,7 @@ class CommandGeneratorAction(ActionBase):
                              env=env,
                              for_signature=for_signature)
         #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw)
-        gen_cmd = apply(Action, (ret,), self.gen_kw)
+        gen_cmd = Action(ret, **self.gen_kw)
         if not gen_cmd:
             raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
         return gen_cmd
@@ -885,7 +885,9 @@ class CommandGeneratorAction(ActionBase):
                  show=_null, execute=_null, chdir=_null, executor=None):
         act = self._generate(target, source, env, 0, executor)
         if act is None:
-            raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
+            raise UserError("While building `%s': "
+                            "Cannot deduce file extension from source files: %s"
+                % (repr(list(map(str, target))), repr(list(map(str, source)))))
         return act(target, source, env, exitstatfunc, presub,
                    show, execute, chdir, executor)
 
@@ -930,7 +932,7 @@ class LazyAction(CommandGeneratorAction, CommandAction):
     def __init__(self, var, kw):
         if __debug__: logInstanceCreation(self, 'Action.LazyAction')
         #FUTURE CommandAction.__init__(self, '${'+var+'}', **kw)
-        apply(CommandAction.__init__, (self, '${'+var+'}'), kw)
+        CommandAction.__init__(self, '${'+var+'}', **kw)
         self.var = SCons.Util.to_String(var)
         self.gen_kw = kw
 
@@ -946,7 +948,7 @@ class LazyAction(CommandGeneratorAction, CommandAction):
         else:
             c = ''
         #TODO(1.5) gen_cmd = Action(c, **self.gen_kw)
-        gen_cmd = apply(Action, (c,), self.gen_kw)
+        gen_cmd = Action(c, **self.gen_kw)
         if not gen_cmd:
             raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
         return gen_cmd
@@ -955,10 +957,8 @@ class LazyAction(CommandGeneratorAction, CommandAction):
         return self._generate_cache(env)
 
     def __call__(self, target, source, env, *args, **kw):
-        args = (self, target, source, env) + args
         c = self.get_parent_class(env)
-        #TODO(1.5) return c.__call__(*args, **kw)
-        return apply(c.__call__, args, kw)
+        return c.__call__(self, target, source, env, *args, **kw)
 
     def get_presig(self, target, source, env):
         c = self.get_parent_class(env)
@@ -987,7 +987,7 @@ class FunctionAction(_ActionAction):
                 self.funccontents = _object_contents(execfunction)
 
         #TODO(1.5) _ActionAction.__init__(self, **kw)
-        apply(_ActionAction.__init__, (self,), kw)
+        _ActionAction.__init__(self, **kw)
 
     def function_name(self):
         try:
@@ -1018,7 +1018,7 @@ class FunctionAction(_ActionAction):
                 else:
                     s = str_for_display()
                 return s
-            return '[' + string.join(map(quote, a), ", ") + ']'
+            return '[' + ", ".join(map(quote, a)) + ']'
         try:
             strfunc = self.execfunction.strfunction
         except AttributeError:
@@ -1045,7 +1045,7 @@ class FunctionAction(_ActionAction):
             if executor:
                 target = executor.get_all_targets()
                 source = executor.get_all_sources()
-            rsources = map(rfile, source)
+            rsources = list(map(rfile, source))
             try:
                 result = self.execfunction(target=target, source=rsources, env=env)
             except KeyboardInterrupt, e:
@@ -1095,40 +1095,34 @@ class FunctionAction(_ActionAction):
 
 class ListAction(ActionBase):
     """Class for lists of other actions."""
-    def __init__(self, list):
+    def __init__(self, actionlist):
         if __debug__: logInstanceCreation(self, 'Action.ListAction')
         def list_of_actions(x):
             if isinstance(x, ActionBase):
                 return x
             return Action(x)
-        self.list = map(list_of_actions, list)
+        self.list = list(map(list_of_actions, actionlist))
         # our children will have had any varlist
         # applied; we don't need to do it again
         self.varlist = ()
         self.targets = '$TARGETS'
 
     def genstring(self, target, source, env):
-        return string.join(map(lambda a, t=target, s=source, e=env:
-                                  a.genstring(t, s, e),
-                               self.list),
-                           '\n')
+        return '\n'.join([a.genstring(target, source, env) for a in self.list])
 
     def __str__(self):
-        return string.join(map(str, self.list), '\n')
+        return '\n'.join(map(str, self.list))
 
     def presub_lines(self, env):
         return SCons.Util.flatten_sequence(
-            map(lambda a, env=env: a.presub_lines(env), self.list))
+            [a.presub_lines(env) for a in self.list])
 
     def get_presig(self, target, source, env):
         """Return the signature contents of this action list.
 
         Simple concatenation of the signatures of the elements.
         """
-        return string.join(map(lambda x, t=target, s=source, e=env:
-                                      x.get_contents(t, s, e),
-                               self.list),
-                           "")
+        return "".join([x.get_contents(target, source, env) for x in self.list])
 
     def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
                  show=_null, execute=_null, chdir=_null, executor=None):
@@ -1204,9 +1198,7 @@ class ActionCaller:
         return self.parent.convert(s)
 
     def subst_args(self, target, source, env):
-        return map(lambda x, self=self, t=target, s=source, e=env:
-                          self.subst(x, t, s, e),
-                   self.args)
+        return [self.subst(x, target, source, env) for x in self.args]
 
     def subst_kw(self, target, source, env):
         kw = {}
@@ -1218,17 +1210,17 @@ class ActionCaller:
         args = self.subst_args(target, source, env)
         kw = self.subst_kw(target, source, env)
         #TODO(1.5) return self.parent.actfunc(*args, **kw)
-        return apply(self.parent.actfunc, args, kw)
+        return self.parent.actfunc(*args, **kw)
 
     def strfunction(self, target, source, env):
         args = self.subst_args(target, source, env)
         kw = self.subst_kw(target, source, env)
         #TODO(1.5) return self.parent.strfunc(*args, **kw)
-        return apply(self.parent.strfunc, args, kw)
+        return self.parent.strfunc(*args, **kw)
 
     def __str__(self):
         #TODO(1.5) return self.parent.strfunc(*self.args, **self.kw)
-        return apply(self.parent.strfunc, self.args, self.kw)
+        return self.parent.strfunc(*self.args, **self.kw)
 
 class ActionFactory:
     """A factory class that will wrap up an arbitrary function
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index ef91af4e..12756e59 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -37,7 +37,6 @@ class GlobalActFunc:
 import os
 import re
 import StringIO
-import string
 import sys
 import types
 import unittest
@@ -68,16 +67,16 @@ try:
 except:
     pass
 f.close()
-if os.environ.has_key( 'ACTPY_PIPE' ):
-    if os.environ.has_key( 'PIPE_STDOUT_FILE' ):
+if 'ACTPY_PIPE' in os.environ:
+    if 'PIPE_STDOUT_FILE' in os.environ:
          stdout_msg = open(os.environ['PIPE_STDOUT_FILE'], 'r').read()
     else:
-         stdout_msg = "act.py: stdout: executed act.py %s\\n" % string.join(sys.argv[1:])
+         stdout_msg = "act.py: stdout: executed act.py %s\\n" % ' '.join(sys.argv[1:])
     sys.stdout.write( stdout_msg )
-    if os.environ.has_key( 'PIPE_STDERR_FILE' ):
+    if 'PIPE_STDERR_FILE' in os.environ:
          stderr_msg = open(os.environ['PIPE_STDERR_FILE'], 'r').read()
     else:
-         stderr_msg = "act.py: stderr: executed act.py %s\\n" % string.join(sys.argv[1:])
+         stderr_msg = "act.py: stderr: executed act.py %s\\n" % ' '.join(sys.argv[1:])
     sys.stderr.write( stderr_msg )
 sys.exit(0)
 """)
@@ -147,7 +146,7 @@ class Environment:
     def __setitem__(self, item, value):
         self.d[item] = value
     def has_key(self, item):
-        return self.d.has_key(item)
+        return item in self.d
     def get(self, key, value=None):
         return self.d.get(key, value)
     def items(self):
@@ -193,7 +192,7 @@ _null = SCons.Action._null
 def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw):
     def call_action(a, pos_call=pos_call, str_call=str_call, kw=kw):
         #FUTURE a = SCons.Action.Action(*a, **kw)
-        a = apply(SCons.Action.Action, a, kw)
+        a = SCons.Action.Action(*a, **kw)
         # returned object must provide these entry points
         assert hasattr(a, '__call__')
         assert hasattr(a, 'get_contents')
@@ -229,7 +228,7 @@ def test_positional_args(pos_callback, cmd, **kw):
     """Test that Action() returns the expected type and that positional args work.
     """
     #FUTURE act = SCons.Action.Action(cmd, **kw)
-    act = apply(SCons.Action.Action, (cmd,), kw)
+    act = SCons.Action.Action(cmd, **kw)
     pos_callback(act)
     assert act.varlist is (), act.varlist
 
@@ -237,7 +236,7 @@ def test_positional_args(pos_callback, cmd, **kw):
         # only valid cmdstrfunc is None
         def none(a): pass
         #FUTURE test_varlist(pos_callback, none, cmd, None, **kw)
-        apply(test_varlist, (pos_callback, none, cmd, None), kw)
+        test_varlist(pos_callback, none, cmd, None, **kw)
     else:
         # _ActionAction should have set these
         assert hasattr(act, 'strfunction')
@@ -251,29 +250,29 @@ def test_positional_args(pos_callback, cmd, **kw):
             assert hasattr(a, 'strfunction')
             assert a.cmdstr == 'cmdstr', a.cmdstr
         #FUTURE test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw)
-        apply(test_varlist, (pos_callback, cmdstr, cmd, 'cmdstr'), kw)
+        test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw)
 
         def fun(): pass
         def strfun(a, fun=fun):
             assert a.strfunction is fun, a.strfunction
             assert a.cmdstr == _null, a.cmdstr
         #FUTURE test_varlist(pos_callback, strfun, cmd, fun, **kw)
-        apply(test_varlist, (pos_callback, strfun, cmd, fun), kw)
+        test_varlist(pos_callback, strfun, cmd, fun, **kw)
 
         def none(a):
             assert hasattr(a, 'strfunction')
             assert a.cmdstr is None, a.cmdstr
         #FUTURE test_varlist(pos_callback, none, cmd, None, **kw)
-        apply(test_varlist, (pos_callback, none, cmd, None), kw)
+        test_varlist(pos_callback, none, cmd, None, **kw)
 
         """Test handling of bad cmdstrfunc arguments """
         try:
             #FUTURE a = SCons.Action.Action(cmd, [], **kw)
-            a = apply(SCons.Action.Action, (cmd, []), kw)
+            a = SCons.Action.Action(cmd, [], **kw)
         except SCons.Errors.UserError, e:
             s = str(e)
             m = 'Invalid command display variable'
-            assert string.find(s, m) != -1, 'Unexpected string:  %s' % s
+            assert s.find(m) != -1, 'Unexpected string:  %s' % s
         else:
             raise Exception, "did not catch expected UserError"
 
@@ -490,7 +489,7 @@ class _ActionActionTestCase(unittest.TestCase):
         except SCons.Errors.UserError, e:
             s = str(e)
             m = 'Cannot have both strfunction and cmdstr args to Action()'
-            assert string.find(s, m) != -1, 'Unexpected string:  %s' % s
+            assert s.find(m) != -1, 'Unexpected string:  %s' % s
         else:
             raise Exception, "did not catch expected UserError"
 
@@ -752,8 +751,7 @@ class _ActionActionTestCase(unittest.TestCase):
         sum = act1 + act2
         assert isinstance(sum, SCons.Action.ListAction), str(sum)
         assert len(sum.list) == 3, len(sum.list)
-        assert map(lambda x: isinstance(x, SCons.Action.ActionBase),
-                   sum.list) == [ 1, 1, 1 ]
+        assert [isinstance(x, SCons.Action.ActionBase) for x in sum.list] == [ 1, 1, 1 ]
 
         sum = act1 + act1
         assert isinstance(sum, SCons.Action.ListAction), str(sum)
@@ -1050,7 +1048,7 @@ class CommandActionTestCase(unittest.TestCase):
         cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile)
 
         act = SCons.Action.CommandAction(cmd3)
-        r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Clone())
+        r = act(list(map(DummyNode, ['aaa', 'bbb'])), [], env.Clone())
         assert r == 0
         c = test.read(outfile, 'r')
         assert c == "act.py: 'aaa' 'bbb'\n", c
@@ -1077,7 +1075,7 @@ class CommandActionTestCase(unittest.TestCase):
 
         act = SCons.Action.CommandAction(cmd5)
         env5 = Environment()
-        if scons_env.has_key('ENV'):
+        if 'ENV' in scons_env:
             env5['ENV'] = scons_env['ENV']
             PATH = scons_env['ENV'].get('PATH', '')
         else:
@@ -1332,8 +1330,8 @@ class CommandActionTestCase(unittest.TestCase):
         # that scheme, then all of the '__t1__' and '__s6__' file names
         # in the asserts below would change to 't1' and 's6' and the
         # like.
-        t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6'])
-        s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6'])
+        t = list(map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6']))
+        s = list(map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6']))
         env = Environment()
 
         a = SCons.Action.CommandAction(["$TARGET"])
@@ -1528,7 +1526,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
         def f_local(target, source, env, for_signature, LocalFunc=LocalFunc):
             return SCons.Action.Action(LocalFunc, varlist=['XYZ'])
 
-        matches_foo = map(lambda x: x + "foo", func_matches)
+        matches_foo = [x + "foo" for x in func_matches]
 
         a = self.factory(f_global)
         c = a.get_contents(target=[], source=[], env=env)
@@ -1676,7 +1674,7 @@ class FunctionActionTestCase(unittest.TestCase):
         c = a.get_contents(target=[], source=[], env=Environment())
         assert c in func_matches, repr(c)
 
-        matches_foo = map(lambda x: x + "foo", func_matches)
+        matches_foo = [x + "foo" for x in func_matches]
 
         a = factory(GlobalFunc, varlist=['XYZ'])
         c = a.get_contents(target=[], source=[], env=Environment())
@@ -1892,7 +1890,7 @@ class LazyActionTestCase(unittest.TestCase):
         c = a.get_contents(target=[], source=[], env=env)
         assert c in func_matches, repr(c)
 
-        matches_foo = map(lambda x: x + "foo", func_matches)
+        matches_foo = [x + "foo" for x in func_matches]
 
         env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ']))
         c = a.get_contents(target=[], source=[], env=env)
@@ -2096,7 +2094,7 @@ if __name__ == "__main__":
                  ActionCompareTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 6405da35..c999afdd 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -97,6 +97,7 @@ There are the following methods for internal use within this module:
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -120,10 +121,9 @@ _null = _Null
 
 def match_splitext(path, suffixes = []):
     if suffixes:
-        matchsuf = filter(lambda S,path=path: path[-len(S):] == S,
-                          suffixes)
+        matchsuf = [S for S in suffixes if path[-len(S):] == S]
         if matchsuf:
-            suf = max(map(None, map(len, matchsuf), matchsuf))[1]
+            suf = max(list(map(None, list(map(len, matchsuf)), matchsuf)))[1]
             return [path[:-len(suf)], path[-len(suf):]]
     return SCons.Util.splitext(path)
 
@@ -156,14 +156,17 @@ class DictCmdGenerator(SCons.Util.Selector):
             for src in map(str, source):
                 my_ext = match_splitext(src, suffixes)[1]
                 if ext and my_ext != ext:
-                    raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" % (repr(map(str, target)), src, ext, my_ext))
+                    raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s"
+                             % (repr(list(map(str, target))), src, ext, my_ext))
                 ext = my_ext
         else:
             ext = match_splitext(str(source[0]), self.src_suffixes())[1]
 
         if not ext:
             #return ext
-            raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
+            raise UserError("While building `%s': "
+                            "Cannot deduce file extension from source files: %s"
+                 % (repr(list(map(str, target))), repr(list(map(str, source)))))
 
         try:
             ret = SCons.Util.Selector.__call__(self, env, source, ext)
@@ -171,7 +174,7 @@ class DictCmdGenerator(SCons.Util.Selector):
             raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e[0], e[1], e[2]))
         if ret is None:
             raise UserError("While building `%s' from `%s': Don't know how to build from a source file with suffix `%s'.  Expected a suffix in this list: %s." % \
-                            (repr(map(str, target)), repr(map(str, source)), ext, repr(self.keys())))
+                            (repr(list(map(str, target))), repr(list(map(str, source))), ext, repr(self.keys())))
         return ret
 
 class CallableSelector(SCons.Util.Selector):
@@ -231,7 +234,7 @@ class OverrideWarner(UserDict.UserDict):
         if self.already_warned:
             return
         for k in self.keys():
-            if misleading_keywords.has_key(k):
+            if k in misleading_keywords:
                 alt = misleading_keywords[k]
                 msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k)
                 SCons.Warnings.warn(SCons.Warnings.MisleadingKeywordsWarning, msg)
@@ -240,14 +243,14 @@ class OverrideWarner(UserDict.UserDict):
 def Builder(**kw):
     """A factory for builder objects."""
     composite = None
-    if kw.has_key('generator'):
-        if kw.has_key('action'):
+    if 'generator' in kw:
+        if 'action' in kw:
             raise UserError, "You must not specify both an action and a generator."
         kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'], {})
         del kw['generator']
-    elif kw.has_key('action'):
+    elif 'action' in kw:
         source_ext_match = kw.get('source_ext_match', 1)
-        if kw.has_key('source_ext_match'):
+        if 'source_ext_match' in kw:
             del kw['source_ext_match']
         if SCons.Util.is_Dict(kw['action']):
             composite = DictCmdGenerator(kw['action'], source_ext_match)
@@ -256,7 +259,7 @@ def Builder(**kw):
         else:
             kw['action'] = SCons.Action.Action(kw['action'])
 
-    if kw.has_key('emitter'):
+    if 'emitter' in kw:
         emitter = kw['emitter']
         if SCons.Util.is_String(emitter):
             # This allows users to pass in an Environment
@@ -272,7 +275,7 @@ def Builder(**kw):
         elif SCons.Util.is_List(emitter):
             kw['emitter'] = ListEmitter(emitter)
 
-    result = apply(BuilderBase, (), kw)
+    result = BuilderBase(**kw)
 
     if not composite is None:
         result = CompositeBuilder(result, composite)
@@ -308,15 +311,15 @@ def _node_errors(builder, env, tlist, slist):
                     raise UserError, msg
                 # TODO(batch):  list constructed each time!
                 if t.get_executor().get_all_targets() != tlist:
-                    msg = "Two different target lists have a target in common: %s  (from %s and from %s)" % (t, map(str, t.get_executor().get_all_targets()), map(str, tlist))
+                    msg = "Two different target lists have a target in common: %s  (from %s and from %s)" % (t, list(map(str, t.get_executor().get_all_targets())), list(map(str, tlist)))
                     raise UserError, msg
             elif t.sources != slist:
-                msg = "Multiple ways to build the same target were specified for: %s  (from %s and from %s)" % (t, map(str, t.sources), map(str, slist))
+                msg = "Multiple ways to build the same target were specified for: %s  (from %s and from %s)" % (t, list(map(str, t.sources)), list(map(str, slist)))
                 raise UserError, msg
 
     if builder.single_source:
         if len(slist) > 1:
-            raise UserError, "More than one source given for single-source builder: targets=%s sources=%s" % (map(str,tlist), map(str,slist))
+            raise UserError, "More than one source given for single-source builder: targets=%s sources=%s" % (list(map(str,tlist)), list(map(str,slist)))
 
 class EmitterProxy:
     """This is a callable class that can act as a
@@ -334,7 +337,7 @@ class EmitterProxy:
         # Recursively substitute the variable.
         # We can't use env.subst() because it deals only
         # in strings.  Maybe we should change that?
-        while SCons.Util.is_String(emitter) and env.has_key(emitter):
+        while SCons.Util.is_String(emitter) and emitter in env:
             emitter = env[emitter]
         if callable(emitter):
             target, source = emitter(target, source, env)
@@ -387,13 +390,13 @@ class BuilderBase:
             suffix = CallableSelector(suffix)
         self.env = env
         self.single_source = single_source
-        if overrides.has_key('overrides'):
+        if 'overrides' in overrides:
             SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
                 "The \"overrides\" keyword to Builder() creation has been deprecated;\n" +\
                 "\tspecify the items as keyword arguments to the Builder() call instead.")
             overrides.update(overrides['overrides'])
             del overrides['overrides']
-        if overrides.has_key('scanner'):
+        if 'scanner' in overrides:
             SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
                                 "The \"scanner\" keyword to Builder() creation has been deprecated;\n"
                                 "\tuse: source_scanner or target_scanner as appropriate.")
@@ -493,7 +496,7 @@ class BuilderBase:
             except IndexError:
                 tlist = []
             else:
-                splitext = lambda S,self=self,env=env: self.splitext(S,env)
+                splitext = lambda S: self.splitext(S,env)
                 tlist = [ t_from_s(pre, suf, splitext) ]
         else:
             target = self._adjustixes(target, pre, suf, self.ensure_suffix)
@@ -574,7 +577,7 @@ class BuilderBase:
             if not self.action:
                 fmt = "Builder %s must have an action to build %s."
                 raise UserError, fmt % (self.get_name(env or self.env),
-                                        map(str,tlist))
+                                        list(map(str,tlist)))
             key = self.action.batch_key(env or self.env, tlist, slist)
             if key:
                 try:
@@ -611,7 +614,7 @@ class BuilderBase:
             ekw = self.executor_kw.copy()
             ekw['chdir'] = chdir
         if kw:
-            if kw.has_key('srcdir'):
+            if 'srcdir' in kw:
                 def prependDirIfRelative(f, srcdir=kw['srcdir']):
                     import os.path
                     if SCons.Util.is_String(f) and not os.path.isabs(f):
@@ -619,7 +622,7 @@ class BuilderBase:
                     return f
                 if not SCons.Util.is_List(source):
                     source = [source]
-                source = map(prependDirIfRelative, source)
+                source = list(map(prependDirIfRelative, source))
                 del kw['srcdir']
             if self.overrides:
                 env_kw = self.overrides.copy()
@@ -658,9 +661,7 @@ class BuilderBase:
             src_suffix = []
         elif not SCons.Util.is_List(src_suffix):
             src_suffix = [ src_suffix ]
-        adjust = lambda suf, s=self: \
-                        callable(suf) and suf or s.adjust_suffix(suf)
-        self.src_suffix = map(adjust, src_suffix)
+        self.src_suffix = [callable(suf) and suf or self.adjust_suffix(suf) for suf in src_suffix]
 
     def get_src_suffix(self, env):
         """Get the first src_suffix in the list of src_suffixes."""
@@ -723,7 +724,7 @@ class BuilderBase:
         lengths = list(set(map(len, src_suffixes)))
 
         def match_src_suffix(name, src_suffixes=src_suffixes, lengths=lengths):
-            node_suffixes = map(lambda l, n=name: n[-l:], lengths)
+            node_suffixes = [name[-l:] for l in lengths]
             for suf in src_suffixes:
                 if suf in node_suffixes:
                     return suf
@@ -749,8 +750,7 @@ class BuilderBase:
                     # target, then filter out any sources that this
                     # Builder isn't capable of building.
                     if len(tlist) > 1:
-                        mss = lambda t, m=match_src_suffix: m(t.name)
-                        tlist = filter(mss, tlist)
+                        tlist = [t for t in tlist if match_src_suffix(t.name)]
                     result.extend(tlist)
             else:
                 result.append(s)
@@ -819,7 +819,7 @@ class BuilderBase:
                 return memo_dict[memo_key]
             except KeyError:
                 pass
-        suffixes = map(lambda x, s=self, e=env: e.subst(x), self.src_suffix)
+        suffixes = [env.subst(x) for x in self.src_suffix]
         memo_dict[memo_key] = suffixes
         return suffixes
 
@@ -838,7 +838,7 @@ class BuilderBase:
             sdict[s] = 1
         for builder in self.get_src_builders(env):
             for s in builder.src_suffixes(env):
-                if not sdict.has_key(s):
+                if s not in sdict:
                     sdict[s] = 1
                     suffixes.append(s)
         return suffixes
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index dc60d06d..d14f777f 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -118,14 +118,16 @@ class Environment:
         self.d[item] = var
     def __getitem__(self, item):
         return self.d[item]
+    def __contains__(self, item):
+        return self.d.__contains__(item)
     def has_key(self, item):
-        return self.d.has_key(item)
+        return item in self.d
     def keys(self):
         return self.d.keys()
     def get(self, key, value=None):
         return self.d.get(key, value)
     def Override(self, overrides):
-        env = apply(Environment, (), self.d)
+        env = Environment(**self.d)
         env.d.update(overrides)
         env.scanner = self.scanner
         return env
@@ -255,7 +257,7 @@ class BuilderTestCase(unittest.TestCase):
             l.extend(ul)
         except TypeError:
             def mystr(l):
-                return str(map(str, l))
+                return str(list(map(str, l)))
         else:
             mystr = str
 
@@ -264,14 +266,14 @@ class BuilderTestCase(unittest.TestCase):
         tlist = builder(env, target = [nnn1, nnn2], source = [])
         s = mystr(tlist)
         assert s == "['nnn1', 'nnn2']", s
-        l = map(str, tlist)
+        l = list(map(str, tlist))
         assert l == ['nnn1', 'nnn2'], l
 
         tlist = builder(env, target = 'n3', source = 'n4')
         s = mystr(tlist)
         assert s == "['n3']", s
         target = tlist[0]
-        l = map(str, tlist)
+        l = list(map(str, tlist))
         assert l == ['n3'], l
         assert target.name == 'n3'
         assert target.sources[0].name == 'n4'
@@ -279,7 +281,7 @@ class BuilderTestCase(unittest.TestCase):
         tlist = builder(env, target = 'n4 n5', source = ['n6 n7'])
         s = mystr(tlist)
         assert s == "['n4 n5']", s
-        l = map(str, tlist)
+        l = list(map(str, tlist))
         assert l == ['n4 n5'], l
         target = tlist[0]
         assert target.name == 'n4 n5'
@@ -288,7 +290,7 @@ class BuilderTestCase(unittest.TestCase):
         tlist = builder(env, target = ['n8 n9'], source = 'n10 n11')
         s = mystr(tlist)
         assert s == "['n8 n9']", s
-        l = map(str, tlist)
+        l = list(map(str, tlist))
         assert l == ['n8 n9'], l
         target = tlist[0]
         assert target.name == 'n8 n9'
@@ -618,7 +620,7 @@ class BuilderTestCase(unittest.TestCase):
                                    src_suffix='.obj',
                                    suffix='.exe')
         tgt = b2(env, target=None, source=['foo$OBJSUFFIX'])
-        s = map(str, tgt[0].sources)
+        s = list(map(str, tgt[0].sources))
         assert s == ['foo.obj'], s
 
     def test_suffix(self):
@@ -715,10 +717,10 @@ class BuilderTestCase(unittest.TestCase):
             # support anyway, don't bother trying to test for it.
             pass
         else:
-            s = map(str, tgts)
+            s = list(map(str, tgts))
             expect = [test.workpath('2.out'), test.workpath('3.out')]
-            expect = map(os.path.normcase, expect)
-            assert map(os.path.normcase, s) == expect, s
+            expect = list(map(os.path.normcase, expect))
+            assert list(map(os.path.normcase, s)) == expect, s
         for t in tgts: t.prepare()
         tgts[0].build()
         tgts[1].build()
@@ -744,7 +746,7 @@ class BuilderTestCase(unittest.TestCase):
             for t in target:
                 open(str(t), 'w').write("function2\n")
             for t in tlist:
-                if not t in map(str, target):
+                if not t in list(map(str, target)):
                     open(t, 'w').write("function2\n")
             return 1
 
@@ -773,7 +775,7 @@ class BuilderTestCase(unittest.TestCase):
             for t in target:
                 open(str(t), 'w').write("function3\n")
             for t in tlist:
-                if not t in map(str, target):
+                if not t in list(map(str, target)):
                     open(t, 'w').write("function3\n")
             return 1
 
@@ -811,17 +813,17 @@ class BuilderTestCase(unittest.TestCase):
         tgt = builder2(env, target='baz', source=sources)[0]
         s = str(tgt)
         assert s == 'baz', s
-        s = map(str, tgt.sources)
+        s = list(map(str, tgt.sources))
         assert s == ['test.foo', 'test2.foo', 'test3.txt', 'test4.foo'], s
-        s = map(str, tgt.sources[0].sources)
+        s = list(map(str, tgt.sources[0].sources))
         assert s == ['test.bar'], s
 
         tgt = builder2(env, None, 'aaa.bar')[0]
         s = str(tgt)
         assert s == 'aaa', s
-        s = map(str, tgt.sources)
+        s = list(map(str, tgt.sources))
         assert s == ['aaa.foo'], s
-        s = map(str, tgt.sources[0].sources)
+        s = list(map(str, tgt.sources[0].sources))
         assert s == ['aaa.bar'], s
 
         builder3 = SCons.Builder.Builder(action='bld3')
@@ -841,11 +843,11 @@ class BuilderTestCase(unittest.TestCase):
         tgt = builder6(env, 'test', 'test.i')[0]
         s = str(tgt)
         assert s == 'test.exe', s
-        s = map(str, tgt.sources)
+        s = list(map(str, tgt.sources))
         assert s == ['test_wrap.obj'], s
-        s = map(str, tgt.sources[0].sources)
+        s = list(map(str, tgt.sources[0].sources))
         assert s == ['test_wrap.c'], s
-        s = map(str, tgt.sources[0].sources[0].sources)
+        s = list(map(str, tgt.sources[0].sources[0].sources))
         assert s == ['test.i'], s
 
     def test_target_scanner(self):
@@ -1198,14 +1200,14 @@ class BuilderTestCase(unittest.TestCase):
 
         tgt = builder(env, target='foo3', source='bar', foo=1)
         assert len(tgt) == 2, len(tgt)
-        assert 'foo3' in map(str, tgt), map(str, tgt)
-        assert 'bar1' in map(str, tgt), map(str, tgt)
+        assert 'foo3' in list(map(str, tgt)), list(map(str, tgt))
+        assert 'bar1' in list(map(str, tgt)), list(map(str, tgt))
 
         tgt = builder(env, target='foo4', source='bar', bar=1)[0]
         assert str(tgt) == 'foo4', str(tgt)
         assert len(tgt.sources) == 2, len(tgt.sources)
-        assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
-        assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+        assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+        assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
 
         env2=Environment(FOO=emit)
         builder2=SCons.Builder.Builder(action='foo',
@@ -1226,14 +1228,14 @@ class BuilderTestCase(unittest.TestCase):
 
         tgt = builder2(env2, target='foo6', source='bar', foo=2)
         assert len(tgt) == 2, len(tgt)
-        assert 'foo6' in map(str, tgt), map(str, tgt)
-        assert 'bar2' in map(str, tgt), map(str, tgt)
+        assert 'foo6' in list(map(str, tgt)), list(map(str, tgt))
+        assert 'bar2' in list(map(str, tgt)), list(map(str, tgt))
 
         tgt = builder2(env2, target='foo7', source='bar', bar=1)[0]
         assert str(tgt) == 'foo7', str(tgt)
         assert len(tgt.sources) == 2, len(tgt.sources)
-        assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
-        assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+        assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+        assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
 
     def test_emitter_preserve_builder(self):
         """Test an emitter not overwriting a newly-set builder"""
@@ -1262,12 +1264,12 @@ class BuilderTestCase(unittest.TestCase):
         env = Environment()
 
         def emit4a(target, source, env):
-            source = map(str, source)
-            target = map(lambda x: 'emit4a-' + x[:-3], source)
+            source = list(map(str, source))
+            target = ['emit4a-' + x[:-3] for x in source]
             return (target, source)
         def emit4b(target, source, env):
-            source = map(str, source)
-            target = map(lambda x: 'emit4b-' + x[:-3], source)
+            source = list(map(str, source))
+            target = ['emit4b-' + x[:-3] for x in source]
             return (target, source)
 
         builder = SCons.Builder.Builder(action='foo',
@@ -1283,8 +1285,8 @@ class BuilderTestCase(unittest.TestCase):
         assert str(tgt) == 'ccc', str(tgt)
 
         def emit4c(target, source, env):
-            source = map(str, source)
-            target = map(lambda x: 'emit4c-' + x[:-3], source)
+            source = list(map(str, source))
+            target = ['emit4c-' + x[:-3] for x in source]
             return (target, source)
 
         builder.add_emitter('.4c', emit4c)
@@ -1296,29 +1298,29 @@ class BuilderTestCase(unittest.TestCase):
         env = Environment()
 
         def emit1a(target, source, env):
-            source = map(str, source)
-            target = target + map(lambda x: 'emit1a-' + x[:-2], source)
+            source = list(map(str, source))
+            target = target + ['emit1a-' + x[:-2] for x in source]
             return (target, source)
         def emit1b(target, source, env):
-            source = map(str, source)
-            target = target + map(lambda x: 'emit1b-' + x[:-2], source)
+            source = list(map(str, source))
+            target = target + ['emit1b-' + x[:-2] for x in source]
             return (target, source)
         builder1 = SCons.Builder.Builder(action='foo',
                                          emitter=[emit1a, emit1b],
                                          node_factory=MyNode)
 
         tgts = builder1(env, target='target-1', source='aaa.1')
-        tgts = map(str, tgts)
+        tgts = list(map(str, tgts))
         assert tgts == ['target-1', 'emit1a-aaa', 'emit1b-aaa'], tgts
 
         # Test a list of emitter functions through the environment.
         def emit2a(target, source, env):
-            source = map(str, source)
-            target = target + map(lambda x: 'emit2a-' + x[:-2], source)
+            source = list(map(str, source))
+            target = target + ['emit2a-' + x[:-2] for x in source]
             return (target, source)
         def emit2b(target, source, env):
-            source = map(str, source)
-            target = target + map(lambda x: 'emit2b-' + x[:-2], source)
+            source = list(map(str, source))
+            target = target + ['emit2b-' + x[:-2] for x in source]
             return (target, source)
         builder2 = SCons.Builder.Builder(action='foo',
                                          emitter='$EMITTERLIST',
@@ -1327,7 +1329,7 @@ class BuilderTestCase(unittest.TestCase):
         env = Environment(EMITTERLIST = [emit2a, emit2b])
 
         tgts = builder2(env, target='target-2', source='aaa.2')
-        tgts = map(str, tgts)
+        tgts = list(map(str, tgts))
         assert tgts == ['target-2', 'emit2a-aaa', 'emit2b-aaa'], tgts
 
     def test_emitter_TARGET_SOURCE(self):
@@ -1345,8 +1347,8 @@ class BuilderTestCase(unittest.TestCase):
 
         targets = builder(env, target = 'TTT', source ='SSS')
         sources = targets[0].sources
-        targets = map(str, targets)
-        sources = map(str, sources)
+        targets = list(map(str, targets))
+        sources = list(map(str, sources))
         assert targets == ['TTT', 'SSS.s1', 'TTT.t1'], targets
         assert sources == ['SSS', 'TTT.t2', 'SSS.s2'], targets
 
@@ -1358,53 +1360,53 @@ class BuilderTestCase(unittest.TestCase):
 
         tgt = b(env, None, 'aaa')[0]
         assert str(tgt) == 'aaa.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'aaa', list(map(str, tgt.sources))
 
         tgt = b(env, None, 'bbb.c')[0]
         assert str(tgt) == 'bbb.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'bbb.c', list(map(str, tgt.sources))
 
         tgt = b(env, None, 'ccc.x.c')[0]
         assert str(tgt) == 'ccc.x.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'ccc.x.c', list(map(str, tgt.sources))
 
         tgt = b(env, None, ['d0.c', 'd1.c'])[0]
         assert str(tgt) == 'd0.o', str(tgt)
-        assert len(tgt.sources) == 2,  map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'd0.c', map(str, tgt.sources)
-        assert str(tgt.sources[1]) == 'd1.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 2,  list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'd0.c', list(map(str, tgt.sources))
+        assert str(tgt.sources[1]) == 'd1.c', list(map(str, tgt.sources))
 
         tgt = b(env, target = None, source='eee')[0]
         assert str(tgt) == 'eee.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'eee', list(map(str, tgt.sources))
 
         tgt = b(env, target = None, source='fff.c')[0]
         assert str(tgt) == 'fff.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'fff.c', list(map(str, tgt.sources))
 
         tgt = b(env, target = None, source='ggg.x.c')[0]
         assert str(tgt) == 'ggg.x.o', str(tgt)
-        assert len(tgt.sources) == 1, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'ggg.x.c', list(map(str, tgt.sources))
 
         tgt = b(env, target = None, source=['h0.c', 'h1.c'])[0]
         assert str(tgt) == 'h0.o', str(tgt)
-        assert len(tgt.sources) == 2,  map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'h0.c', map(str, tgt.sources)
-        assert str(tgt.sources[1]) == 'h1.c', map(str, tgt.sources)
+        assert len(tgt.sources) == 2,  list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'h0.c', list(map(str, tgt.sources))
+        assert str(tgt.sources[1]) == 'h1.c', list(map(str, tgt.sources))
 
         w = b(env, target='i0.w', source=['i0.x'])[0]
         y = b(env, target='i1.y', source=['i1.z'])[0]
         tgt = b(env, None, source=[w, y])[0]
         assert str(tgt) == 'i0.o', str(tgt)
-        assert len(tgt.sources) == 2, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'i0.w', map(str, tgt.sources)
-        assert str(tgt.sources[1]) == 'i1.y', map(str, tgt.sources)
+        assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'i0.w', list(map(str, tgt.sources))
+        assert str(tgt.sources[1]) == 'i1.y', list(map(str, tgt.sources))
 
     def test_get_name(self):
         """Test getting name of builder.
@@ -1642,7 +1644,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index 73bfe6be..d585888a 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -29,7 +29,6 @@ CacheDir support
 
 import os.path
 import stat
-import string
 import sys
 
 import SCons.Action
@@ -158,7 +157,7 @@ class CacheDir:
             return None, None
 
         sig = node.get_cachedir_bsig()
-        subdir = string.upper(sig[0])
+        subdir = sig[0].upper()
         dir = os.path.join(self.path, subdir)
         return dir, os.path.join(dir, sig)
 
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 5e63548a..54475096 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -286,7 +286,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py
index e995e77a..9221e2fa 100644
--- a/src/engine/SCons/Conftest.py
+++ b/src/engine/SCons/Conftest.py
@@ -101,7 +101,6 @@ Autoconf-like configuration support; low level implementation of tests.
 #
 
 import re
-import string
 from types import IntType
 
 #
@@ -230,7 +229,7 @@ int main()
 
 def _check_empty_program(context, comp, text, language, use_shared = False):
     """Return 0 on success, 1 otherwise."""
-    if not context.env.has_key(comp) or not context.env[comp]:
+    if comp not in context.env or not context.env[comp]:
         # The compiler construction variable is not set or empty
         return 1
 
@@ -636,7 +635,7 @@ return 0;
 """ % (call or "")
 
     if call:
-        i = string.find(call, "\n")
+        i = call.find("\n")
         if i > 0:
             calltext = call[:i] + ".."
         elif call[-1] == ';':
@@ -723,7 +722,7 @@ def _Have(context, key, have, comment = None):
              Give "have" as is should appear in the header file, include quotes
              when desired and escape special characters!
     """
-    key_up = string.upper(key)
+    key_up = key.upper()
     key_up = re.sub('[^A-Z0-9_]', '_', key_up)
     context.havedict[key_up] = have
     if have == 1:
@@ -755,7 +754,7 @@ def _LogFailed(context, text, msg):
     """
     if LogInputFiles:
         context.Log("Failed program was:\n")
-        lines = string.split(text, '\n')
+        lines = text.split('\n')
         if len(lines) and lines[-1] == '':
             lines = lines[:-1]              # remove trailing empty line
         n = 1
diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py
index 90e5a82e..a6c0cb55 100644
--- a/src/engine/SCons/Debug.py
+++ b/src/engine/SCons/Debug.py
@@ -32,7 +32,6 @@ needed by most users.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 import time
 
@@ -46,7 +45,7 @@ else:
     def logInstanceCreation(instance, name=None):
         if name is None:
             name = instance.__class__.__name__
-        if not tracked_classes.has_key(name):
+        if name not in tracked_classes:
             tracked_classes[name] = []
         tracked_classes[name].append(weakref.ref(instance))
 
@@ -60,11 +59,11 @@ def string_to_classes(s):
         c.sort()
         return c
     else:
-        return string.split(s)
+        return s.split()
 
 def fetchLoggedInstances(classes="*"):
     classnames = string_to_classes(classes)
-    return map(lambda cn: (cn, len(tracked_classes[cn])), classnames)
+    return [(cn, len(tracked_classes[cn])) for cn in classnames]
   
 def countLoggedInstances(classes, file=sys.stdout):
     for classname in string_to_classes(classes):
@@ -94,7 +93,7 @@ if sys.platform[:5] == "linux":
     # Linux doesn't actually support memory usage stats from getrusage().
     def memory():
         mstr = open('/proc/self/stat').read()
-        mstr = string.split(mstr)[22]
+        mstr = mstr.split()[22]
         return int(mstr)
 else:
     try:
@@ -156,7 +155,7 @@ def _dump_one_caller(key, file, level=0):
     leader = '      '*level
     for v,c in l:
         file.write("%s  %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:])))
-        if caller_dicts.has_key(c):
+        if c in caller_dicts:
             _dump_one_caller(c, file, level+1)
 
 # print each call tree
@@ -175,15 +174,12 @@ shorten_list = [
 ]
 
 if os.sep != '/':
-   def platformize(t):
-       return (string.replace(t[0], '/', os.sep), t[1])
-   shorten_list = map(platformize, shorten_list)
-   del platformize
+    shorten_list = [(t[0].replace('/', os.sep), t[1]) for t in shorten_list]
 
 def func_shorten(func_tuple):
     f = func_tuple[0]
     for t in shorten_list:
-        i = string.find(f, t[0])
+        i = f.find(t[0])
         if i >= 0:
             if t[1]:
                 i = i + len(t[0])
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 7ce981dd..2f48d0d3 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -41,7 +41,6 @@ import os.path
 import errno
 import shutil
 import stat
-import string
 import time
 import types
 import sys
@@ -88,7 +87,7 @@ def DefaultEnvironment(*args, **kw):
     global _default_env
     if not _default_env:
         import SCons.Util
-        _default_env = apply(SCons.Environment.Environment, args, kw)
+        _default_env = SCons.Environment.Environment(*args, **kw)
         if SCons.Util.md5:
             _default_env.Decider('MD5')
         else:
@@ -165,7 +164,7 @@ def get_paths_str(dest):
         elem_strs = []
         for element in dest:
             elem_strs.append('"' + str(element) + '"')
-        return '[' + string.join(elem_strs, ', ') + ']'
+        return '[' + ', '.join(elem_strs) + ']'
     else:
         return '"' + str(dest) + '"'
 
@@ -315,16 +314,16 @@ def _concat_ixes(prefix, list, suffix, env):
 
     return result
 
-def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
+def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
     """
-    This is a wrapper around _concat()/_concat_ixes() that checks for the
-    existence of prefixes or suffixes on list elements and strips them
+    This is a wrapper around _concat()/_concat_ixes() that checks for
+    the existence of prefixes or suffixes on list items and strips them
     where it finds them.  This is used by tools (like the GNU linker)
     that need to turn something like 'libfoo.a' into '-lfoo'.
     """
     
-    if not list:
-        return list
+    if not itms:
+        return itms
 
     if not callable(c):
         env_c = env['_concat']
@@ -337,11 +336,11 @@ def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
         else:
             c = _concat_ixes
     
-    stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
-    stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
+    stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes)))
+    stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes)))
 
     stripped = []
-    for l in SCons.PathList.PathList(list).subst_path(env, None, None):
+    for l in SCons.PathList.PathList(itms).subst_path(env, None, None):
         if isinstance(l, SCons.Node.FS.File):
             stripped.append(l)
             continue
@@ -446,11 +445,11 @@ class Variable_Method_Caller:
             frame = sys.exc_info()[2].tb_frame.f_back
         variable = self.variable
         while frame:
-            if frame.f_locals.has_key(variable):
+            if variable in frame.f_locals:
                 v = frame.f_locals[variable]
                 if v:
                     method = getattr(v, self.method)
-                    return apply(method, args, kw)
+                    return method(*args, **kw)
             frame = frame.f_back
         return None
 
diff --git a/src/engine/SCons/DefaultsTests.py b/src/engine/SCons/DefaultsTests.py
index 3d9c1ee7..8534cf8d 100644
--- a/src/engine/SCons/DefaultsTests.py
+++ b/src/engine/SCons/DefaultsTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import StringIO
 import sys
 import types
@@ -83,7 +82,7 @@ if __name__ == "__main__":
                ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index f840dfc3..3ebba120 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -31,6 +31,7 @@ Environment
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -40,7 +41,6 @@ import os
 import sys
 import re
 import shlex
-import string
 from UserDict import UserDict
 
 import SCons.Action
@@ -98,11 +98,11 @@ def apply_tools(env, tools, toolpath):
     if not tools:
         return
     # Filter out null tools from the list.
-    for tool in filter(None, tools):
+    for tool in [_f for _f in tools if _f]:
         if SCons.Util.is_List(tool) or type(tool)==type(()):
             toolname = tool[0]
             toolargs = tool[1] # should be a dict of kw args
-            tool = apply(env.Tool, [toolname], toolargs)
+            tool = env.Tool(toolname, **toolargs)
         else:
             env.Tool(tool)
 
@@ -173,7 +173,7 @@ def _delete_duplicates(l, keep_last):
         l.reverse()
     for i in l:
         try:
-            if not seen.has_key(i):
+            if i not in seen:
                 result.append(i)
                 seen[i]=1
         except TypeError:
@@ -221,7 +221,7 @@ class MethodWrapper:
 
     def __call__(self, *args, **kwargs):
         nargs = (self.object,) + args
-        return apply(self.method, nargs, kwargs)
+        return self.method(*nargs, **kwargs)
 
     def clone(self, new_object):
         """
@@ -257,7 +257,7 @@ class BuilderWrapper(MethodWrapper):
             target = [target]
         if source is not None and not SCons.Util.is_List(source):
             source = [source]
-        return apply(MethodWrapper.__call__, (self, target, source) + args, kw)
+        return MethodWrapper.__call__(self, target, source, *args, **kw)
 
     def __repr__(self):
         return '<BuilderWrapper %s>' % repr(self.name)
@@ -290,7 +290,7 @@ class BuilderWrapper(MethodWrapper):
     # future, so leave it for now.
     #def execute(self, **kw):
     #    kw['env'] = self.env
-    #    apply(self.builder.execute, (), kw)
+    #    self.builder.execute(**kw)
 
 class BuilderDict(UserDict):
     """This is a dictionary-like class used by an Environment to hold
@@ -430,7 +430,7 @@ class SubstitutionEnvironment:
             # key and we don't need to check.  If we do check, using a
             # global, pre-compiled regular expression directly is more
             # efficient than calling another function or a method.
-            if not self._dict.has_key(key) \
+            if key not in self._dict \
                and not _is_valid_var.match(key):
                     raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
             self._dict[key] = value
@@ -440,7 +440,7 @@ class SubstitutionEnvironment:
         return self._dict.get(key, default)
 
     def has_key(self, key):
-        return self._dict.has_key(key)
+        return key in self._dict
 
     def __contains__(self, key):
         return self._dict.__contains__(key)
@@ -471,7 +471,7 @@ class SubstitutionEnvironment:
                     if SCons.Util.is_String(n):
                         # n = self.subst(n, raw=1, **kw)
                         kw['raw'] = 1
-                        n = apply(self.subst, (n,), kw)
+                        n = self.subst(n, **kw)
                         if node_factory:
                             n = node_factory(n)
                     if SCons.Util.is_List(n):
@@ -481,7 +481,7 @@ class SubstitutionEnvironment:
                 elif node_factory:
                     # v = node_factory(self.subst(v, raw=1, **kw))
                     kw['raw'] = 1
-                    v = node_factory(apply(self.subst, (v,), kw))
+                    v = node_factory(self.subst(v, **kw))
                     if SCons.Util.is_List(v):
                         nodes.extend(v)
                     else:
@@ -566,7 +566,7 @@ class SubstitutionEnvironment:
                         # We have an object plus a string, or multiple
                         # objects that we need to smush together.  No choice
                         # but to make them into a string.
-                        p = string.join(map(SCons.Util.to_String_for_subst, p), '')
+                        p = ''.join(map(SCons.Util.to_String_for_subst, p))
             else:
                 p = s(p)
             r.append(p)
@@ -587,7 +587,7 @@ class SubstitutionEnvironment:
         if not SCons.Util.is_List(command): kw['shell'] = True
         # run constructed command
         #TODO(1.5) p = SCons.Action._subproc(self, command, **kw)
-        p = apply(SCons.Action._subproc, (self, command), kw)
+        p = SCons.Action._subproc(self, command, **kw)
         out,err = p.communicate()
         status = p.wait()
         if err:
@@ -610,8 +610,7 @@ class SubstitutionEnvironment:
         Removes the specified function's MethodWrapper from the
         added_methods list, so we don't re-bind it when making a clone.
         """
-        is_not_func = lambda dm, f=function: not dm.method is f
-        self.added_methods = filter(is_not_func, self.added_methods)
+        self.added_methods = [dm for dm in self.added_methods if not dm.method is function]
 
     def Override(self, overrides):
         """
@@ -681,11 +680,11 @@ class SubstitutionEnvironment:
 
             # utility function to deal with -D option
             def append_define(name, dict = dict):
-                t = string.split(name, '=')
+                t = name.split('=')
                 if len(t) == 1:
                     dict['CPPDEFINES'].append(name)
                 else:
-                    dict['CPPDEFINES'].append([t[0], string.join(t[1:], '=')])
+                    dict['CPPDEFINES'].append([t[0], '='.join(t[1:])])
 
             # Loop through the flags and add them to the appropriate option.
             # This tries to strike a balance between checking for all possible
@@ -807,7 +806,7 @@ class SubstitutionEnvironment:
         if not SCons.Util.is_Dict(args):
             args = self.ParseFlags(args)
         if not unique:
-            apply(self.Append, (), args)
+            self.Append(**args)
             return self
         for key, value in args.items():
             if not value:
@@ -866,9 +865,9 @@ class SubstitutionEnvironment:
 #             if not pathval:
 #                 continue
 #             if prepend:
-#                 apply(self.PrependENVPath, (pathname, pathval))
+#                 self.PrependENVPath(pathname, pathval)
 #             else:
-#                 apply(self.AppendENVPath, (pathname, pathval))
+#                 self.AppendENVPath(pathname, pathval)
 
 
 # Used by the FindSourceFiles() method, below.
@@ -979,12 +978,12 @@ class Base(SubstitutionEnvironment):
         # Apply the passed-in and customizable variables to the
         # environment before calling the tools, because they may use
         # some of them during initialization.
-        if kw.has_key('options'):
+        if 'options' in kw:
             # Backwards compatibility:  they may stll be using the
             # old "options" keyword.
             variables = kw['options']
             del kw['options']
-        apply(self.Replace, (), kw)
+        self.Replace(**kw)
         keys = kw.keys()
         if variables:
             keys = keys + variables.keys()
@@ -1100,7 +1099,7 @@ class Base(SubstitutionEnvironment):
             for scanner in scanners:
                 for k in scanner.get_skeys(self):
                     if k and self['PLATFORM'] == 'win32':
-                        k = string.lower(k)
+                        k = k.lower()
                     result[k] = scanner
 
         self._memo['_gsm'] = result
@@ -1111,7 +1110,7 @@ class Base(SubstitutionEnvironment):
         """Find the appropriate scanner given a key (usually a file suffix).
         """
         if skey and self['PLATFORM'] == 'win32':
-            skey = string.lower(skey)
+            skey = skey.lower()
         return self._gsm().get(skey)
 
     def scanner_map_delete(self, kw=None):
@@ -1240,13 +1239,13 @@ class Base(SubstitutionEnvironment):
         """
 
         orig = ''
-        if self._dict.has_key(envname) and self._dict[envname].has_key(name):
+        if envname in self._dict and name in self._dict[envname]:
             orig = self._dict[envname][name]
 
         nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing,
                                    canonicalize=self._canonicalize)
 
-        if not self._dict.has_key(envname):
+        if envname not in self._dict:
             self._dict[envname] = {}
 
         self._dict[envname][name] = nv
@@ -1261,7 +1260,7 @@ class Base(SubstitutionEnvironment):
         for key, val in kw.items():
             if SCons.Util.is_List(val):
                 val = _delete_duplicates(val, delete_existing)
-            if not self._dict.has_key(key) or self._dict[key] in ('', None):
+            if key not in self._dict or self._dict[key] in ('', None):
                 self._dict[key] = val
             elif SCons.Util.is_Dict(self._dict[key]) and \
                  SCons.Util.is_Dict(val):
@@ -1271,9 +1270,9 @@ class Base(SubstitutionEnvironment):
                 if not SCons.Util.is_List(dk):
                     dk = [dk]
                 if delete_existing:
-                    dk = filter(lambda x, val=val: x not in val, dk)
+                    dk = [x for x in dk if x not in val]
                 else:
-                    val = filter(lambda x, dk=dk: x not in dk, val)
+                    val = [x for x in val if x not in dk]
                 self._dict[key] = dk + val
             else:
                 dk = self._dict[key]
@@ -1281,14 +1280,14 @@ class Base(SubstitutionEnvironment):
                     # By elimination, val is not a list.  Since dk is a
                     # list, wrap val in a list first.
                     if delete_existing:
-                        dk = filter(lambda x, val=val: x not in val, dk)
+                        dk = [x for x in dk if x not in val]
                         self._dict[key] = dk + [val]
                     else:
                         if not val in dk:
                             self._dict[key] = dk + [val]
                 else:
                     if delete_existing:
-                        dk = filter(lambda x, val=val: x not in val, dk)
+                        dk = [x for x in dk if x not in val]
                     self._dict[key] = dk + val
         self.scanner_map_delete(kw)
 
@@ -1327,12 +1326,12 @@ class Base(SubstitutionEnvironment):
         new = {}
         for key, value in kw.items():
             new[key] = SCons.Subst.scons_subst_once(value, self, key)
-        apply(clone.Replace, (), new)
+        clone.Replace(**new)
 
         apply_tools(clone, tools, toolpath)
 
         # apply them again in case the tools overwrote them
-        apply(clone.Replace, (), new)        
+        clone.Replace(**new)        
 
         # Finally, apply any flags to be merged in
         if parse_flags: clone.MergeFlags(parse_flags)
@@ -1346,7 +1345,7 @@ class Base(SubstitutionEnvironment):
             msg = "The env.Copy() method is deprecated; use the env.Clone() method instead."
             SCons.Warnings.warn(SCons.Warnings.DeprecatedCopyWarning, msg)
             _warn_copy_deprecated = False
-        return apply(self.Clone, args, kw)
+        return self.Clone(*args, **kw)
 
     def _changed_build(self, dependency, target, prev_ni):
         if dependency.changed_state(target, prev_ni):
@@ -1416,7 +1415,7 @@ class Base(SubstitutionEnvironment):
     def Dictionary(self, *args):
         if not args:
             return self._dict
-        dlist = map(lambda x, s=self: s._dict[x], args)
+        dlist = [self._dict[x] for x in args]
         if len(dlist) == 1:
             dlist = dlist[0]
         return dlist
@@ -1472,7 +1471,7 @@ class Base(SubstitutionEnvironment):
                 return env.MergeFlags(cmd, unique)
             function = parse_conf
         if SCons.Util.is_List(command):
-            command = string.join(command)
+            command = ' '.join(command)
         command = self.subst(command)
         return function(self, self.backtick(command))
 
@@ -1494,11 +1493,11 @@ class Base(SubstitutionEnvironment):
                 raise
             return
         lines = SCons.Util.LogicalLines(fp).readlines()
-        lines = filter(lambda l: l[0] != '#', lines)
+        lines = [l for l in lines if l[0] != '#']
         tdlist = []
         for line in lines:
             try:
-                target, depends = string.split(line, ':', 1)
+                target, depends = line.split(':', 1)
             except (AttributeError, TypeError, ValueError):
                 # Python 1.5.2 throws TypeError if line isn't a string,
                 # Python 2.x throws AttributeError because it tries
@@ -1506,11 +1505,13 @@ class Base(SubstitutionEnvironment):
                 # if the line doesn't split into two or more elements.
                 pass
             else:
-                tdlist.append((string.split(target), string.split(depends)))
+                tdlist.append((target.split(), depends.split()))
         if only_one:
-            targets = reduce(lambda x, y: x+y, map(lambda p: p[0], tdlist))
+            targets = reduce(lambda x, y: x+y, [p[0] for p in tdlist])
             if len(targets) > 1:
-                raise SCons.Errors.UserError, "More than one dependency target found in `%s':  %s" % (filename, targets)
+                raise SCons.Errors.UserError(
+                            "More than one dependency target found in `%s':  %s"
+                                            % (filename, targets))
         for target, depends in tdlist:
             self.Depends(target, depends)
 
@@ -1596,13 +1597,13 @@ class Base(SubstitutionEnvironment):
         """
 
         orig = ''
-        if self._dict.has_key(envname) and self._dict[envname].has_key(name):
+        if envname in self._dict and name in self._dict[envname]:
             orig = self._dict[envname][name]
 
         nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing,
                                     canonicalize=self._canonicalize)
 
-        if not self._dict.has_key(envname):
+        if envname not in self._dict:
             self._dict[envname] = {}
 
         self._dict[envname][name] = nv
@@ -1617,7 +1618,7 @@ class Base(SubstitutionEnvironment):
         for key, val in kw.items():
             if SCons.Util.is_List(val):
                 val = _delete_duplicates(val, not delete_existing)
-            if not self._dict.has_key(key) or self._dict[key] in ('', None):
+            if key not in self._dict or self._dict[key] in ('', None):
                 self._dict[key] = val
             elif SCons.Util.is_Dict(self._dict[key]) and \
                  SCons.Util.is_Dict(val):
@@ -1627,9 +1628,9 @@ class Base(SubstitutionEnvironment):
                 if not SCons.Util.is_List(dk):
                     dk = [dk]
                 if delete_existing:
-                    dk = filter(lambda x, val=val: x not in val, dk)
+                    dk = [x for x in dk if x not in val]
                 else:
-                    val = filter(lambda x, dk=dk: x not in dk, val)
+                    val = [x for x in val if x not in dk]
                 self._dict[key] = val + dk
             else:
                 dk = self._dict[key]
@@ -1637,14 +1638,14 @@ class Base(SubstitutionEnvironment):
                     # By elimination, val is not a list.  Since dk is a
                     # list, wrap val in a list first.
                     if delete_existing:
-                        dk = filter(lambda x, val=val: x not in val, dk)
+                        dk = [x for x in dk if x not in val]
                         self._dict[key] = [val] + dk
                     else:
                         if not val in dk:
                             self._dict[key] = [val] + dk
                 else:
                     if delete_existing:
-                        dk = filter(lambda x, val=val: x not in val, dk)
+                        dk = [x for x in dk if x not in val]
                     self._dict[key] = val + dk
         self.scanner_map_delete(kw)
 
@@ -1690,9 +1691,9 @@ class Base(SubstitutionEnvironment):
 
     def SetDefault(self, **kw):
         for k in kw.keys():
-            if self._dict.has_key(k):
+            if k in self._dict:
                 del kw[k]
-        apply(self.Replace, (), kw)
+        self.Replace(**kw)
 
     def _find_toolpath_dir(self, tp):
         return self.fs.Dir(self.subst(tp)).srcnode().abspath
@@ -1702,8 +1703,8 @@ class Base(SubstitutionEnvironment):
             tool = self.subst(tool)
             if toolpath is None:
                 toolpath = self.get('toolpath', [])
-            toolpath = map(self._find_toolpath_dir, toolpath)
-            tool = apply(SCons.Tool.Tool, (tool, toolpath), kw)
+            toolpath = list(map(self._find_toolpath_dir, toolpath))
+            tool = SCons.Tool.Tool(tool, toolpath, **kw)
         tool(self)
 
     def WhereIs(self, prog, path=None, pathext=None, reject=[]):
@@ -1741,15 +1742,15 @@ class Base(SubstitutionEnvironment):
             if SCons.Util.is_String(a):
                 a = self.subst(a)
             return a
-        nargs = map(subst_string, args)
+        nargs = list(map(subst_string, args))
         nkw = self.subst_kw(kw)
-        return apply(SCons.Action.Action, nargs, nkw)
+        return SCons.Action.Action(*nargs, **nkw)
 
     def AddPreAction(self, files, action):
         nodes = self.arg2nodes(files, self.fs.Entry)
         action = SCons.Action.Action(action)
         uniq = {}
-        for executor in map(lambda n: n.get_executor(), nodes):
+        for executor in [n.get_executor() for n in nodes]:
             uniq[executor] = 1
         for executor in uniq.keys():
             executor.add_pre_action(action)
@@ -1759,7 +1760,7 @@ class Base(SubstitutionEnvironment):
         nodes = self.arg2nodes(files, self.fs.Entry)
         action = SCons.Action.Action(action)
         uniq = {}
-        for executor in map(lambda n: n.get_executor(), nodes):
+        for executor in [n.get_executor() for n in nodes]:
             uniq[executor] = 1
         for executor in uniq.keys():
             executor.add_post_action(action)
@@ -1769,7 +1770,7 @@ class Base(SubstitutionEnvironment):
         tlist = self.arg2nodes(target, self.ans.Alias)
         if not SCons.Util.is_List(source):
             source = [source]
-        source = filter(None, source)
+        source = [_f for _f in source if _f]
 
         if not action:
             if not source:
@@ -1796,7 +1797,7 @@ class Base(SubstitutionEnvironment):
             'multi'             : 1,
             'is_explicit'       : None,
         })
-        bld = apply(SCons.Builder.Builder, (), nkw)
+        bld = SCons.Builder.Builder(**nkw)
 
         # Apply the Builder separately to each target so that the Aliases
         # stay separate.  If we did one "normal" Builder call with the
@@ -1813,7 +1814,7 @@ class Base(SubstitutionEnvironment):
                 b = bld
             else:
                 nkw['action'] = b.action + action
-                b = apply(SCons.Builder.Builder, (), nkw)
+                b = SCons.Builder.Builder(**nkw)
             t.convert()
             result.extend(b(self, t, t.sources + source))
         return result
@@ -1827,14 +1828,14 @@ class Base(SubstitutionEnvironment):
         return tlist
 
     def BuildDir(self, *args, **kw):
-        if kw.has_key('build_dir'):
+        if 'build_dir' in kw:
             kw['variant_dir'] = kw['build_dir']
             del kw['build_dir']
-        return apply(self.VariantDir, args, kw)
+        return self.VariantDir(*args, **kw)
 
     def Builder(self, **kw):
         nkw = self.subst_kw(kw)
-        return apply(SCons.Builder.Builder, [], nkw)
+        return SCons.Builder.Builder(**nkw)
 
     def CacheDir(self, path):
         import SCons.CacheDir
@@ -1862,7 +1863,7 @@ class Base(SubstitutionEnvironment):
             nkw['custom_tests'] = self.subst_kw(nkw['custom_tests'])
         except KeyError:
             pass
-        return apply(SCons.SConf.SConf, nargs, nkw)
+        return SCons.SConf.SConf(*nargs, **nkw)
 
     def Command(self, target, source, action, **kw):
         """Builds the supplied target files from the supplied
@@ -1877,8 +1878,8 @@ class Base(SubstitutionEnvironment):
         try: bkw['source_scanner'] = kw['source_scanner']
         except KeyError: pass
         else: del kw['source_scanner']
-        bld = apply(SCons.Builder.Builder, (), bkw)
-        return apply(bld, (self, target, source), kw)
+        bld = SCons.Builder.Builder(**bkw)
+        return bld(self, target, source, **kw)
 
     def Depends(self, target, dependency):
         """Explicity specify that 'target's depend on 'dependency'."""
@@ -1895,9 +1896,9 @@ class Base(SubstitutionEnvironment):
         if SCons.Util.is_Sequence(s):
             result=[]
             for e in s:
-                result.append(apply(self.fs.Dir, (e,) + args, kw))
+                result.append(self.fs.Dir(e, *args, **kw))
             return result
-        return apply(self.fs.Dir, (s,) + args, kw)
+        return self.fs.Dir(s, *args, **kw)
 
     def NoClean(self, *targets):
         """Tags a target so that it will not be cleaned by -c"""
@@ -1924,17 +1925,17 @@ class Base(SubstitutionEnvironment):
         if SCons.Util.is_Sequence(s):
             result=[]
             for e in s:
-                result.append(apply(self.fs.Entry, (e,) + args, kw))
+                result.append(self.fs.Entry(e, *args, **kw))
             return result
-        return apply(self.fs.Entry, (s,) + args, kw)
+        return self.fs.Entry(s, *args, **kw)
 
     def Environment(self, **kw):
-        return apply(SCons.Environment.Environment, [], self.subst_kw(kw))
+        return SCons.Environment.Environment(**self.subst_kw(kw))
 
     def Execute(self, action, *args, **kw):
         """Directly execute an action through an Environment
         """
-        action = apply(self.Action, (action,) + args, kw)
+        action = self.Action(action, *args, **kw)
         result = action([], [], self)
         if isinstance(result, SCons.Errors.BuildError):
             errstr = result.errstr
@@ -1952,9 +1953,9 @@ class Base(SubstitutionEnvironment):
         if SCons.Util.is_Sequence(s):
             result=[]
             for e in s:
-                result.append(apply(self.fs.File, (e,) + args, kw))
+                result.append(self.fs.File(e, *args, **kw))
             return result
-        return apply(self.fs.File, (s,) + args, kw)
+        return self.fs.File(s, *args, **kw)
 
     def FindFile(self, file, dirs):
         file = self.subst(file)
@@ -1965,7 +1966,7 @@ class Base(SubstitutionEnvironment):
         return SCons.Util.flatten(sequence)
 
     def GetBuildPath(self, files):
-        result = map(str, self.arg2nodes(files, self.fs.Entry))
+        result = list(map(str, self.arg2nodes(files, self.fs.Entry)))
         if SCons.Util.is_List(files):
             return result
         else:
@@ -2007,7 +2008,7 @@ class Base(SubstitutionEnvironment):
 
     def Repository(self, *dirs, **kw):
         dirs = self.arg2nodes(list(dirs), self.fs.Dir)
-        apply(self.fs.Repository, dirs, kw)
+        self.fs.Repository(*dirs, **kw)
 
     def Requires(self, target, prerequisite):
         """Specify that 'prerequisite' must be built before 'target',
@@ -2026,7 +2027,7 @@ class Base(SubstitutionEnvironment):
                 arg = self.subst(arg)
             nargs.append(arg)
         nkw = self.subst_kw(kw)
-        return apply(SCons.Scanner.Base, nargs, nkw)
+        return SCons.Scanner.Base(*nargs, **nkw)
 
     def SConsignFile(self, name=".sconsign", dbm_module=None):
         if name is not None:
@@ -2093,9 +2094,9 @@ class Base(SubstitutionEnvironment):
               in the list are not split at spaces.
         In all cases, the function returns a list of Nodes and strings."""
         if SCons.Util.is_List(arg):
-            return map(self.subst, arg)
+            return list(map(self.subst, arg))
         elif SCons.Util.is_String(arg):
-            return string.split(self.subst(arg))
+            return self.subst(arg).split()
         else:
             return [self.subst(arg)]
 
@@ -2235,7 +2236,7 @@ class OverrideEnvironment(Base):
             self.__dict__['overrides'][key]
             return 1
         except KeyError:
-            return self.__dict__['__subject'].has_key(key)
+            return key in self.__dict__['__subject']
     def __contains__(self, key):
         if self.__dict__['overrides'].__contains__(key):
             return 1
@@ -2314,13 +2315,13 @@ def NoSubstitutionProxy(subject):
             nkw = kwargs.copy()
             nkw['gvars'] = {}
             self.raw_to_mode(nkw)
-            return apply(SCons.Subst.scons_subst_list, nargs, nkw)
+            return SCons.Subst.scons_subst_list(*nargs, **nkw)
         def subst_target_source(self, string, *args, **kwargs):
             nargs = (string, self,) + args
             nkw = kwargs.copy()
             nkw['gvars'] = {}
             self.raw_to_mode(nkw)
-            return apply(SCons.Subst.scons_subst, nargs, nkw)
+            return SCons.Subst.scons_subst(*nargs, **nkw)
     return _NoSubstitutionProxy(subject)
 
 # Local Variables:
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index aa80952e..7d3d33ea 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import copy
 import os
-import string
 import StringIO
 import sys
 import TestCmd
@@ -44,14 +43,14 @@ def diff_env(env1, env2):
     keys = d.keys()
     keys.sort()
     for k in keys:
-        if env1.has_key(k):
-           if env2.has_key(k):
+        if k in env1:
+           if k in env2:
                if env1[k] != env2[k]:
                    s1 = s1 + "    " + repr(k) + " : " + repr(env1[k]) + "\n"
                    s2 = s2 + "    " + repr(k) + " : " + repr(env2[k]) + "\n"
            else:
                s1 = s1 + "    " + repr(k) + " : " + repr(env1[k]) + "\n"
-        elif env2.has_key(k):
+        elif k in env2:
            s2 = s2 + "    " + repr(k) + " : " + repr(env2[k]) + "\n"
     s1 = s1 + "}\n"
     s2 = s2 + "}\n"
@@ -66,14 +65,14 @@ def diff_dict(d1, d2):
     keys = d.keys()
     keys.sort()
     for k in keys:
-        if d1.has_key(k):
-           if d2.has_key(k):
+        if k in d1:
+           if k in d2:
                if d1[k] != d2[k]:
                    s1 = s1 + "    " + repr(k) + " : " + repr(d1[k]) + "\n"
                    s2 = s2 + "    " + repr(k) + " : " + repr(d2[k]) + "\n"
            else:
                s1 = s1 + "    " + repr(k) + " : " + repr(d1[k]) + "\n"
-        elif env2.has_key(k):
+        elif k in env2:
            s2 = s2 + "    " + repr(k) + " : " + repr(d2[k]) + "\n"
     s1 = s1 + "}\n"
     s2 = s2 + "}\n"
@@ -132,7 +131,7 @@ class Scanner:
 class CLVar(UserList.UserList):
     def __init__(self, seq):
         if type(seq) == type(''):
-            seq = string.split(seq)
+            seq = seq.split()
         UserList.UserList.__init__(self, seq)
     def __add__(self, other):
         return UserList.UserList.__add__(self, CLVar(other))
@@ -158,15 +157,15 @@ def test_tool( env ):
 
 class TestEnvironmentFixture:
     def TestEnvironment(self, *args, **kw):
-        if not kw or not kw.has_key('tools'):
+        if not kw or 'tools' not in kw:
             kw['tools'] = [test_tool]
         default_keys = { 'CC' : 'cc',
                          'CCFLAGS' : '-DNDEBUG',
                          'ENV' : { 'TMP' : '/tmp' } }
         for key, value in default_keys.items():
-            if not kw.has_key(key):
+            if key not in kw:
                 kw[key] = value
-        if not kw.has_key('BUILDERS'):
+        if 'BUILDERS' not in kw:
             static_obj = SCons.Builder.Builder(action = {},
                                                emitter = {},
                                                suffix = '.o',
@@ -174,7 +173,7 @@ class TestEnvironmentFixture:
             kw['BUILDERS'] = {'Object' : static_obj}
             static_obj.add_action('.cpp', 'fake action')
             
-        env = apply(Environment, args, kw)
+        env = Environment(*args, **kw)
         return env
 
 class SubstitutionTestCase(unittest.TestCase):
@@ -183,7 +182,7 @@ class SubstitutionTestCase(unittest.TestCase):
         """Test initializing a SubstitutionEnvironment
         """
         env = SubstitutionEnvironment()
-        assert not env.has_key('__env__')
+        assert '__env__' not in env
 
     def test___cmp__(self):
         """Test comparing SubstitutionEnvironments
@@ -231,8 +230,8 @@ class SubstitutionTestCase(unittest.TestCase):
         """Test the SubstitutionEnvironment has_key() method
         """
         env = SubstitutionEnvironment(XXX = 'x')
-        assert env.has_key('XXX')
-        assert not env.has_key('YYY')
+        assert 'XXX' in env
+        assert 'YYY' not in env
 
     def test_contains(self):
         """Test the SubstitutionEnvironment __contains__() method
@@ -264,7 +263,7 @@ class SubstitutionTestCase(unittest.TestCase):
         class X(SCons.Node.Node):
             pass
         def Factory(name, directory = None, create = 1, dict=dict, X=X):
-            if not dict.has_key(name):
+            if name not in dict:
                 dict[name] = X()
                 dict[name].name = name
             return dict[name]
@@ -390,7 +389,7 @@ class SubstitutionTestCase(unittest.TestCase):
                               DummyNode,
                               target=targets,
                               source=sources)
-        names = map(lambda n: n.name, nodes)
+        names = [n.name for n in nodes]
         assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names
 
     def test_gvars(self):
@@ -577,16 +576,16 @@ class SubstitutionTestCase(unittest.TestCase):
         assert r == ['foo', 'xxx', 'bar'], r
 
         r = env.subst_path(['$FOO', '$LIST', '$BAR'])
-        assert map(str, r) == ['foo', 'one two', 'bar'], r
+        assert list(map(str, r)) == ['foo', 'one two', 'bar'], r
 
         r = env.subst_path(['$FOO', '$TARGET', '$SOURCE', '$BAR'])
         assert r == ['foo', '', '', 'bar'], r
 
         r = env.subst_path(['$FOO', '$TARGET', '$BAR'], target=MyNode('ttt'))
-        assert map(str, r) == ['foo', 'ttt', 'bar'], r
+        assert list(map(str, r)) == ['foo', 'ttt', 'bar'], r
 
         r = env.subst_path(['$FOO', '$SOURCE', '$BAR'], source=MyNode('sss'))
-        assert map(str, r) == ['foo', 'sss', 'bar'], r
+        assert list(map(str, r)) == ['foo', 'sss', 'bar'], r
 
         n = MyObj()
 
@@ -830,7 +829,7 @@ sys.exit(0)
         assert d['LIBPATH'] == ['/usr/fax',
                                 'foo',
                                 'C:\\Program Files\\ASCEND'], d['LIBPATH']
-        LIBS = map(str, d['LIBS'])
+        LIBS = list(map(str, d['LIBS']))
         assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS)
         assert d['LINKFLAGS'] == ['-Wl,-link', '-pthread',
                                   '-mno-cygwin', '-mwindows',
@@ -845,7 +844,7 @@ sys.exit(0)
         """
         env = SubstitutionEnvironment()
         env.MergeFlags('')
-        assert not env.has_key('CCFLAGS'), env['CCFLAGS']
+        assert 'CCFLAGS' not in env, env['CCFLAGS']
         env.MergeFlags('-X')
         assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
         env.MergeFlags('-X')
@@ -909,8 +908,8 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture):
         env2 = self.TestEnvironment(XXX = 'x', YYY = 'y')
         assert env1 == env2, diff_env(env1, env2)
 
-        assert not env1.has_key('__env__')
-        assert not env2.has_key('__env__')
+        assert '__env__' not in env1
+        assert '__env__' not in env2
 
     def test_variables(self):
         """Test that variables only get applied once."""
@@ -1088,69 +1087,69 @@ env4.builder1.env, env3)
         env = Environment()
         try: del env['SCANNERS']
         except KeyError: pass
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [None, None, None, None, None], s
 
         env = self.TestEnvironment(SCANNERS = [])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [None, None, None, None, None], s
 
         env.Replace(SCANNERS = [s1])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, None, None], s
 
         env.Append(SCANNERS = [s2])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, s2, None], s
 
         env.AppendUnique(SCANNERS = [s3])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, s2, s3], s
 
         env = env.Clone(SCANNERS = [s2])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [None, None, None, s2, None], s
 
         env['SCANNERS'] = [s1]
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, None, None], s
 
         env.PrependUnique(SCANNERS = [s2, s1])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, s2, None], s
 
         env.Prepend(SCANNERS = [s3])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, s3, s3], s
 
         # Verify behavior of case-insensitive suffix matches on Windows.
-        uc_suffixes = map(string.upper, suffixes)
+        uc_suffixes = [_.upper() for _ in suffixes]
 
         env = Environment(SCANNERS = [s1, s2, s3],
                           PLATFORM = 'linux')
 
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [s1, s1, None, s2, s3], s
 
-        s = map(env.get_scanner, uc_suffixes)
+        s = list(map(env.get_scanner, uc_suffixes))
         assert s == [None, None, None, None, None], s
 
         env['PLATFORM'] = 'win32'
 
-        s = map(env.get_scanner, uc_suffixes)
+        s = list(map(env.get_scanner, uc_suffixes))
         assert s == [s1, s1, None, s2, s3], s
 
         # Verify behavior for a scanner returning None (on Windows
         # where we might try to perform case manipulation on None).
         env.Replace(SCANNERS = [s4])
-        s = map(env.get_scanner, suffixes)
+        s = list(map(env.get_scanner, suffixes))
         assert s == [None, None, None, None, None], s
 
     def test_ENV(self):
         """Test setting the external ENV in Environments
         """
         env = Environment()
-        assert env.Dictionary().has_key('ENV')
+        assert 'ENV' in env.Dictionary()
 
         env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' })
         assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
@@ -1182,7 +1181,7 @@ env4.builder1.env, env3)
                 except warning:
                     exc_caught = 1
                 assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
-                assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
+                assert kw not in env4, "`%s' variable was incorrectly set" % kw
         finally:
             SCons.Warnings.warningAsException(old)
 
@@ -1204,7 +1203,7 @@ env4.builder1.env, env3)
                 except warning:
                     exc_caught = 1
                 assert exc_caught, "Did not catch FutureReservedVariableWarning for `%s'" % kw
-                assert env4.has_key(kw), "`%s' variable was not set" % kw
+                assert kw in env4, "`%s' variable was not set" % kw
         finally:
             SCons.Warnings.warningAsException(old)
 
@@ -1233,7 +1232,7 @@ env4.builder1.env, env3)
                 path = drive + path
             path = os.path.normpath(path)
             drive, path = os.path.splitdrive(path)
-            return string.lower(drive) + path
+            return drive.lower() + path
 
         env = dict.TestEnvironment(LIBS = [ 'foo', 'bar', 'baz' ],
                           LIBLINKPREFIX = 'foo',
@@ -1310,7 +1309,7 @@ env4.builder1.env, env3)
             if arg not in ('$(','$)','-I'):
                 return np(str(arg))
             return arg
-        flags = map(normalize_if_path, flags)
+        flags = list(map(normalize_if_path, flags))
         assert flags == expect, flags
 
     def test_platform(self):
@@ -1776,8 +1775,8 @@ def exists(env):
         assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
         assert 4 in env2.Dictionary('YYY')
         assert not 4 in env1.Dictionary('YYY')
-        assert env2.Dictionary('ZZZ').has_key(5)
-        assert not env1.Dictionary('ZZZ').has_key(5)
+        assert 5 in env2.Dictionary('ZZZ')
+        assert 5 not in env1.Dictionary('ZZZ')
 
         #
         env1 = self.TestEnvironment(BUILDERS = {'b1' : Builder()})
@@ -1953,16 +1952,16 @@ def generate(env):
         xxx, zzz = env.Dictionary('XXX', 'ZZZ')
         assert xxx == 'x'
         assert zzz == 'z'
-        assert env.Dictionary().has_key('BUILDERS')
-        assert env.Dictionary().has_key('CC')
-        assert env.Dictionary().has_key('CCFLAGS')
-        assert env.Dictionary().has_key('ENV')
+        assert 'BUILDERS' in env.Dictionary()
+        assert 'CC' in env.Dictionary()
+        assert 'CCFLAGS' in env.Dictionary()
+        assert 'ENV' in env.Dictionary()
 
         assert env['XXX'] == 'x'
         env['XXX'] = 'foo'
         assert env.Dictionary('XXX') == 'foo'
         del env['XXX']
-        assert not env.Dictionary().has_key('XXX')
+        assert 'XXX' not in env.Dictionary()
 
     def test_FindIxes(self):
         "Test FindIxes()"
@@ -2105,8 +2104,8 @@ f5: \
         del dlist[:]
 
         env.ParseDepends('$SINGLE', only_one=1)
-        t = map(str, tlist)
-        d = map(str, dlist)
+        t = list(map(str, tlist))
+        d = list(map(str, dlist))
         assert t == ['f0'], t
         assert d == ['d1', 'd2', 'd3'], d
 
@@ -2114,8 +2113,8 @@ f5: \
         del dlist[:]
 
         env.ParseDepends(test.workpath('multiple'))
-        t = map(str, tlist)
-        d = map(str, dlist)
+        t = list(map(str, tlist))
+        d = list(map(str, dlist))
         assert t == ['f1', 'f2', 'f3', 'f4', 'f5'], t
         assert d == ['foo', 'bar', 'abc', 'def', 'ghi', 'jkl', 'mno'], d
 
@@ -2519,21 +2518,21 @@ def generate(env):
                           test.workpath('sub2'),
                           test.workpath('sub3'),
                           test.workpath('sub4'),
-                        ] + string.split(env_path, os.pathsep)
+                        ] + env_path.split(os.pathsep)
 
         pathdirs_1243 = [ test.workpath('sub1'),
                           test.workpath('sub2'),
                           test.workpath('sub4'),
                           test.workpath('sub3'),
-                        ] + string.split(env_path, os.pathsep)
+                        ] + env_path.split(os.pathsep)
 
-        path = string.join(pathdirs_1234, os.pathsep)
+        path = os.pathsep.join(pathdirs_1234)
         env = self.TestEnvironment(ENV = {'PATH' : path})
         wi = env.WhereIs('xxx.exe')
         assert wi == test.workpath(sub3_xxx_exe), wi
         wi = env.WhereIs('xxx.exe', pathdirs_1243)
         assert wi == test.workpath(sub4_xxx_exe), wi
-        wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
+        wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
         assert wi == test.workpath(sub4_xxx_exe), wi
 
         wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
@@ -2541,13 +2540,13 @@ def generate(env):
         wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
         assert wi == test.workpath(sub4_xxx_exe), wi
 
-        path = string.join(pathdirs_1243, os.pathsep)
+        path = os.pathsep.join(pathdirs_1243)
         env = self.TestEnvironment(ENV = {'PATH' : path})
         wi = env.WhereIs('xxx.exe')
         assert wi == test.workpath(sub4_xxx_exe), wi
         wi = env.WhereIs('xxx.exe', pathdirs_1234)
         assert wi == test.workpath(sub3_xxx_exe), wi
-        wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
+        wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
         assert wi == test.workpath(sub3_xxx_exe), wi
 
         if sys.platform == 'win32':
@@ -2558,13 +2557,13 @@ def generate(env):
             assert wi == test.workpath(sub4_xxx_exe), wi
 
             wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
-            assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+            assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
 
             # Test that we return a normalized path even when
             # the path contains forward slashes.
             forward_slash = test.workpath('') + '/sub3'
             wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
-            assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+            assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
 
 
 
@@ -2637,37 +2636,37 @@ def generate(env):
 
         tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
         assert str(tgt) == 'export_alias', tgt
-        assert len(tgt.sources) == 2, map(str, tgt.sources)
-        assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
-        assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
+        assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+        assert str(tgt.sources[0]) == 'asrc1', list(map(str, tgt.sources))
+        assert str(tgt.sources[1]) == 'kkk', list(map(str, tgt.sources))
 
         n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
         assert n is tgt, n
-        assert len(tgt.sources) == 4, map(str, tgt.sources)
-        assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
-        assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
+        assert len(tgt.sources) == 4, list(map(str, tgt.sources))
+        assert str(tgt.sources[2]) == 'lll', list(map(str, tgt.sources))
+        assert str(tgt.sources[3]) == 'asrc4', list(map(str, tgt.sources))
 
         n = env.Alias('$EA', 'asrc5')[0]
         assert n is tgt, n
-        assert len(tgt.sources) == 5, map(str, tgt.sources)
-        assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
+        assert len(tgt.sources) == 5, list(map(str, tgt.sources))
+        assert str(tgt.sources[4]) == 'asrc5', list(map(str, tgt.sources))
 
         t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
         assert str(t1) == 't1', t1
         assert str(t2) == 't2', t2
-        assert len(t1.sources) == 2, map(str, t1.sources)
-        assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
-        assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
-        assert len(t2.sources) == 2, map(str, t2.sources)
-        assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
-        assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
+        assert len(t1.sources) == 2, list(map(str, t1.sources))
+        assert str(t1.sources[0]) == 'asrc6', list(map(str, t1.sources))
+        assert str(t1.sources[1]) == 'asrc7', list(map(str, t1.sources))
+        assert len(t2.sources) == 2, list(map(str, t2.sources))
+        assert str(t2.sources[0]) == 'asrc6', list(map(str, t2.sources))
+        assert str(t2.sources[1]) == 'asrc7', list(map(str, t2.sources))
 
         tgt = env.Alias('add', 's1')
         tgt = env.Alias('add', 's2')[0]
-        s = map(str, tgt.sources)
+        s = list(map(str, tgt.sources))
         assert s == ['s1', 's2'], s
         tgt = env.Alias(tgt, 's3')[0]
-        s = map(str, tgt.sources)
+        s = list(map(str, tgt.sources))
         assert s == ['s1', 's2', 's3'], s
 
         tgt = env.Alias('act', None, "action1")[0]
@@ -2770,20 +2769,20 @@ def generate(env):
         fff = env.arg2nodes('fff')[0]
 
         t = env.Clean('foo', 'aaa')
-        l = map(str, CT[foo])
+        l = list(map(str, CT[foo]))
         assert l == ['aaa'], l
 
         t = env.Clean(foo, ['$BAR', 'ccc'])
-        l = map(str, CT[foo])
+        l = list(map(str, CT[foo]))
         assert l == ['aaa', 'bbb', 'ccc'], l
 
         eee = env.arg2nodes('eee')[0]
 
         t = env.Clean('$FOO', 'ddd')
-        l = map(str, CT[fff])
+        l = list(map(str, CT[fff]))
         assert l == ['ddd'], l
         t = env.Clean(fff, [eee, 'fff'])
-        l = map(str, CT[fff])
+        l = list(map(str, CT[fff]))
         assert l == ['ddd', 'eee', 'fff'], l
 
     def test_Command(self):
@@ -2794,25 +2793,25 @@ def generate(env):
         assert t.builder is not None
         assert t.builder.action.__class__.__name__ == 'CommandAction'
         assert t.builder.action.cmd_list == 'buildfoo $target $source'
-        assert 'foo1.in' in map(lambda x: x.path, t.sources)
-        assert 'foo2.in' in map(lambda x: x.path, t.sources)
+        assert 'foo1.in' in [x.path for x in t.sources]
+        assert 'foo2.in' in [x.path for x in t.sources]
 
         sub = env.fs.Dir('sub')
         t = env.Command(target='bar.out', source='sub',
                         action='buildbar $target $source')[0]
-        assert 'sub' in map(lambda x: x.path, t.sources)
+        assert 'sub' in [x.path for x in t.sources]
 
         def testFunc(env, target, source):
             assert str(target[0]) == 'foo.out'
-            assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
+            assert 'foo1.in' in list(map(str, source)) and 'foo2.in' in list(map(str, source)), list(map(str, source))
             return 0
         t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
                         action=testFunc)[0]
         assert t.builder is not None
         assert t.builder.action.__class__.__name__ == 'FunctionAction'
         t.build()
-        assert 'foo1.in' in map(lambda x: x.path, t.sources)
-        assert 'foo2.in' in map(lambda x: x.path, t.sources)
+        assert 'foo1.in' in [x.path for x in t.sources]
+        assert 'foo2.in' in [x.path for x in t.sources]
 
         x = []
         def test2(baz, x=x):
@@ -2829,7 +2828,7 @@ def generate(env):
                         action = 'foo',
                         X = 'xxx')[0]
         assert str(t) == 'xxx.out', str(t)
-        assert 'xxx.in' in map(lambda x: x.path, t.sources)
+        assert 'xxx.in' in [x.path for x in t.sources]
 
         env = self.TestEnvironment(source_scanner = 'should_not_find_this')
         t = env.Command(target='file.out', source='file.in',
@@ -3422,9 +3421,9 @@ def generate(env):
         bad_msg = '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'
         added.append('INIT')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         env.Append(TARGETS = 'targets',
                    SOURCES = 'sources',
@@ -3437,9 +3436,9 @@ def generate(env):
                    APPEND = 'append')
         added.append('APPEND')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         env.AppendUnique(TARGETS = 'targets',
                          SOURCES = 'sources',
@@ -3452,9 +3451,9 @@ def generate(env):
                          APPENDUNIQUE = 'appendunique')
         added.append('APPENDUNIQUE')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         env.Prepend(TARGETS = 'targets',
                     SOURCES = 'sources',
@@ -3467,9 +3466,9 @@ def generate(env):
                     PREPEND = 'prepend')
         added.append('PREPEND')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         env.Prepend(TARGETS = 'targets',
                     SOURCES = 'sources',
@@ -3482,9 +3481,9 @@ def generate(env):
                     PREPENDUNIQUE = 'prependunique')
         added.append('PREPENDUNIQUE')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         env.Replace(TARGETS = 'targets',
                     SOURCES = 'sources',
@@ -3497,9 +3496,9 @@ def generate(env):
                     REPLACE = 'replace')
         added.append('REPLACE')
         for x in self.reserved_variables:
-            assert not env.has_key(x), env[x]
+            assert x not in env, env[x]
         for x in added:
-            assert env.has_key(x), bad_msg % x
+            assert x in env, bad_msg % x
 
         copy = env.Clone(TARGETS = 'targets',
                          SOURCES = 'sources',
@@ -3511,9 +3510,9 @@ def generate(env):
                          UNCHANGED_TARGETS = 'unchanged_targets',
                          COPY = 'copy')
         for x in self.reserved_variables:
-            assert not copy.has_key(x), env[x]
+            assert x not in copy, env[x]
         for x in added + ['COPY']:
-            assert copy.has_key(x), bad_msg % x
+            assert x in copy, bad_msg % x
 
         over = env.Override({'TARGETS' : 'targets',
                              'SOURCES' : 'sources',
@@ -3525,9 +3524,9 @@ def generate(env):
                              'UNCHANGED_TARGETS' : 'unchanged_targets',
                              'OVERRIDE' : 'override'})
         for x in self.reserved_variables:
-            assert not over.has_key(x), over[x]
+            assert x not in over, over[x]
         for x in added + ['OVERRIDE']:
-            assert over.has_key(x), bad_msg % x
+            assert x in over, bad_msg % x
 
     def test_parse_flags(self):
         '''Test the Base class parse_flags argument'''
@@ -3548,7 +3547,7 @@ def generate(env):
         # all we have to show is that it gets to MergeFlags internally
         env = Environment(tools = [])
         env2 = env.Clone(parse_flags = '-X')
-        assert not env.has_key('CCFLAGS')
+        assert 'CCFLAGS' not in env
         assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
 
         env = Environment(tools = [], CCFLAGS=None)
@@ -3558,9 +3557,9 @@ def generate(env):
 
         env = Environment(tools = [], CPPDEFINES = 'FOO')
         env2 = env.Clone(parse_flags = '-std=c99 -X -DBAR')
-        assert not env.has_key('CFLAGS')
+        assert 'CFLAGS' not in env
         assert env2['CFLAGS']  == ['-std=c99'], env2['CFLAGS']
-        assert not env.has_key('CCFLAGS')
+        assert 'CCFLAGS' not in env
         assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
         assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
         assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
@@ -3594,19 +3593,19 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
         env, env2, env3 = self.envs
 
         del env3['XXX']
-        assert not env.has_key('XXX'), "env has XXX?"
-        assert not env2.has_key('XXX'), "env2 has XXX?"
-        assert not env3.has_key('XXX'), "env3 has XXX?"
+        assert 'XXX' not in env, "env has XXX?"
+        assert 'XXX' not in env2, "env2 has XXX?"
+        assert 'XXX' not in env3, "env3 has XXX?"
 
         del env3['YYY']
-        assert not env.has_key('YYY'), "env has YYY?"
-        assert not env2.has_key('YYY'), "env2 has YYY?"
-        assert not env3.has_key('YYY'), "env3 has YYY?"
+        assert 'YYY' not in env, "env has YYY?"
+        assert 'YYY' not in env2, "env2 has YYY?"
+        assert 'YYY' not in env3, "env3 has YYY?"
 
         del env3['ZZZ']
-        assert not env.has_key('ZZZ'), "env has ZZZ?"
-        assert not env2.has_key('ZZZ'), "env2 has ZZZ?"
-        assert not env3.has_key('ZZZ'), "env3 has ZZZ?"
+        assert 'ZZZ' not in env, "env has ZZZ?"
+        assert 'ZZZ' not in env2, "env2 has ZZZ?"
+        assert 'ZZZ' not in env3, "env3 has ZZZ?"
 
     def test_get(self):
         """Test the OverrideEnvironment get() method"""
@@ -3624,15 +3623,15 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
     def test_has_key(self):
         """Test the OverrideEnvironment has_key() method"""
         env, env2, env3 = self.envs
-        assert env.has_key('XXX'), env.has_key('XXX')
-        assert env2.has_key('XXX'), env2.has_key('XXX')
-        assert env3.has_key('XXX'), env3.has_key('XXX')
-        assert env.has_key('YYY'), env.has_key('YYY')
-        assert env2.has_key('YYY'), env2.has_key('YYY')
-        assert env3.has_key('YYY'), env3.has_key('YYY')
-        assert not env.has_key('ZZZ'), env.has_key('ZZZ')
-        assert not env2.has_key('ZZZ'), env2.has_key('ZZZ')
-        assert env3.has_key('ZZZ'), env3.has_key('ZZZ')
+        assert 'XXX' in env, 'XXX' in env
+        assert 'XXX' in env2, 'XXX' in env2
+        assert 'XXX' in env3, 'XXX' in env3
+        assert 'YYY' in env, 'YYY' in env
+        assert 'YYY' in env2, 'YYY' in env2
+        assert 'YYY' in env3, 'YYY' in env3
+        assert 'ZZZ' not in env, 'ZZZ' in env
+        assert 'ZZZ' not in env2, 'ZZZ' in env2
+        assert 'ZZZ' in env3, 'ZZZ' in env3
 
     def test_contains(self):
         """Test the OverrideEnvironment __contains__() method"""
@@ -3819,7 +3818,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
         # all we have to show is that it gets to MergeFlags internally
         env = SubstitutionEnvironment()
         env2 = env.Override({'parse_flags' : '-X'})
-        assert not env.has_key('CCFLAGS')
+        assert 'CCFLAGS' not in env
         assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
 
         env = SubstitutionEnvironment(CCFLAGS=None)
@@ -3829,9 +3828,9 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
 
         env = SubstitutionEnvironment(CPPDEFINES = 'FOO')
         env2 = env.Override({'parse_flags' : '-std=c99 -X -DBAR'})
-        assert not env.has_key('CFLAGS')
+        assert 'CFLAGS' not in env
         assert env2['CFLAGS']  == ['-std=c99'], env2['CFLAGS']
-        assert not env.has_key('CCFLAGS')
+        assert 'CCFLAGS' not in env
         assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
         assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
         assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
@@ -3933,9 +3932,9 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture):
 
         args = ('$XXX $TARGET $SOURCE $YYY',)
         kw = {'target' : DummyNode('ttt'), 'source' : DummyNode('sss')}
-        x = apply(env.subst_target_source, args, kw)
+        x = env.subst_target_source(*args, **kw)
         assert x == 'x ttt sss y', x
-        x = apply(proxy.subst_target_source, args, kw)
+        x = proxy.subst_target_source(*args, **kw)
         assert x == ' ttt sss ', x
 
 class EnvironmentVariableTestCase(unittest.TestCase):
@@ -3982,7 +3981,7 @@ if __name__ == "__main__":
                  EnvironmentVariableTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py
index 562cbcf9..813e08c5 100644
--- a/src/engine/SCons/Errors.py
+++ b/src/engine/SCons/Errors.py
@@ -133,7 +133,7 @@ class ExplicitExit(Exception):
         self.node = node
         self.status = status
         self.exitstatus = status
-        apply(Exception.__init__, (self,) + args)
+        Exception.__init__(self, *args)
 
 def convert_to_BuildError(status, exc_info=None):
     """
diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py
index 4da42d5a..aaf71b8d 100644
--- a/src/engine/SCons/Executor.py
+++ b/src/engine/SCons/Executor.py
@@ -27,10 +27,10 @@ Nodes.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import UserList
 
 from SCons.Debug import logInstanceCreation
@@ -161,10 +161,10 @@ class Executor:
         ut = []
         for b in self.batches:
             if b.targets[0].is_up_to_date():
-                us.extend(map(rfile, b.sources))
+                us.extend(list(map(rfile, b.sources)))
                 ut.extend(b.targets)
             else:
-                cs.extend(map(rfile, b.sources))
+                cs.extend(list(map(rfile, b.sources)))
                 ct.extend(b.targets)
         self._changed_sources_list = SCons.Util.NodeList(cs)
         self._changed_targets_list = SCons.Util.NodeList(ct)
@@ -190,14 +190,14 @@ class Executor:
         return rfile(self.batches[0].sources[0]).get_subst_proxy()
 
     def _get_sources(self, *args, **kw):
-        return SCons.Util.NodeList(map(lambda n: rfile(n).get_subst_proxy(), self.get_all_sources()))
+        return SCons.Util.NodeList([rfile(n).get_subst_proxy() for n in self.get_all_sources()])
 
     def _get_target(self, *args, **kw):
         #return SCons.Util.NodeList([self.batches[0].targets[0].get_subst_proxy()])
         return self.batches[0].targets[0].get_subst_proxy()
 
     def _get_targets(self, *args, **kw):
-        return SCons.Util.NodeList(map(lambda n: n.get_subst_proxy(), self.get_all_targets()))
+        return SCons.Util.NodeList([n.get_subst_proxy() for n in self.get_all_targets()])
 
     def _get_unchanged_sources(self, *args, **kw):
         try:
@@ -342,7 +342,7 @@ class Executor:
         for act in self.get_action_list():
             #args = (self.get_all_targets(), self.get_all_sources(), env)
             args = ([], [], env)
-            status = apply(act, args, kw)
+            status = act(*args, **kw)
             if isinstance(status, SCons.Errors.BuildError):
                 status.executor = self
                 raise status
@@ -372,7 +372,7 @@ class Executor:
         # TODO(batch):  extend to multiple batches
         assert (len(self.batches) == 1)
         # TODO(batch):  remove duplicates?
-        sources = filter(lambda x, s=self.batches[0].sources: x not in s, sources)
+        sources = [x for x in sources if x not in self.batches[0].sources]
         self.batches[0].sources.extend(sources)
 
     def get_sources(self):
@@ -406,9 +406,10 @@ class Executor:
 
     def my_str(self):
         env = self.get_build_env()
-        get = lambda action, t=self.get_all_targets(), s=self.get_all_sources(), e=env: \
-                     action.genstring(t, s, e)
-        return string.join(map(get, self.get_action_list()), "\n")
+        return "\n".join([action.genstring(self.get_all_targets(),
+                                           self.get_all_sources(),
+                                           env)
+                          for action in self.get_action_list()])
 
 
     def __str__(self):
@@ -417,7 +418,7 @@ class Executor:
     def nullify(self):
         self.cleanup()
         self.do_execute = self.do_nothing
-        self.my_str     = lambda S=self: ''
+        self.my_str     = lambda: ''
 
     memoizer_counters.append(SCons.Memoize.CountValue('get_contents'))
 
@@ -431,9 +432,10 @@ class Executor:
         except KeyError:
             pass
         env = self.get_build_env()
-        get = lambda action, t=self.get_all_targets(), s=self.get_all_sources(), e=env: \
-                     action.get_contents(t, s, e)
-        result = string.join(map(get, self.get_action_list()), "")
+        result = "".join([action.get_contents(self.get_all_targets(),
+                                              self.get_all_sources(),
+                                              env)
+                          for action in self.get_action_list()])
         self._memo['get_contents'] = result
         return result
 
@@ -521,7 +523,7 @@ class Executor:
             idict = {}
             for i in ignore:
                 idict[i] = 1
-            sourcelist = filter(lambda s, i=idict: not i.has_key(s), sourcelist)
+            sourcelist = [s for s in sourcelist if s not in idict]
 
         memo_dict[key] = sourcelist
 
@@ -547,7 +549,7 @@ def GetBatchExecutor(key):
     return _batch_executors[key]
 
 def AddBatchExecutor(key, executor):
-    assert not _batch_executors.has_key(key)
+    assert key not in _batch_executors
     _batch_executors[key] = executor
 
 nullenv = None
diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py
index 205553a8..aaafa070 100644
--- a/src/engine/SCons/ExecutorTests.py
+++ b/src/engine/SCons/ExecutorTests.py
@@ -23,7 +23,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import sys
 import unittest
 
@@ -39,7 +38,7 @@ class MyEnvironment:
     def Override(self, overrides):
         d = self._dict.copy()
         d.update(overrides)
-        return apply(MyEnvironment, (), d)
+        return MyEnvironment(**d)
     def _update(self, dict):
         self._dict.update(dict)
 
@@ -48,11 +47,11 @@ class MyAction:
         self.actions = actions
     def __call__(self, target, source, env, **kw):
         for action in self.actions:
-            apply(action, (target, source, env), kw)
+            action(target, source, env, **kw)
     def genstring(self, target, source, env):
-        return string.join(['GENSTRING'] + map(str, self.actions) + target + source)
+        return ' '.join(['GENSTRING'] + list(map(str, self.actions)) + target + source)
     def get_contents(self, target, source, env):
-        return string.join(self.actions + target + source)
+        return ' '.join(self.actions + target + source)
     def get_implicit_deps(self, target, source, env):
         return []
 
@@ -79,7 +78,7 @@ class MyNode:
                                            [],
                                            [self],
                                            ['s1', 's2'])
-        apply(executor, (self), {})
+        executor(self)
     def get_env_scanner(self, env, kw):
         return MyScanner('dep-')
     def get_implicit_deps(self, env, scanner, path):
@@ -184,8 +183,8 @@ class ExecutorTestCase(unittest.TestCase):
 
         class LocalScanner:
             def path(self, env, dir, target, source):
-                target = map(str, target)
-                source = map(str, source)
+                target = list(map(str, target))
+                source = list(map(str, source))
                 return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source)
         s = LocalScanner()
 
@@ -440,13 +439,13 @@ class ExecutorTestCase(unittest.TestCase):
         x = SCons.Executor.Executor('b', env, [{}], [], [s1, s2, s3])
 
         r = x.get_unignored_sources(None, [])
-        assert r == [s1, s2, s3], map(str, r)
+        assert r == [s1, s2, s3], list(map(str, r))
 
         r = x.get_unignored_sources(None, [s2])
-        assert r == [s1, s3], map(str, r)
+        assert r == [s1, s3], list(map(str, r))
 
         r = x.get_unignored_sources(None, [s1, s3])
-        assert r == [s2], map(str, r)
+        assert r == [s2], list(map(str, r))
 
 
 
@@ -455,7 +454,7 @@ if __name__ == "__main__":
     tclasses = [ ExecutorTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py
index e2375f8a..5d6befe6 100644
--- a/src/engine/SCons/Job.py
+++ b/src/engine/SCons/Job.py
@@ -31,6 +31,8 @@ stop, and wait on jobs.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
+import SCons.compat
+
 import os
 import signal
 
@@ -127,7 +129,7 @@ class Jobs:
         turns out that it very difficult to stop the build process
         by throwing asynchronously an exception such as
         KeyboardInterrupt. For example, the python Condition
-        variables (threading.Condition) and Queue's do not seem to
+        variables (threading.Condition) and queue's do not seem to
         asynchronous-exception-safe. It would require adding a whole
         bunch of try/finally block and except KeyboardInterrupt all
         over the place.
@@ -221,7 +223,7 @@ class Serial:
 # Parallel class (and its dependent classes) will work if the interpreter
 # doesn't support threads.
 try:
-    import Queue
+    import queue
     import threading
 except ImportError:
     pass
@@ -271,8 +273,8 @@ else:
             One must specify the stack size of the worker threads. The
             stack size is specified in kilobytes.
             """
-            self.requestQueue = Queue.Queue(0)
-            self.resultsQueue = Queue.Queue(0)
+            self.requestQueue = queue.Queue(0)
+            self.resultsQueue = queue.Queue(0)
 
             try:
                 prev_size = threading.stack_size(stack_size*1024) 
diff --git a/src/engine/SCons/JobTests.py b/src/engine/SCons/JobTests.py
index 793a8b74..afa00fb0 100644
--- a/src/engine/SCons/JobTests.py
+++ b/src/engine/SCons/JobTests.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -491,7 +492,7 @@ class _SConsTaskTest(unittest.TestCase):
             self.failUnless(state in [SCons.Node.no_state, N.expect_to_be],
                             "Node %s got unexpected result: %s" % (N, state))
 
-        self.failUnless(filter(lambda N: N.get_state(), testnodes),
+        self.failUnless([N for N in testnodes if N.get_state()],
                         "no nodes ran at all.")
 
 
diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py
index 966a618d..4566d31b 100644
--- a/src/engine/SCons/Memoize.py
+++ b/src/engine/SCons/Memoize.py
@@ -165,11 +165,11 @@ class CountValue(Counter):
     """
     def __call__(self, *args, **kw):
         obj = args[0]
-        if obj._memo.has_key(self.method_name):
+        if self.method_name in obj._memo:
             self.hit = self.hit + 1
         else:
             self.miss = self.miss + 1
-        return apply(self.underlying_method, args, kw)
+        return self.underlying_method(*args, **kw)
 
 class CountDict(Counter):
     """
@@ -199,12 +199,12 @@ class CountDict(Counter):
         except KeyError:
             self.miss = self.miss + 1
         else:
-            key = apply(self.keymaker, args, kw)
-            if memo_dict.has_key(key):
+            key = self.keymaker(*args, **kw)
+            if key in memo_dict:
                 self.hit = self.hit + 1
             else:
                 self.miss = self.miss + 1
-        return apply(self.underlying_method, args, kw)
+        return self.underlying_method(*args, **kw)
 
 class Memoizer:
     """Object which performs caching of method calls for its 'primary'
diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py
index 14520527..b3edf013 100644
--- a/src/engine/SCons/MemoizeTests.py
+++ b/src/engine/SCons/MemoizeTests.py
@@ -187,7 +187,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py
index d599335f..521488e6 100644
--- a/src/engine/SCons/Node/Alias.py
+++ b/src/engine/SCons/Node/Alias.py
@@ -32,7 +32,6 @@ This creates a hash of global Aliases (dummy targets).
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import UserDict
 
 import SCons.Errors
@@ -46,7 +45,7 @@ class AliasNameSpace(UserDict.UserDict):
         try:
             a = self[name]
         except KeyError:
-            a = apply(SCons.Node.Alias.Alias, (name,), kw)
+            a = SCons.Node.Alias.Alias(name, **kw)
             self[name] = a
         return a
 
@@ -95,8 +94,8 @@ class Alias(SCons.Node.Node):
     def get_contents(self):
         """The contents of an alias is the concatenation
         of the content signatures of all its sources."""
-        childsigs = map(lambda n: n.get_csig(), self.children())
-        return string.join(childsigs, '')
+        childsigs = [n.get_csig() for n in self.children()]
+        return ''.join(childsigs)
 
     def sconsign(self):
         """An Alias is not recorded in .sconsign files"""
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index 82322e3b..69310723 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -119,7 +119,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 88248d74..705e0bcd 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -32,6 +32,7 @@ that can be used by scripts or modules looking for the canonical default.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -43,7 +44,6 @@ import os.path
 import re
 import shutil
 import stat
-import string
 import sys
 import time
 
@@ -260,7 +260,7 @@ def set_duplicate(duplicate):
                                            "should be in Valid_Duplicates")
     global Link_Funcs
     Link_Funcs = []
-    for func in string.split(duplicate,'-'):
+    for func in duplicate.split('-'):
         if link_dict[func]:
             Link_Funcs.append(link_dict[func])
 
@@ -373,7 +373,7 @@ if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin:
         return x
 else:
     def _my_normcase(x):
-        return string.upper(x)
+        return x.upper()
 
 
 
@@ -459,7 +459,7 @@ def set_diskcheck(list):
         dc.set(list)
 
 def diskcheck_types():
-    return map(lambda dc: dc.type, diskcheckers)
+    return [dc.type for dc in diskcheckers]
 
 
 
@@ -497,7 +497,7 @@ class EntryProxy(SCons.Util.Proxy):
             return self
         else:
             entry = self.get()
-            r = string.replace(entry.get_path(), os.sep, '/')
+            r = entry.get_path().replace(os.sep, '/')
             return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_posix")
 
     def __get_windows_path(self):
@@ -507,7 +507,7 @@ class EntryProxy(SCons.Util.Proxy):
             return self
         else:
             entry = self.get()
-            r = string.replace(entry.get_path(), os.sep, '\\')
+            r = entry.get_path().replace(os.sep, '\\')
             return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_windows")
 
     def __get_srcnode(self):
@@ -753,8 +753,8 @@ class Base(SCons.Node.Node):
         try: i = path_elems.index(dir)
         except ValueError: pass
         else: path_elems = path_elems[i+1:]
-        path_elems = map(lambda n: n.name, path_elems)
-        return string.join(path_elems, os.sep)
+        path_elems = [n.name for n in path_elems]
+        return os.sep.join(path_elems)
 
     def set_src_builder(self, builder):
         """Set the source code builder for this node."""
@@ -1249,7 +1249,7 @@ class FS(LocalFS):
             root = directory.root
 
         if os.sep != '/':
-            p = string.replace(p, os.sep, '/')
+            p = p.replace(os.sep, '/')
         return root._lookup_abs(p, fsclass, create)
 
     def Entry(self, name, directory = None, create = 1):
@@ -1327,12 +1327,12 @@ class FS(LocalFS):
                 if start_dir.is_under(bd):
                     # If already in the build-dir location, don't reflect
                     return [orig], fmt % str(orig)
-                p = apply(os.path.join, [bd.path] + tail)
+                p = os.path.join(bd.path, *tail)
                 targets.append(self.Entry(p))
             tail = [dir.name] + tail
             dir = dir.up()
         if targets:
-            message = fmt % string.join(map(str, targets))
+            message = fmt % ' '.join(map(str, targets))
         return targets, message
 
     def Glob(self, pathname, ondisk=True, source=True, strings=False, cwd=None):
@@ -1574,9 +1574,9 @@ class Dir(Base):
             i = self.path_elements.index(other) + 1
 
             path_elems = ['..'] * (len(self.path_elements) - i) \
-                         + map(lambda n: n.name, other.path_elements[i:])
+                         + [n.name for n in other.path_elements[i:]]
              
-            result = string.join(path_elems, os.sep)
+            result = os.sep.join(path_elems)
 
         memo_dict[other] = result
 
@@ -1622,7 +1622,7 @@ class Dir(Base):
         """A null "builder" for directories."""
         global MkdirBuilder
         if self.builder is not MkdirBuilder:
-            apply(SCons.Node.Node.build, [self,], kw)
+            SCons.Node.Node.build(self, **kw)
 
     #
     #
@@ -1687,7 +1687,7 @@ class Dir(Base):
         sorted_children.sort(name_cmp)
         for node in sorted_children:
             contents.append('%s %s\n' % (node.get_csig(), node.name))
-        return string.join(contents, '')
+        return ''.join(contents)
 
     def get_csig(self):
         """Compute the content signature for Directory nodes. In
@@ -1783,7 +1783,7 @@ class Dir(Base):
                 d[name] = result
             return result
         else:
-            return d.has_key(name)
+            return name in d
 
     memoizer_counters.append(SCons.Memoize.CountValue('srcdir_list'))
 
@@ -1915,8 +1915,7 @@ class Dir(Base):
         names.remove('.')
         names.remove('..')
         func(arg, self, names)
-        select_dirs = lambda n, e=entries: isinstance(e[n], Dir)
-        for dirname in filter(select_dirs, names):
+        for dirname in [n for n in names if isinstance(entries[n], Dir)]:
             entries[dirname].walk(func, arg)
 
     def glob(self, pathname, ondisk=True, source=False, strings=False):
@@ -1964,7 +1963,7 @@ class Dir(Base):
         for dir in list:
             r = dir._glob1(basename, ondisk, source, strings)
             if strings:
-                r = map(lambda x, d=str(dir): os.path.join(d, x), r)
+                r = [os.path.join(str(dir), x) for x in r]
             result.extend(r)
         result.sort(lambda a, b: cmp(str(a), str(b)))
         return result
@@ -1990,9 +1989,8 @@ class Dir(Base):
             # We use the .name attribute from the Node because the keys of
             # the dir.entries dictionary are normalized (that is, all upper
             # case) on case-insensitive systems like Windows.
-            #node_names = [ v.name for k, v in dir.entries.items() if k not in ('.', '..') ]
-            entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys())
-            node_names = map(lambda n, e=dir.entries: e[n].name, entry_names)
+            node_names = [ v.name for k, v in dir.entries.items()
+                           if k not in ('.', '..') ]
             names.extend(node_names)
             if not strings:
                 # Make sure the working directory (self) actually has
@@ -2015,7 +2013,7 @@ class Dir(Base):
                     # after we exit this loop.
                     if pattern[0] != '.':
                         #disk_names = [ d for d in disk_names if d[0] != '.' ]
-                        disk_names = filter(lambda x: x[0] != '.', disk_names)
+                        disk_names = [x for x in disk_names if x[0] != '.']
                     disk_names = fnmatch.filter(disk_names, pattern)
                     dirEntry = dir.Entry
                     for name in disk_names:
@@ -2031,14 +2029,14 @@ class Dir(Base):
         names = set(names)
         if pattern[0] != '.':
             #names = [ n for n in names if n[0] != '.' ]
-            names = filter(lambda x: x[0] != '.', names)
+            names = [x for x in names if x[0] != '.']
         names = fnmatch.filter(names, pattern)
 
         if strings:
             return names
 
         #return [ self.entries[_my_normcase(n)] for n in names ]
-        return map(lambda n, e=self.entries:  e[_my_normcase(n)], names)
+        return [self.entries[_my_normcase(n)] for n in names]
 
 class RootDir(Dir):
     """A class for the root directory of a file system.
@@ -2200,7 +2198,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
                 except AttributeError:
                     s = str(n)
                 else:
-                    s = string.replace(s, os.sep, '/')
+                    s = s.replace(os.sep, '/')
                 return s
         for attr in ['bsources', 'bdepends', 'bimplicit']:
             try:
@@ -2208,7 +2206,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
             except AttributeError:
                 pass
             else:
-                setattr(self, attr, map(node_to_str, val))
+                setattr(self, attr, list(map(node_to_str, val)))
     def convert_from_sconsign(self, dir, name):
         """
         Converts a newly-read FileBuildInfo object for in-SCons use
@@ -2249,9 +2247,9 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
         bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs
         for bkid, bkidsig in izip(bkids, bkidsigs):
             result.append(str(bkid) + ': ' +
-                          string.join(bkidsig.format(names=names), ' '))
+                          ' '.join(bkidsig.format(names=names)))
         result.append('%s [%s]' % (self.bactsig, self.bact))
-        return string.join(result, '\n')
+        return '\n'.join(result)
 
 class File(Base):
     """A class for files in a file system.
@@ -2288,7 +2286,7 @@ class File(Base):
         directory of this file."""
         # TODO(1.5)
         # return [self.Dir(p) for p in pathlist]
-        return map(lambda p, s=self: s.Dir(p), pathlist)
+        return [self.Dir(p) for p in pathlist]
 
     def File(self, name):
         """Create a file node named 'name' relative to
@@ -2603,7 +2601,7 @@ class File(Base):
         if scanner:
             # result = [n.disambiguate() for n in scanner(self, env, path)]
             result = scanner(self, env, path)
-            result = map(lambda N: N.disambiguate(), result)
+            result = [N.disambiguate() for N in result]
         else:
             result = []
 
@@ -3019,7 +3017,7 @@ class File(Base):
         children = self.children()
         executor = self.get_executor()
         # sigs = [n.get_cachedir_csig() for n in children]
-        sigs = map(lambda n: n.get_cachedir_csig(), children)
+        sigs = [n.get_cachedir_csig() for n in children]
         sigs.append(SCons.Util.MD5signature(executor.get_contents()))
         sigs.append(self.path)
         result = self.cachesig = SCons.Util.MD5collect(sigs)
@@ -3117,8 +3115,8 @@ class FileFinder:
         if verbose and not callable(verbose):
             if not SCons.Util.is_String(verbose):
                 verbose = "find_file"
-            verbose = '  %s: ' % verbose
-            verbose = lambda s, v=verbose: sys.stdout.write(v + s)
+            _verbose = '  %s: ' % verbose
+            verbose = lambda s: sys.stdout.write(_verbose + s)
 
         filedir, filename = os.path.split(filename)
         if filedir:
@@ -3153,7 +3151,7 @@ class FileFinder:
             #paths = filter(None, map(filedir_lookup, paths))
 
             self.default_filedir = filedir
-            paths = filter(None, map(self.filedir_lookup, paths))
+            paths = [_f for _f in map(self.filedir_lookup, paths) if _f]
 
         result = None
         for dir in paths:
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 9582a977..af7638d3 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import sys
 import time
 import unittest
@@ -40,13 +39,6 @@ import SCons.Warnings
 
 built_it = None
 
-# This will be built-in in 2.3.  For now fake it.
-try :
-    True , False
-except NameError :
-    True = 1 ; False = 0
-
-
 scanner_count = 0
 
 class Scanner:
@@ -341,7 +333,7 @@ class VariantDirTestCase(unittest.TestCase):
 
         f11 = fs.File('src/file11')
         t, m = f11.alter_targets()
-        bdt = map(lambda n: n.path, t)
+        bdt = [n.path for n in t]
         var1_file11 = os.path.normpath('build/var1/file11')
         var2_file11 = os.path.normpath('build/var2/file11')
         assert bdt == [var1_file11, var2_file11], bdt
@@ -349,11 +341,11 @@ class VariantDirTestCase(unittest.TestCase):
         f12 = fs.File('src/file12')
         f12.builder = 1
         bdt, m = f12.alter_targets()
-        assert bdt == [], map(lambda n: n.path, bdt)
+        assert bdt == [], [n.path for n in bdt]
 
         d13 = fs.Dir('src/new_dir')
         t, m = d13.alter_targets()
-        bdt = map(lambda n: n.path, t)
+        bdt = [n.path for n in t]
         var1_new_dir = os.path.normpath('build/var1/new_dir')
         var2_new_dir = os.path.normpath('build/var2/new_dir')
         assert bdt == [var1_new_dir, var2_new_dir], bdt
@@ -445,7 +437,7 @@ class VariantDirTestCase(unittest.TestCase):
                 self.have['copy'] = copy
 
                 self.links_to_be_called = []
-                for link in string.split(self.duplicate, '-'):
+                for link in self.duplicate.split('-'):
                     if self.have[link]:
                         self.links_to_be_called.append(link)
 
@@ -817,7 +809,7 @@ class FileBuildInfoTestCase(_tempdirTestCase):
             'actionsig [action]',
         ]
 
-        expect = string.join(expect_lines, '\n')
+        expect = '\n'.join(expect_lines)
         format = bi1.format()
         assert format == expect, (repr(expect), repr(format))
 
@@ -921,12 +913,12 @@ class FSTestCase(_tempdirTestCase):
         drive, path = os.path.splitdrive(os.getcwd())
 
         def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive):
-            dir = fileSys.Dir(string.replace(lpath, '/', sep))
+            dir = fileSys.Dir(lpath.replace('/', sep))
 
             if os.sep != '/':
-                path_ = string.replace(path_, '/', os.sep)
-                abspath_ = string.replace(abspath_, '/', os.sep)
-                up_path_ = string.replace(up_path_, '/', os.sep)
+                path_ = path_.replace('/', os.sep)
+                abspath_ = abspath_.replace('/', os.sep)
+                up_path_ = up_path_.replace('/', os.sep)
 
             def strip_slash(p, drive=drive):
                 if p[-1] == os.sep and len(p) > 1:
@@ -937,7 +929,7 @@ class FSTestCase(_tempdirTestCase):
             path = strip_slash(path_)
             abspath = strip_slash(abspath_)
             up_path = strip_slash(up_path_)
-            name = string.split(abspath, os.sep)[-1]
+            name = abspath.split(os.sep)[-1]
 
             assert dir.name == name, \
                    "dir.name %s != expected name %s" % \
@@ -978,7 +970,7 @@ class FSTestCase(_tempdirTestCase):
             Dir_test('#',           './',          sub_dir,           sub)
 
             try:
-                f2 = fs.File(string.join(['f1', 'f2'], sep), directory = d1)
+                f2 = fs.File(sep.join(['f1', 'f2']), directory = d1)
             except TypeError, x:
                 assert str(x) == ("Tried to lookup File '%s' as a Dir." %
                                   d1_f1), x
@@ -986,7 +978,7 @@ class FSTestCase(_tempdirTestCase):
                 raise
 
             try:
-                dir = fs.Dir(string.join(['d1', 'f1'], sep))
+                dir = fs.Dir(sep.join(['d1', 'f1']))
             except TypeError, x:
                 assert str(x) == ("Tried to lookup File '%s' as a Dir." %
                                   d1_f1), x
@@ -1051,7 +1043,7 @@ class FSTestCase(_tempdirTestCase):
         assert built_it
 
         def match(path, expect):
-            expect = string.replace(expect, '/', os.sep)
+            expect = expect.replace('/', os.sep)
             assert path == expect, "path %s != expected %s" % (path, expect)
 
         e1 = fs.Entry("d1")
@@ -1434,7 +1426,7 @@ class FSTestCase(_tempdirTestCase):
         test.subdir('sub', ['sub', 'dir'])
 
         def drive_workpath(drive, dirs, test=test):
-            x = apply(test.workpath, dirs)
+            x = test.workpath(*dirs)
             drive, path = os.path.splitdrive(x)
             return 'X:' + path
 
@@ -1466,11 +1458,11 @@ class FSTestCase(_tempdirTestCase):
             seps = seps + ['/']
 
         def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs):
-            dir = fileSys.Dir(string.replace(lpath, '/', sep))
+            dir = fileSys.Dir(lpath.replace('/', sep))
 
             if os.sep != '/':
-                path_ = string.replace(path_, '/', os.sep)
-                up_path_ = string.replace(up_path_, '/', os.sep)
+                path_ = path_.replace('/', os.sep)
+                up_path_ = up_path_.replace('/', os.sep)
 
             def strip_slash(p):
                 if p[-1] == os.sep and len(p) > 3:
@@ -1478,7 +1470,7 @@ class FSTestCase(_tempdirTestCase):
                 return p
             path = strip_slash(path_)
             up_path = strip_slash(up_path_)
-            name = string.split(path, os.sep)[-1]
+            name = path.split(os.sep)[-1]
 
             assert dir.name == name, \
                    "dir.name %s != expected name %s" % \
@@ -1577,8 +1569,8 @@ class FSTestCase(_tempdirTestCase):
 
         d1 = fs.Dir('d1')
         d2 = d1.Dir('d2')
-        dirs = string.split(os.path.normpath(d2.abspath), os.sep)
-        above_path = apply(os.path.join, ['..']*len(dirs) + ['above'])
+        dirs = os.path.normpath(d2.abspath).split(os.sep)
+        above_path = os.path.join(*['..']*len(dirs) + ['above'])
         above = d2.Dir(above_path)
 
     def test_rel_path(self):
@@ -1730,7 +1722,7 @@ class DirTestCase(_tempdirTestCase):
         fs.Dir(os.path.join('ddd', 'd1', 'f4'))
         fs.Dir(os.path.join('ddd', 'd1', 'f5'))
         dir.scan()
-        kids = map(lambda x: x.path, dir.children(None))
+        kids = [x.path for x in dir.children(None)]
         kids.sort()
         assert kids == [os.path.join('ddd', 'd1'),
                         os.path.join('ddd', 'f1'),
@@ -1757,7 +1749,7 @@ class DirTestCase(_tempdirTestCase):
         s = self.fs.Dir(os.path.join('d', 'sub'))
 
         #TODO(1.5) files = d.get_contents().split('\n')
-        files = string.split(d.get_contents(), '\n')
+        files = d.get_contents().split('\n')
 
         assert e.get_contents() == '', e.get_contents()
         assert e.get_text_contents() == '', e.get_text_contents()
@@ -1776,13 +1768,13 @@ class DirTestCase(_tempdirTestCase):
 
         fs.File(os.path.join('ddd', 'f1'))
         dir.scan()
-        kids = map(lambda x: x.path, dir.children())
+        kids = [x.path for x in dir.children()]
         kids.sort()
         assert kids == [os.path.join('ddd', 'f1')], kids
 
         fs.File(os.path.join('ddd', 'f2'))
         dir.scan()
-        kids = map(lambda x: x.path, dir.children())
+        kids = [x.path for x in dir.children()]
         kids.sort()
         assert kids == [os.path.join('ddd', 'f1'),
                         os.path.join('ddd', 'f2')], kids
@@ -1818,8 +1810,8 @@ class DirTestCase(_tempdirTestCase):
         self.fs.VariantDir(sub2, src, duplicate=0)
 
         def check(result, expect):
-            result = map(str, result)
-            expect = map(os.path.normpath, expect)
+            result = list(map(str, result))
+            expect = list(map(os.path.normpath, expect))
             assert result == expect, result
 
         s = src.srcdir_list()
@@ -1922,8 +1914,8 @@ class DirTestCase(_tempdirTestCase):
         exists_e.exists = return_true
 
         def check(result, expect):
-            result = map(str, result)
-            expect = map(os.path.normpath, expect)
+            result = list(map(str, result))
+            expect = list(map(os.path.normpath, expect))
             assert result == expect, result
 
         # First check from the source directory.
@@ -2135,7 +2127,7 @@ class FileTestCase(_tempdirTestCase):
         d1 = self.fs.Dir('subdir/d1')
         d2 = self.fs.Dir('subdir/d2')
         dirs = fff.Dirs(['d1', 'd2'])
-        assert dirs == [d1, d2], map(str, dirs)
+        assert dirs == [d1, d2], list(map(str, dirs))
 
     def test_exists(self):
         """Test the File.exists() method"""
@@ -2248,7 +2240,7 @@ class GlobTestCase(_tempdirTestCase):
         strings_kwargs = copy.copy(kwargs)
         strings_kwargs['strings'] = True
         for input, string_expect, node_expect in cases:
-            r = apply(self.fs.Glob, (input,), strings_kwargs)
+            r = self.fs.Glob(input, **strings_kwargs)
             r.sort()
             assert r == string_expect, "Glob(%s, strings=True) expected %s, got %s" % (input, string_expect, r)
 
@@ -2259,7 +2251,7 @@ class GlobTestCase(_tempdirTestCase):
         # Verify those by running the list through str() before comparing
         # them with the expected list of strings.
         for input, string_expect, node_expect in cases:
-            r = apply(self.fs.Glob, (input,), kwargs)
+            r = self.fs.Glob(input, **kwargs)
             if node_expect:
                 r.sort(lambda a,b: cmp(a.path, b.path))
                 result = []
@@ -2269,16 +2261,16 @@ class GlobTestCase(_tempdirTestCase):
                     result.append(n)
                 fmt = lambda n: "%s %s" % (repr(n), repr(str(n)))
             else:
-                r = map(str, r)
+                r = list(map(str, r))
                 r.sort()
                 result = string_expect
                 fmt = lambda n: n
             if r != result:
                 import pprint
                 print "Glob(%s) expected:" % repr(input)
-                pprint.pprint(map(fmt, result))
+                pprint.pprint(list(map(fmt, result)))
                 print "Glob(%s) got:" % repr(input)
-                pprint.pprint(map(fmt, r))
+                pprint.pprint(list(map(fmt, r)))
                 self.fail()
 
     def test_exact_match(self):
@@ -2538,7 +2530,7 @@ class RepositoryTestCase(_tempdirTestCase):
         ]
 
         rep = self.fs.Dir('#').getRepositories()
-        r = map(lambda x, np=os.path.normpath: np(str(x)), rep)
+        r = [os.path.normpath(str(x)) for x in rep]
         assert r == expect, r
 
     def test_get_all_rdirs(self):
@@ -2560,7 +2552,7 @@ class RepositoryTestCase(_tempdirTestCase):
         ]
 
         rep = self.fs.Dir('#').get_all_rdirs()
-        r = map(lambda x, np=os.path.normpath: np(str(x)), rep)
+        r = [os.path.normpath(str(x)) for x in rep]
         assert r == expect, r
 
     def test_rentry(self):
@@ -2742,25 +2734,25 @@ class RepositoryTestCase(_tempdirTestCase):
         rep3_sub_d1 = fs.Dir(test.workpath('rep3', 'sub', 'd1'))
 
         r = fs.Top.Rfindalldirs((d1,))
-        assert r == [d1], map(str, r)
+        assert r == [d1], list(map(str, r))
 
         r = fs.Top.Rfindalldirs((d1, d2))
-        assert r == [d1, d2], map(str, r)
+        assert r == [d1, d2], list(map(str, r))
 
         r = fs.Top.Rfindalldirs(('d1',))
-        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
 
         r = fs.Top.Rfindalldirs(('#d1',))
-        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
 
         r = sub.Rfindalldirs(('d1',))
-        assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], map(str, r)
+        assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], list(map(str, r))
 
         r = sub.Rfindalldirs(('#d1',))
-        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+        assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
 
         r = fs.Top.Rfindalldirs(('d1', d2))
-        assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], map(str, r)
+        assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], list(map(str, r))
 
     def test_rexists(self):
         """Test the Entry.rexists() method"""
@@ -2892,10 +2884,10 @@ class find_fileTestCase(unittest.TestCase):
         nodes.append(SCons.Node.FS.find_file('pseudo', paths))
         nodes.append(SCons.Node.FS.find_file('same', paths))
 
-        file_names = map(str, nodes)
-        file_names = map(os.path.normpath, file_names)
+        file_names = list(map(str, nodes))
+        file_names = list(map(os.path.normpath, file_names))
         expect = ['./foo', './bar/baz', './pseudo', './bar/same']
-        expect = map(os.path.normpath, expect)
+        expect = list(map(os.path.normpath, expect))
         assert file_names == expect, file_names
 
         # Make sure we don't blow up if there's already a File in place
@@ -3433,14 +3425,14 @@ class SaveStringsTestCase(unittest.TestCase):
         fs1.VariantDir('d0', 'src', duplicate=0)
         fs1.VariantDir('d1', 'src', duplicate=1)
 
-        s = map(str, nodes)
-        expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+        s = list(map(str, nodes))
+        expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
         assert s == expect, s
 
         modify(nodes)
 
-        s = map(str, nodes)
-        expect = map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b'])
+        s = list(map(str, nodes))
+        expect = list(map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b']))
         assert s == expect, s
 
         SCons.Node.FS.save_strings(1)
@@ -3449,14 +3441,14 @@ class SaveStringsTestCase(unittest.TestCase):
         fs2.VariantDir('d0', 'src', duplicate=0)
         fs2.VariantDir('d1', 'src', duplicate=1)
 
-        s = map(str, nodes)
-        expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+        s = list(map(str, nodes))
+        expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
         assert s == expect, s
 
         modify(nodes)
 
-        s = map(str, nodes)
-        expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+        s = list(map(str, nodes))
+        expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
         assert s == expect, 'node str() not cached: %s'%s
 
 
@@ -3509,7 +3501,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 643e2184..07842375 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -20,12 +20,12 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import re
-import string
 import sys
 import types
 import unittest
@@ -125,7 +125,7 @@ class Environment:
     def Override(self, overrides):
         d = self._dict.copy()
         d.update(overrides)
-        return apply(Environment, (), d)
+        return Environment(**d)
     def _update(self, dict):
         self._dict.update(dict)
     def get_factory(self, factory):
@@ -889,24 +889,24 @@ class NodeTestCase(unittest.TestCase):
         d2.found_includes = [e, f]
         f.found_includes = [g]
         deps = node.get_implicit_deps(env, s, target)
-        assert deps == [d1, d2, e, f, g], map(str, deps)
+        assert deps == [d1, d2, e, f, g], list(map(str, deps))
 
         # Recursive scanning eliminates duplicates
         e.found_includes = [f]
         deps = node.get_implicit_deps(env, s, target)
-        assert deps == [d1, d2, e, f, g], map(str, deps)
+        assert deps == [d1, d2, e, f, g], list(map(str, deps))
 
         # Scanner method can select specific nodes to recurse
         def no_fff(nodes):
-            return filter(lambda n: str(n)[0] != 'f', nodes)
+            return [n for n in nodes if str(n)[0] != 'f']
         s.recurse_nodes = no_fff
         deps = node.get_implicit_deps(env, s, target)
-        assert deps == [d1, d2, e, f], map(str, deps)
+        assert deps == [d1, d2, e, f], list(map(str, deps))
 
         # Scanner method can short-circuit recursing entirely
         s.recurse_nodes = lambda nodes: []
         deps = node.get_implicit_deps(env, s, target)
-        assert deps == [d1, d2], map(str, deps)
+        assert deps == [d1, d2], list(map(str, deps))
 
     def test_get_env_scanner(self):
         """Test fetching the environment scanner for a Node
@@ -1130,13 +1130,13 @@ class NodeTestCase(unittest.TestCase):
         nw = SCons.Node.Walker(n1)
         assert nw.next().name ==  "n4"
         assert nw.next().name ==  "n5"
-        assert nw.history.has_key(n2)
+        assert n2 in nw.history
         assert nw.next().name ==  "n2"
         assert nw.next().name ==  "n6"
         assert nw.next().name ==  "n7"
-        assert nw.history.has_key(n3)
+        assert n3 in nw.history
         assert nw.next().name ==  "n3"
-        assert nw.history.has_key(n1)
+        assert n1 in nw.history
         assert nw.next().name ==  "n1"
         assert nw.next() is None
 
@@ -1293,7 +1293,7 @@ class NodeListTestCase(unittest.TestCase):
         # New-style classes report as "object"; classic classes report
         # as "instance"...
         r = re.sub("object", "instance", r)
-        l = string.join(["<MyNode instance at 0x>"]*3, ", ")
+        l = ", ".join(["<MyNode instance at 0x>"]*3)
         assert r == '[%s]' % l, r
 
 
@@ -1306,7 +1306,7 @@ if __name__ == "__main__":
                  NodeListTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py
index eba008b6..3d8bdaac 100644
--- a/src/engine/SCons/Node/Python.py
+++ b/src/engine/SCons/Node/Python.py
@@ -67,7 +67,7 @@ class Value(SCons.Node.Node):
 
     def build(self, **kw):
         if not hasattr(self, 'built_value'):
-            apply (SCons.Node.Node.build, (self,), kw)
+            SCons.Node.Node.build(self, **kw)
 
     is_up_to_date = SCons.Node.Node.children_are_up_to_date
 
diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py
index 1dc2bb7f..74a9c996 100644
--- a/src/engine/SCons/Node/PythonTests.py
+++ b/src/engine/SCons/Node/PythonTests.py
@@ -119,7 +119,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index c4f36cca..c25c955e 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -41,12 +41,12 @@ be able to depend on any other type of "thing."
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import copy
 from itertools import chain, izip
-import string
 import UserList
 
 from SCons.Debug import logInstanceCreation
@@ -57,7 +57,7 @@ import SCons.Util
 from SCons.Debug import Trace
 
 def classname(obj):
-    return string.split(str(obj.__class__), '.')[-1]
+    return str(obj.__class__).split('.')[-1]
 
 # Node states
 #
@@ -372,7 +372,7 @@ class Node:
 
         """
         try:
-            apply(self.get_executor(), (self,), kw)
+            self.get_executor()(self, **kw)
         except SCons.Errors.BuildError, e:
             e.node = self
             raise
@@ -548,8 +548,7 @@ class Node:
         deps = []
         while nodes:
             n = nodes.pop(0)
-            d = filter(lambda x, seen=seen: not seen.has_key(x),
-                       n.get_found_includes(env, scanner, path))
+            d = [x for x in n.get_found_includes(env, scanner, path) if x not in seen]
             if d:
                 deps.extend(d)
                 for n in d:
@@ -832,7 +831,7 @@ class Node:
         except TypeError, e:
             e = e.args[0]
             if SCons.Util.is_List(e):
-                s = map(str, e)
+                s = list(map(str, e))
             else:
                 s = str(e)
             raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -849,7 +848,7 @@ class Node:
         except TypeError, e:
             e = e.args[0]
             if SCons.Util.is_List(e):
-                s = map(str, e)
+                s = list(map(str, e))
             else:
                 s = str(e)
             raise SCons.Errors.UserError("attempted to ignore a non-Node dependency of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -863,7 +862,7 @@ class Node:
         except TypeError, e:
             e = e.args[0]
             if SCons.Util.is_List(e):
-                s = map(str, e)
+                s = list(map(str, e))
             else:
                 s = str(e)
             raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -1215,11 +1214,11 @@ class Node:
 
         lines = []
 
-        removed = filter(lambda x, nk=new_bkids: not x in nk, old_bkids)
+        removed = [x for x in old_bkids if not x in new_bkids]
         if removed:
-            removed = map(stringify, removed)
+            removed = list(map(stringify, removed))
             fmt = "`%s' is no longer a dependency\n"
-            lines.extend(map(lambda s, fmt=fmt: fmt % s, removed))
+            lines.extend([fmt % s for s in removed])
 
         for k in new_bkids:
             if not k in old_bkids:
@@ -1229,14 +1228,14 @@ class Node:
 
         if len(lines) == 0 and old_bkids != new_bkids:
             lines.append("the dependency order changed:\n" +
-                         "%sold: %s\n" % (' '*15, map(stringify, old_bkids)) +
-                         "%snew: %s\n" % (' '*15, map(stringify, new_bkids)))
+                         "%sold: %s\n" % (' '*15, list(map(stringify, old_bkids))) +
+                         "%snew: %s\n" % (' '*15, list(map(stringify, new_bkids))))
 
         if len(lines) == 0:
             def fmt_with_title(title, strlines):
-                lines = string.split(strlines, '\n')
+                lines = strlines.split('\n')
                 sep = '\n' + ' '*(15 + len(title))
-                return ' '*15 + title + string.join(lines, sep) + '\n'
+                return ' '*15 + title + sep.join(lines) + '\n'
             if old.bactsig != new.bactsig:
                 if old.bact == new.bact:
                     lines.append("the contents of the build action changed\n" +
@@ -1254,7 +1253,7 @@ class Node:
             return "%s %s"  % (preamble, lines[0])
         else:
             lines = ["%s:\n" % preamble] + lines
-            return string.join(lines, ' '*11)
+            return ( ' '*11).join(lines)
 
 try:
     [].extend(UserList.UserList([]))
@@ -1267,7 +1266,7 @@ except TypeError:
 else:
     class NodeList(UserList.UserList):
         def __str__(self):
-            return str(map(str, self.data))
+            return str(list(map(str, self.data)))
 
 def get_children(node, parent): return node.children()
 def ignore_cycle(node, stack): pass
@@ -1310,7 +1309,7 @@ class Walker:
                 node = self.stack[-1].wkids.pop(0)
                 if not self.stack[-1].wkids:
                     self.stack[-1].wkids = None
-                if self.history.has_key(node):
+                if node in self.history:
                     self.cycle_func(node, self.stack)
                 else:
                     node.wkids = copy.copy(self.kids_func(node, self.stack[-1]))
diff --git a/src/engine/SCons/Options/BoolOption.py b/src/engine/SCons/Options/BoolOption.py
index 652cf5ee..452fdd3b 100644
--- a/src/engine/SCons/Options/BoolOption.py
+++ b/src/engine/SCons/Options/BoolOption.py
@@ -41,7 +41,7 @@ def BoolOption(*args, **kw):
         msg = "The BoolOption() function is deprecated; use the BoolVariable() function instead."
         SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
         warned = True
-    return apply(SCons.Variables.BoolVariable, args, kw)
+    return SCons.Variables.BoolVariable(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Options/EnumOption.py b/src/engine/SCons/Options/EnumOption.py
index e89b5b9a..2db158d5 100644
--- a/src/engine/SCons/Options/EnumOption.py
+++ b/src/engine/SCons/Options/EnumOption.py
@@ -41,7 +41,7 @@ def EnumOption(*args, **kw):
         msg = "The EnumOption() function is deprecated; use the EnumVariable() function instead."
         SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
         warned = True
-    return apply(SCons.Variables.EnumVariable, args, kw)
+    return SCons.Variables.EnumVariable(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py
index a6609242..4167d8ef 100644
--- a/src/engine/SCons/Options/ListOption.py
+++ b/src/engine/SCons/Options/ListOption.py
@@ -41,7 +41,7 @@ def ListOption(*args, **kw):
         msg = "The ListOption() function is deprecated; use the ListVariable() function instead."
         SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
         warned = True
-    return apply(SCons.Variables.ListVariable, args, kw)
+    return SCons.Variables.ListVariable(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Options/PackageOption.py b/src/engine/SCons/Options/PackageOption.py
index 51f9f9bf..ba0608aa 100644
--- a/src/engine/SCons/Options/PackageOption.py
+++ b/src/engine/SCons/Options/PackageOption.py
@@ -41,7 +41,7 @@ def PackageOption(*args, **kw):
         msg = "The PackageOption() function is deprecated; use the PackageVariable() function instead."
         SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
         warned = True
-    return apply(SCons.Variables.PackageVariable, args, kw)
+    return SCons.Variables.PackageVariable(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Options/PathOption.py b/src/engine/SCons/Options/PathOption.py
index fd1130b9..5d460a07 100644
--- a/src/engine/SCons/Options/PathOption.py
+++ b/src/engine/SCons/Options/PathOption.py
@@ -45,27 +45,27 @@ class _PathOptionClass:
 
     def __call__(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable, args, kw)
+        return SCons.Variables.PathVariable(*args, **kw)
 
     def PathAccept(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable.PathAccept, args, kw)
+        return SCons.Variables.PathVariable.PathAccept(*args, **kw)
 
     def PathIsDir(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable.PathIsDir, args, kw)
+        return SCons.Variables.PathVariable.PathIsDir(*args, **kw)
 
     def PathIsDirCreate(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable.PathIsDirCreate, args, kw)
+        return SCons.Variables.PathVariable.PathIsDirCreate(*args, **kw)
 
     def PathIsFile(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable.PathIsFile, args, kw)
+        return SCons.Variables.PathVariable.PathIsFile(*args, **kw)
 
     def PathExists(self, *args, **kw):
         self.warn()
-        return apply(SCons.Variables.PathVariable.PathExists, args, kw)
+        return SCons.Variables.PathVariable.PathExists(*args, **kw)
 
 PathOption = _PathOptionClass()
 
diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py
index 104aa82d..f6c84835 100644
--- a/src/engine/SCons/Options/__init__.py
+++ b/src/engine/SCons/Options/__init__.py
@@ -48,24 +48,17 @@ class Options(SCons.Variables.Variables):
             msg = "The Options class is deprecated; use the Variables class instead."
             SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
             warned = True
-        apply(SCons.Variables.Variables.__init__,
-              (self,) + args,
-              kw)
+        SCons.Variables.Variables.__init__(self, *args, **kw)
 
     def AddOptions(self, *args, **kw):
-        return apply(SCons.Variables.Variables.AddVariables,
-                     (self,) + args,
-                     kw)
+        return SCons.Variables.Variables.AddVariables(self, *args, **kw)
 
     def UnknownOptions(self, *args, **kw):
-        return apply(SCons.Variables.Variables.UnknownVariables,
-                     (self,) + args,
-                     kw)
+        return SCons.Variables.Variables.UnknownVariables(self, *args, **kw)
 
     def FormatOptionHelpText(self, *args, **kw):
-        return apply(SCons.Variables.Variables.FormatVariableHelpText,
-                     (self,) + args,
-                     kw)
+        return SCons.Variables.Variables.FormatVariableHelpText(self, *args,
+                     **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/PathList.py b/src/engine/SCons/PathList.py
index 9da0f314..7b12865f 100644
--- a/src/engine/SCons/PathList.py
+++ b/src/engine/SCons/PathList.py
@@ -33,7 +33,6 @@ Do the Right Thing (almost) regardless of how the variable is specified.
 """
 
 import os
-import string
 
 import SCons.Memoize
 import SCons.Node
@@ -98,14 +97,14 @@ class _PathList:
         over and over for each target.
         """
         if SCons.Util.is_String(pathlist):
-            pathlist = string.split(pathlist, os.pathsep)
+            pathlist = pathlist.split(os.pathsep)
         elif not SCons.Util.is_Sequence(pathlist):
             pathlist = [pathlist]
 
         pl = []
         for p in pathlist:
             try:
-                index = string.find(p, '$')
+                index = p.find('$')
             except (AttributeError, TypeError):
                 type = TYPE_OBJECT
             else:
diff --git a/src/engine/SCons/PathListTests.py b/src/engine/SCons/PathListTests.py
index faecc4db..31a9ec63 100644
--- a/src/engine/SCons/PathListTests.py
+++ b/src/engine/SCons/PathListTests.py
@@ -159,7 +159,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py
index 5bcd91ce..2ae1e972 100644
--- a/src/engine/SCons/Platform/__init__.py
+++ b/src/engine/SCons/Platform/__init__.py
@@ -48,7 +48,6 @@ import SCons.compat
 
 import imp
 import os
-import string
 import sys
 import tempfile
 
@@ -69,15 +68,15 @@ def platform_default():
     if osname == 'posix':
         if sys.platform == 'cygwin':
             return 'cygwin'
-        elif string.find(sys.platform, 'irix') != -1:
+        elif sys.platform.find('irix') != -1:
             return 'irix'
-        elif string.find(sys.platform, 'sunos') != -1:
+        elif sys.platform.find('sunos') != -1:
             return 'sunos'
-        elif string.find(sys.platform, 'hp-ux') != -1:
+        elif sys.platform.find('hp-ux') != -1:
             return 'hpux'
-        elif string.find(sys.platform, 'aix') != -1:
+        elif sys.platform.find('aix') != -1:
             return 'aix'
-        elif string.find(sys.platform, 'darwin') != -1:
+        elif sys.platform.find('darwin') != -1:
             return 'darwin'
         else:
             return 'posix'
@@ -94,7 +93,7 @@ def platform_module(name = platform_default()):
     our execution environment.
     """
     full_name = 'SCons.Platform.' + name
-    if not sys.modules.has_key(full_name):
+    if full_name not in sys.modules:
         if os.name == 'java':
             eval(full_name)
         else:
@@ -184,7 +183,7 @@ class TempFileMunge:
         if env['SHELL'] and env['SHELL'] == 'sh':
             # The sh shell will try to escape the backslashes in the
             # path, so unescape them.
-            native_tmp = string.replace(native_tmp, '\\', r'\\\\')
+            native_tmp = native_tmp.replace('\\', r'\\\\')
             # In Cygwin, we want to use rm to delete the temporary
             # file, because del does not exist in the sh shell.
             rm = env.Detect('rm') or 'del'
@@ -198,8 +197,8 @@ class TempFileMunge:
         if not prefix:
             prefix = '@'
 
-        args = map(SCons.Subst.quote_spaces, cmd[1:])
-        os.write(fd, string.join(args, " ") + "\n")
+        args = list(map(SCons.Subst.quote_spaces, cmd[1:]))
+        os.write(fd, " ".join(args) + "\n")
         os.close(fd)
         # XXX Using the SCons.Action.print_actions value directly
         # like this is bogus, but expedient.  This class should
@@ -218,7 +217,7 @@ class TempFileMunge:
         # reach into SCons.Action directly.
         if SCons.Action.print_actions:
             print("Using tempfile "+native_tmp+" for command line:\n"+
-                  str(cmd[0]) + " " + string.join(args," "))
+                  str(cmd[0]) + " " + " ".join(args))
         return [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
     
 def Platform(name = platform_default()):
diff --git a/src/engine/SCons/Platform/aix.py b/src/engine/SCons/Platform/aix.py
index a5f95731..0229112d 100644
--- a/src/engine/SCons/Platform/aix.py
+++ b/src/engine/SCons/Platform/aix.py
@@ -33,7 +33,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import posix
 
@@ -51,9 +50,9 @@ def get_xlc(env, xlc=None, xlc_r=None, packages=[]):
         cmd = "lslpp -fc " + package + " 2>/dev/null | egrep '" + xlc + "([^-_a-zA-Z0-9].*)?$'"
         line = os.popen(cmd).readline()
         if line:
-            v, p = string.split(line, ':')[1:3]
-            xlcVersion = string.split(v)[1]
-            xlcPath = string.split(p)[0]
+            v, p = line.split(':')[1:3]
+            xlcVersion = v.split()[1]
+            xlcPath = p.split()[0]
             xlcPath = xlcPath[:xlcPath.rindex('/')]
             break
     return (xlcPath, xlc, xlc_r, xlcVersion)
diff --git a/src/engine/SCons/Platform/os2.py b/src/engine/SCons/Platform/os2.py
index aa348d46..0fa45531 100644
--- a/src/engine/SCons/Platform/os2.py
+++ b/src/engine/SCons/Platform/os2.py
@@ -34,7 +34,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import win32
 
 def generate(env):
-    if not env.has_key('ENV'):
+    if 'ENV' not in env:
         env['ENV']        = {}
     env['OBJPREFIX']      = ''
     env['OBJSUFFIX']      = '.obj'
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py
index d1102b35..ece48d7d 100644
--- a/src/engine/SCons/Platform/posix.py
+++ b/src/engine/SCons/Platform/posix.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import errno
 import os
 import os.path
-import string
 import subprocess
 import sys
 import select
@@ -53,14 +52,14 @@ def escape(arg):
     slash = '\\'
     special = '"$()'
 
-    arg = string.replace(arg, slash, slash+slash)
+    arg = arg.replace(slash, slash+slash)
     for c in special:
-        arg = string.replace(arg, c, slash+c)
+        arg = arg.replace(c, slash+c)
 
     return '"' + arg + '"'
 
 def exec_system(l, env):
-    stat = os.system(string.join(l))
+    stat = os.system(' '.join(l))
     if stat & 0xff:
         return stat | 0x80
     return stat >> 8
@@ -90,22 +89,22 @@ def exec_fork(l, env):
         return stat >> 8
 
 def _get_env_command(sh, escape, cmd, args, env):
-    s = string.join(args)
+    s = ' '.join(args)
     if env:
         l = ['env', '-'] + \
-            map(lambda t, e=escape: e(t[0])+'='+e(t[1]), env.items()) + \
+            [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \
             [sh, '-c', escape(s)]
-        s = string.join(l)
+        s = ' '.join(l)
     return s
 
 def env_spawn(sh, escape, cmd, args, env):
     return exec_system([_get_env_command( sh, escape, cmd, args, env)], env)
 
 def spawnvpe_spawn(sh, escape, cmd, args, env):
-    return exec_spawnvpe([sh, '-c', string.join(args)], env)
+    return exec_spawnvpe([sh, '-c', ' '.join(args)], env)
 
 def fork_spawn(sh, escape, cmd, args, env):
-    return exec_fork([sh, '-c', string.join(args)], env)
+    return exec_fork([sh, '-c', ' '.join(args)], env)
 
 def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
     stdout_eof = stderr_eof = 0
@@ -131,7 +130,7 @@ def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
                 raise
 
 def exec_popen3(l, env, stdout, stderr):
-    proc = subprocess.Popen(string.join(l),
+    proc = subprocess.Popen(' '.join(l),
                             stdout=stdout,
                             stderr=stderr,
                             shell=True)
@@ -198,7 +197,7 @@ def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
 def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
     # spawn using fork / exec and providing a pipe for the command's
     # stdout / stderr stream
-    return exec_piped_fork([sh, '-c', string.join(args)],
+    return exec_piped_fork([sh, '-c', ' '.join(args)],
                            env, stdout, stderr)
 
 
@@ -217,7 +216,7 @@ def generate(env):
     # os.fork()/os.exec() works better than os.system().  There may just
     # not be a default that works best for all users.
 
-    if os.__dict__.has_key('spawnvpe'):
+    if 'spawnvpe' in os.__dict__:
         spawn = spawnvpe_spawn
     elif env.Detect('env'):
         spawn = env_spawn
@@ -229,7 +228,7 @@ def generate(env):
     else:
         pspawn = piped_fork_spawn
 
-    if not env.has_key('ENV'):
+    if 'ENV' not in env:
         env['ENV']        = {}
     env['ENV']['PATH']    = '/usr/local/bin:/opt/bin:/bin:/usr/bin'
     env['OBJPREFIX']      = ''
diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py
index a50a6ae1..52255ba6 100644
--- a/src/engine/SCons/Platform/win32.py
+++ b/src/engine/SCons/Platform/win32.py
@@ -34,7 +34,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import sys
 import tempfile
 
@@ -67,14 +66,14 @@ else:
     _builtin_open = __builtin__.open
     
     def _scons_file(*args, **kw):
-        fp = apply(_builtin_file, args, kw)
+        fp = _builtin_file(*args, **kw)
         win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
                                       win32con.HANDLE_FLAG_INHERIT,
                                       0)
         return fp
 
     def _scons_open(*args, **kw):
-        fp = apply(_builtin_open, args, kw)
+        fp = _builtin_open(*args, **kw)
         win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
                                       win32con.HANDLE_FLAG_INHERIT,
                                       0)
@@ -109,11 +108,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
         stderrRedirected = 0
         for arg in args:
             # are there more possibilities to redirect stdout ?
-            if (string.find( arg, ">", 0, 1 ) != -1 or
-                string.find( arg, "1>", 0, 2 ) != -1):
+            if (arg.find( ">", 0, 1 ) != -1 or
+                arg.find( "1>", 0, 2 ) != -1):
                 stdoutRedirected = 1
             # are there more possibilities to redirect stderr ?
-            if string.find( arg, "2>", 0, 2 ) != -1:
+            if arg.find( "2>", 0, 2 ) != -1:
                 stderrRedirected = 1
 
         # redirect output of non-redirected streams to our tempfiles
@@ -124,7 +123,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
 
         # actually do the spawn
         try:
-            args = [sh, '/C', escape(string.join(args)) ]
+            args = [sh, '/C', escape(' '.join(args)) ]
             ret = os.spawnve(os.P_WAIT, sh, args, env)
         except OSError, e:
             # catch any error
@@ -162,7 +161,7 @@ def exec_spawn(l, env):
             result = 127
             if len(l) > 2:
                 if len(l[2]) < 1000:
-                    command = string.join(l[0:3])
+                    command = ' '.join(l[0:3])
                 else:
                     command = l[0]
             else:
@@ -174,7 +173,7 @@ def spawn(sh, escape, cmd, args, env):
     if not sh:
         sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
         return 127
-    return exec_spawn([sh, '/C', escape(string.join(args))], env)
+    return exec_spawn([sh, '/C', escape(' '.join(args))], env)
 
 # Windows does not allow special characters in file names anyway, so no
 # need for a complex escape function, we will just quote the arg, except
@@ -318,7 +317,7 @@ def generate(env):
         tmp_path = systemroot + os.pathsep + \
                    os.path.join(systemroot,'System32')
         tmp_pathext = '.com;.exe;.bat;.cmd'
-        if os.environ.has_key('PATHEXT'):
+        if 'PATHEXT' in os.environ:
             tmp_pathext = os.environ['PATHEXT'] 
         cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
         if not cmd_interp:
@@ -330,7 +329,7 @@ def generate(env):
             cmd_interp = env.Detect('command')
 
     
-    if not env.has_key('ENV'):
+    if 'ENV' not in env:
         env['ENV']        = {}
 
     # Import things from the external environment to the construction
@@ -347,7 +346,7 @@ def generate(env):
         if v:
             env['ENV'][var] = v
 
-    if not env['ENV'].has_key('COMSPEC'):
+    if 'COMSPEC' not in env['ENV']:
         v = os.environ.get("COMSPEC")
         if v:
             env['ENV']['COMSPEC'] = v
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 133dab50..bd67ab25 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -30,7 +30,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import re
-import string
 import StringIO
 import sys
 import traceback
@@ -96,7 +95,7 @@ sconf_global = None   # current sconf object
 
 def _createConfigH(target, source, env):
     t = open(str(target[0]), "w")
-    defname = re.sub('[^A-Za-z0-9_]', '_', string.upper(str(target[0])))
+    defname = re.sub('[^A-Za-z0-9_]', '_', str(target[0]).upper())
     t.write("""#ifndef %(DEFNAME)s_SEEN
 #define %(DEFNAME)s_SEEN
 
@@ -153,8 +152,7 @@ def _createSource( target, source, env ):
     fd.close()
 def _stringSource( target, source, env ):
     return (str(target[0]) + ' <-\n  |' +
-            string.replace( source[0].get_contents(),
-                            '\n', "\n  |" ) )
+            source[0].get_contents().replace( '\n', "\n  |" ) )
 
 # python 2.2 introduces types.BooleanType
 BooleanTypes = [types.IntType]
@@ -222,8 +220,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
               "The stored build information has an unexpected class: %s" % bi.__class__)
         else:
             self.display("The original builder output was:\n" +
-                         string.replace("  |" + str(bi.string),
-                                        "\n", "\n  |"))
+                         ("  |" + str(bi.string)).replace("\n", "\n  |"))
 
     def failed(self):
         # check, if the reason was a ConfigureDryRunError or a
@@ -246,7 +243,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
                 def excepthook(type, value, tb):
                     traceback.print_tb(tb)
                     print type, value
-            apply(excepthook, self.exc_info())
+            excepthook(*self.exc_info())
         return SCons.Taskmaster.Task.failed(self)
 
     def collect_node_states(self):
@@ -465,7 +462,7 @@ class SConfBase:
         lines.append(define_str)
         lines.append('')
 
-        self.config_h_text = self.config_h_text + string.join(lines, '\n')
+        self.config_h_text = self.config_h_text + '\n'.join(lines)
 
     def BuildNodes(self, nodes):
         """
@@ -645,7 +642,7 @@ class SConfBase:
                 raise (SCons.Errors.UserError,
                        "Test called after sconf.Finish()")
             context = CheckContext(self.sconf)
-            ret = apply(self.test, (context,) +  args, kw)
+            ret = self.test(context, *args, **kw)
             if self.sconf.config_h is not None:
                 self.sconf.config_h_text = self.sconf.config_h_text + context.config_h
             context.Result("error: no result")
@@ -689,7 +686,7 @@ class SConfBase:
         if self.logfile is not None and not dryrun:
             # truncate logfile, if SConf.Configure is called for the first time
             # in a build
-            if _ac_config_logs.has_key(self.logfile):
+            if self.logfile in _ac_config_logs:
                 log_mode = "a"
             else:
                 _ac_config_logs[self.logfile] = None
@@ -804,19 +801,19 @@ class CheckContext:
             self.did_show_result = 1
 
     def TryBuild(self, *args, **kw):
-        return apply(self.sconf.TryBuild, args, kw)
+        return self.sconf.TryBuild(*args, **kw)
 
     def TryAction(self, *args, **kw):
-        return apply(self.sconf.TryAction, args, kw)
+        return self.sconf.TryAction(*args, **kw)
 
     def TryCompile(self, *args, **kw):
-        return apply(self.sconf.TryCompile, args, kw)
+        return self.sconf.TryCompile(*args, **kw)
 
     def TryLink(self, *args, **kw):
-        return apply(self.sconf.TryLink, args, kw)
+        return self.sconf.TryLink(*args, **kw)
 
     def TryRun(self, *args, **kw):
-        return apply(self.sconf.TryRun, args, kw)
+        return self.sconf.TryRun(*args, **kw)
 
     def __getattr__( self, attr ):
         if( attr == 'env' ):
@@ -889,7 +886,7 @@ def SConf(*args, **kw):
                 del kw[bt]
             except KeyError:
                 pass
-        return apply(SConfBase, args, kw)
+        return SConfBase(*args, **kw)
     else:
         return SCons.Util.Null()
 
@@ -901,7 +898,7 @@ def CheckFunc(context, function_name, header = None, language = None):
 
 def CheckType(context, type_name, includes = "", language = None):
     res = SCons.Conftest.CheckType(context, type_name,
-                                        header = includes, language = language)
+                                   header = includes, language = language)
     context.did_show_result = 1
     return not res
 
@@ -933,7 +930,7 @@ def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
     for s in headers:
         l.append("#include %s%s%s\n"
                  % (include_quotes[0], s, include_quotes[1]))
-    return string.join(l, ''), lastHeader
+    return ''.join(l), lastHeader
 
 def CheckHeader(context, header, include_quotes = '<>', language = None):
     """
diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py
index 45b6eef3..d0da84a9 100644
--- a/src/engine/SCons/SConfTests.py
+++ b/src/engine/SCons/SConfTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import re
-import string
 import StringIO
 import sys
 from types import *
@@ -60,7 +59,7 @@ class SConfTestCase(unittest.TestCase):
         import SCons.SConsign
         SCons.SConsign.write() # simulate normal scons-finish
         for n in sys.modules.keys():
-            if string.split(n, '.')[0] == 'SCons' and n[:12] != 'SCons.compat':
+            if n.split('.')[0] == 'SCons' and n[:12] != 'SCons.compat':
                 m = sys.modules[n]
                 if type(m) is ModuleType:
                     # if this is really a scons module, clear its namespace
diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py
index 9a020445..7ae584ae 100644
--- a/src/engine/SCons/SConsignTests.py
+++ b/src/engine/SCons/SConsignTests.py
@@ -386,7 +386,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py
index 622ac677..fd8d2f28 100644
--- a/src/engine/SCons/Scanner/C.py
+++ b/src/engine/SCons/Scanner/C.py
@@ -44,7 +44,7 @@ class SConsCPPScanner(SCons.cpp.PreProcessor):
     missing.
     """
     def __init__(self, *args, **kw):
-        apply(SCons.cpp.PreProcessor.__init__, (self,)+args, kw)
+        SCons.cpp.PreProcessor.__init__(self, *args, **kw)
         self.missing = []
     def initialize_result(self, fname):
         self.result = SCons.Util.UniqueList([fname])
diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py
index a62f4c1a..e92af248 100644
--- a/src/engine/SCons/Scanner/CTests.py
+++ b/src/engine/SCons/Scanner/CTests.py
@@ -192,7 +192,7 @@ class DummyEnvironment(UserDict.UserDict):
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def get_calculator(self):
         return None
@@ -213,8 +213,8 @@ else:
 
 def deps_match(self, deps, headers):
     global my_normpath
-    scanned = map(my_normpath, map(str, deps))
-    expect = map(my_normpath, headers)
+    scanned = list(map(my_normpath, list(map(str, deps))))
+    expect = list(map(my_normpath, headers))
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
 # define some tests:
@@ -310,7 +310,7 @@ class CScannerTestCase8(unittest.TestCase):
         env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
         deps2 = s(env.File('#fa.cpp'), env, path)
-        headers1 =  map(test.workpath, ['include/fa.h', 'include/fb.h'])
+        headers1 =  list(map(test.workpath, ['include/fa.h', 'include/fb.h']))
         headers2 =  ['include/fa.h', 'include/fb.h']
         deps_match(self, deps1, headers1)
         deps_match(self, deps2, headers2)
diff --git a/src/engine/SCons/Scanner/D.py b/src/engine/SCons/Scanner/D.py
index 4134337a..9402ed14 100644
--- a/src/engine/SCons/Scanner/D.py
+++ b/src/engine/SCons/Scanner/D.py
@@ -33,7 +33,6 @@ Coded by Andy Friesen
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 
 import SCons.Scanner
 
@@ -54,7 +53,7 @@ class D(SCons.Scanner.Classic):
 
     def find_include(self, include, source_dir, path):
         # translate dots (package separators) to slashes
-        inc = string.replace(include, '.', '/')
+        inc = include.replace('.', '/')
 
         i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path)
         if i is None:
diff --git a/src/engine/SCons/Scanner/Dir.py b/src/engine/SCons/Scanner/Dir.py
index a623c99c..6b7f05b9 100644
--- a/src/engine/SCons/Scanner/Dir.py
+++ b/src/engine/SCons/Scanner/Dir.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -28,21 +29,21 @@ import SCons.Scanner
 
 def only_dirs(nodes):
     is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
-    return filter(is_Dir, nodes)
+    return list(filter(is_Dir, nodes))
 
 def DirScanner(**kw):
     """Return a prototype Scanner instance for scanning
     directories for on-disk files"""
     kw['node_factory'] = SCons.Node.FS.Entry
     kw['recursive'] = only_dirs
-    return apply(SCons.Scanner.Base, (scan_on_disk, "DirScanner"), kw)
+    return SCons.Scanner.Base(scan_on_disk, "DirScanner", **kw)
 
 def DirEntryScanner(**kw):
     """Return a prototype Scanner instance for "scanning"
     directory Nodes for their in-memory entries"""
     kw['node_factory'] = SCons.Node.FS.Entry
     kw['recursive'] = None
-    return apply(SCons.Scanner.Base, (scan_in_memory, "DirEntryScanner"), kw)
+    return SCons.Scanner.Base(scan_in_memory, "DirEntryScanner", **kw)
 
 skip_entry = {}
 
@@ -67,7 +68,7 @@ for skip in skip_entry_list:
     skip_entry[skip] = 1
     skip_entry[SCons.Node.FS._my_normcase(skip)] = 1
 
-do_not_scan = lambda k: not skip_entry.has_key(k)
+do_not_scan = lambda k: k not in skip_entry
 
 def scan_on_disk(node, env, path=()):
     """
@@ -100,9 +101,9 @@ def scan_in_memory(node, env, path=()):
         # mixed Node types (Dirs and Files, for example) has a Dir as
         # the first entry.
         return []
-    entry_list = filter(do_not_scan, entries.keys())
+    entry_list = list(filter(do_not_scan, entries.keys()))
     entry_list.sort()
-    return map(lambda n, e=entries: e[n], entry_list)
+    return [entries[n] for n in entry_list]
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Scanner/DirTests.py b/src/engine/SCons/Scanner/DirTests.py
index 5d59bd56..0ad1cfe7 100644
--- a/src/engine/SCons/Scanner/DirTests.py
+++ b/src/engine/SCons/Scanner/DirTests.py
@@ -24,7 +24,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 import sys
 import types
 import unittest
@@ -91,7 +90,7 @@ class DirScannerTestCase(DirScannerTestBase):
             os.path.join('dir', 'sub'),
         ]
         deps = s(env.Dir('dir'), env, ())
-        sss = map(str, deps)
+        sss = list(map(str, deps))
         assert sss == expect, sss
 
         expect = [
@@ -99,7 +98,7 @@ class DirScannerTestCase(DirScannerTestBase):
             os.path.join('dir', 'sub', 'f4'),
         ]
         deps = s(env.Dir('dir/sub'), env, ())
-        sss = map(str, deps)
+        sss = list(map(str, deps))
         assert sss == expect, sss
 
 class DirEntryScannerTestCase(DirScannerTestBase):
@@ -109,16 +108,16 @@ class DirEntryScannerTestCase(DirScannerTestBase):
         s = SCons.Scanner.Dir.DirEntryScanner()
 
         deps = s(env.Dir('dir'), env, ())
-        sss = map(str, deps)
+        sss = list(map(str, deps))
         assert sss == [], sss
 
         deps = s(env.Dir('dir/sub'), env, ())
-        sss = map(str, deps)
+        sss = list(map(str, deps))
         assert sss == [], sss
 
         # Make sure we don't blow up if handed a non-Dir node.
         deps = s(env.File('dir/f1'), env, ())
-        sss = map(str, deps)
+        sss = list(map(str, deps))
         assert sss == [], sss
 
 def suite():
diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py
index 2aed6538..fd6a0148 100644
--- a/src/engine/SCons/Scanner/Fortran.py
+++ b/src/engine/SCons/Scanner/Fortran.py
@@ -26,11 +26,11 @@ This module implements the dependency scanner for Fortran code.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 
 import SCons.Node
 import SCons.Node.FS
@@ -75,7 +75,7 @@ class F90Scanner(SCons.Scanner.Classic):
         kw['skeys'] = suffixes
         kw['name'] = name
 
-        apply(SCons.Scanner.Current.__init__, (self,) + args, kw)
+        SCons.Scanner.Current.__init__(self, *args, **kw)
 
     def scan(self, node, env, path=()):
 
@@ -94,12 +94,12 @@ class F90Scanner(SCons.Scanner.Classic):
             d = {}
             for m in defmodules:
                 d[m] = 1
-            modules = filter(lambda m, d=d: not d.has_key(m), modules)
+            modules = [m for m in modules if m not in d]
             #modules = self.undefinedModules(modules, defmodules)
 
             # Convert module name to a .mod filename
             suffix = env.subst('$FORTRANMODSUFFIX')
-            modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+            modules = [x.lower() + suffix for x in modules]
             # Remove unique items from the list
             mods_and_includes = SCons.Util.unique(includes+modules)
             node.includes = mods_and_includes
@@ -124,7 +124,7 @@ class F90Scanner(SCons.Scanner.Classic):
                 nodes.append((sortkey, n))
 
         nodes.sort()
-        nodes = map(lambda pair: pair[1], nodes)
+        nodes = [pair[1] for pair in nodes]
         return nodes
 
 def FortranScan(path_variable="FORTRANPATH"):
diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py
index 570b5658..0380e87f 100644
--- a/src/engine/SCons/Scanner/FortranTests.py
+++ b/src/engine/SCons/Scanner/FortranTests.py
@@ -221,7 +221,7 @@ class DummyEnvironment:
             raise KeyError, "Dummy environment only has FORTRANPATH attribute."
 
     def has_key(self, key):
-        return self.Dictionary().has_key(key)
+        return key in self.Dictionary()
 
     def __getitem__(self,key):
         return self.Dictionary()[key]
@@ -240,7 +240,7 @@ class DummyEnvironment:
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def get_calculator(self):
         return None
@@ -255,8 +255,8 @@ class DummyEnvironment:
         return self.fs.File(filename)
 
 def deps_match(self, deps, headers):
-    scanned = map(os.path.normpath, map(str, deps))
-    expect = map(os.path.normpath, headers)
+    scanned = list(map(os.path.normpath, list(map(str, deps))))
+    expect = list(map(os.path.normpath, headers))
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
 # define some tests:
@@ -382,7 +382,7 @@ class FortranScannerTestCase10(unittest.TestCase):
         env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
         deps2 = s(env.File('#fff4.f'), env, path)
-        headers1 =  map(test.workpath, ['include/f4.f'])
+        headers1 =  list(map(test.workpath, ['include/f4.f']))
         headers2 =  ['include/f4.f']
         deps_match(self, deps1, headers1)
         deps_match(self, deps2, headers2)
diff --git a/src/engine/SCons/Scanner/IDLTests.py b/src/engine/SCons/Scanner/IDLTests.py
index a454b31d..26b3956b 100644
--- a/src/engine/SCons/Scanner/IDLTests.py
+++ b/src/engine/SCons/Scanner/IDLTests.py
@@ -205,10 +205,10 @@ class DummyEnvironment:
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def has_key(self, key):
-        return self.Dictionary().has_key(key)
+        return key in self.Dictionary()
 
     def __getitem__(self,key):
         return self.Dictionary()[key]
@@ -238,8 +238,8 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
     my_normpath = os.path.normcase
 
 def deps_match(self, deps, headers):
-    scanned = map(my_normpath, map(str, deps))
-    expect = map(my_normpath, headers)
+    scanned = list(map(my_normpath, list(map(str, deps))))
+    expect = list(map(my_normpath, headers))
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
 # define some tests:
@@ -329,7 +329,7 @@ class IDLScannerTestCase7(unittest.TestCase):
         env.fs.chdir(env.Dir(''))
         path = s.path(env, dir)
         deps2 = s(env.File('#t4.idl'), env, path)
-        headers1 =  map(test.workpath, ['include/fa.idl', 'include/fb.idl'])
+        headers1 =  list(map(test.workpath, ['include/fa.idl', 'include/fb.idl']))
         headers2 =  ['include/fa.idl', 'include/fb.idl']
         deps_match(self, deps1, headers1)
         deps_match(self, deps2, headers2)
diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py
index 17000a2c..f3085d1b 100644
--- a/src/engine/SCons/Scanner/LaTeX.py
+++ b/src/engine/SCons/Scanner/LaTeX.py
@@ -30,7 +30,6 @@ This module implements the dependency scanner for LaTeX code.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 import re
 
 import SCons.Scanner
@@ -60,11 +59,11 @@ def modify_env_var(env, var, abspath):
         if SCons.Util.is_List(env[var]):
             #TODO(1.5)
             #env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
-            env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var]))
+            env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
         else:
             # Split at os.pathsep to convert into absolute path
             #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
-            env.PrependENVPath(var, map(lambda p: os.path.abspath(p), string.split(str(env[var]), os.pathsep)))
+            env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
     except KeyError:
         pass
 
@@ -75,7 +74,7 @@ def modify_env_var(env, var, abspath):
     if SCons.Util.is_List(env['ENV'][var]):
         # TODO(1.5)
         #env['ENV'][var] = os.pathsep.join(env['ENV'][var])
-        env['ENV'][var] = string.join(env['ENV'][var], os.pathsep)
+        env['ENV'][var] = os.pathsep.join(env['ENV'][var])
     # Append the trailing os.pathsep character here to catch the case with no env[var]
     env['ENV'][var] = env['ENV'][var] + os.pathsep
 
@@ -231,7 +230,7 @@ class LaTeX(SCons.Scanner.Base):
         kw['scan_check'] = LaTeXScanCheck(suffixes)
         kw['name'] = name
 
-        apply(SCons.Scanner.Base.__init__, (self,) + args, kw)
+        SCons.Scanner.Base.__init__(self, *args, **kw)
 
     def _latex_names(self, include):
         filename = include[1]
@@ -253,10 +252,10 @@ class LaTeX(SCons.Scanner.Base):
             base, ext = os.path.splitext( filename )
             if ext == "":
                 #TODO(1.5) return [filename + e for e in self.graphics_extensions]
-                #return map(lambda e, f=filename: f+e, self.graphics_extensions + TexGraphics)
+                #return map(lambda e: filename+e, self.graphics_extensions + TexGraphics)
                 # use the line above to find dependency for PDF builder when only .eps figure is present
                 # Since it will be found if the user tell scons how to make the pdf figure leave it out for now.
-                return map(lambda e, f=filename: f+e, self.graphics_extensions)
+                return [filename+e for e in self.graphics_extensions]
         return [filename]
 
     def sort_key(self, include):
@@ -303,7 +302,7 @@ class LaTeX(SCons.Scanner.Base):
             split_includes = []
             for include in includes:
                 inc_type = noopt_cre.sub('', include[0])
-                inc_list = string.split(include[1],',')
+                inc_list = include[1].split(',')
                 for j in range(len(inc_list)):
                     split_includes.append( (inc_type, inc_list[j]) )
             #
@@ -368,7 +367,7 @@ class LaTeX(SCons.Scanner.Base):
 
         #
         nodes.sort()
-        nodes = map(lambda pair: pair[1], nodes)
+        nodes = [pair[1] for pair in nodes]
         return nodes
 
 # Local Variables:
diff --git a/src/engine/SCons/Scanner/LaTeXTests.py b/src/engine/SCons/Scanner/LaTeXTests.py
index e87a1aa4..ac978cf9 100644
--- a/src/engine/SCons/Scanner/LaTeXTests.py
+++ b/src/engine/SCons/Scanner/LaTeXTests.py
@@ -24,7 +24,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 import sys
 import types
 import unittest
@@ -88,7 +87,7 @@ class DummyEnvironment(UserDict.UserDict):
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def get_calculator(self):
         return None
@@ -109,8 +108,8 @@ else:
 
 def deps_match(self, deps, headers):
     global my_normpath
-    scanned = map(my_normpath, map(str, deps))
-    expect = map(my_normpath, headers)
+    scanned = list(map(my_normpath, list(map(str, deps))))
+    expect = list(map(my_normpath, headers))
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
 
 
diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py
index bd7bffe2..49e93a56 100644
--- a/src/engine/SCons/Scanner/Prog.py
+++ b/src/engine/SCons/Scanner/Prog.py
@@ -23,8 +23,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import SCons.Node
 import SCons.Node.FS
 import SCons.Scanner
@@ -37,7 +35,7 @@ def ProgramScanner(**kw):
     """Return a prototype Scanner instance for scanning executable
     files for static-lib dependencies"""
     kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH')
-    ps = apply(SCons.Scanner.Base, [scan, "ProgramScanner"], kw)
+    ps = SCons.Scanner.Base(scan, "ProgramScanner", **kw)
     return ps
 
 def scan(node, env, libpath = ()):
@@ -53,7 +51,7 @@ def scan(node, env, libpath = ()):
         # There are no LIBS in this environment, so just return a null list:
         return []
     if SCons.Util.is_String(libs):
-        libs = string.split(libs)
+        libs = libs.split()
     else:
         libs = SCons.Util.flatten(libs)
 
diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py
index 7eaafcc7..ee62ca75 100644
--- a/src/engine/SCons/Scanner/ProgTests.py
+++ b/src/engine/SCons/Scanner/ProgTests.py
@@ -24,7 +24,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 import sys
 import types
 import unittest
@@ -57,10 +56,10 @@ class DummyEnvironment:
         elif len(args) == 1:
             return self._dict[args[0]]
         else:
-            return map(lambda x, s=self: s._dict[x], args)
+            return [self._dict[x] for x in args]
 
     def has_key(self, key):
-        return self.Dictionary().has_key(key)
+        return key in self.Dictionary()
 
     def __getitem__(self,key):
         return self.Dictionary()[key]
@@ -82,7 +81,7 @@ class DummyEnvironment:
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def get_factory(self, factory):
         return factory or self.fs.File
@@ -102,10 +101,10 @@ class DummyNode:
         return self.name
     
 def deps_match(deps, libs):
-    deps=map(str, deps)
+    deps=list(map(str, deps))
     deps.sort()
     libs.sort()
-    return map(os.path.normpath, deps) == map(os.path.normpath, libs)
+    return list(map(os.path.normpath, deps)) == list(map(os.path.normpath, libs))
 
 # define some tests:
 
@@ -116,14 +115,14 @@ class ProgramScannerTestCase1(unittest.TestCase):
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['l1.lib']), map(str, deps)
+        assert deps_match(deps, ['l1.lib']), list(map(str, deps))
 
         env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
                                LIBS='l1')
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['l1.lib']), map(str, deps)
+        assert deps_match(deps, ['l1.lib']), list(map(str, deps))
 
         f1 = env.fs.File(test.workpath('f1'))
         env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
@@ -144,23 +143,23 @@ class ProgramScannerTestCase1(unittest.TestCase):
 
 class ProgramScannerTestCase2(unittest.TestCase):
     def runTest(self):
-        env = DummyEnvironment(LIBPATH=map(test.workpath,
-                                           ["", "d1", "d1/d2" ]),
+        env = DummyEnvironment(LIBPATH=list(map(test.workpath,
+                                           ["", "d1", "d1/d2" ])),
                                LIBS=[ 'l1', 'l2', 'l3' ])
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), map(str, deps)
+        assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), list(map(str, deps))
 
 class ProgramScannerTestCase3(unittest.TestCase):
     def runTest(self):
         env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"),
                                         test.workpath("d1")],
-                               LIBS=string.split('l2 l3'))
+                               LIBS='l2 l3'.split())
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
+        assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), list(map(str, deps))
 
 class ProgramScannerTestCase5(unittest.TestCase):
     def runTest(self):
@@ -171,11 +170,11 @@ class ProgramScannerTestCase5(unittest.TestCase):
                 else:
                     return arg
         env = SubstEnvironment(LIBPATH=[ "$blah" ],
-                               LIBS=string.split('l2 l3'))
+                               LIBS='l2 l3'.split())
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, [ 'd1/l2.lib' ]), map(str, deps)
+        assert deps_match(deps, [ 'd1/l2.lib' ]), list(map(str, deps))
 
 class ProgramScannerTestCase6(unittest.TestCase):
     def runTest(self):
@@ -186,7 +185,7 @@ class ProgramScannerTestCase6(unittest.TestCase):
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), map(str, deps)
+        assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps))
 
 class ProgramScannerTestCase7(unittest.TestCase):
     def runTest(self):
@@ -199,7 +198,7 @@ class ProgramScannerTestCase7(unittest.TestCase):
         s = SCons.Scanner.Prog.ProgramScanner()
         path = s.path(env)
         deps = s(DummyNode('dummy'), env, path)
-        assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), map(str, deps)
+        assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps))
 
 class ProgramScannerTestCase8(unittest.TestCase):
     def runTest(self):
@@ -239,7 +238,7 @@ def suite():
                 def runTest(self):
                     env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"),
                                                     test.workpath("d1")],
-                                           LIBS=string.split(u'l2 l3'))
+                                           LIBS=u'l2 l3'.split())
                     s = SCons.Scanner.Prog.ProgramScanner()
                     path = s.path(env)
                     deps = s(DummyNode('dummy'), env, path)
diff --git a/src/engine/SCons/Scanner/RCTests.py b/src/engine/SCons/Scanner/RCTests.py
index bf1048d0..a20c9199 100644
--- a/src/engine/SCons/Scanner/RCTests.py
+++ b/src/engine/SCons/Scanner/RCTests.py
@@ -88,10 +88,10 @@ class DummyEnvironment(UserDict.UserDict):
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
 
     def has_key(self, key):
-        return self.Dictionary().has_key(key)
+        return key in self.Dictionary()
 
     def get_calculator(self):
         return None
@@ -112,8 +112,8 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
     my_normpath = os.path.normcase
 
 def deps_match(self, deps, headers):
-    scanned = map(my_normpath, map(str, deps))
-    expect = map(my_normpath, headers)
+    scanned = list(map(my_normpath, list(map(str, deps))))
+    expect = list(map(my_normpath, headers))
     scanned.sort()
     expect.sort()
     self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py
index 518e0ed4..d89fb149 100644
--- a/src/engine/SCons/Scanner/ScannerTests.py
+++ b/src/engine/SCons/Scanner/ScannerTests.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -49,7 +50,7 @@ class DummyEnvironment(UserDict.UserDict):
     def subst_path(self, path, target=None, source=None, conv=None):
         if type(path) != type([]):
             path = [path]
-        return map(self.subst, path)
+        return list(map(self.subst, path))
     def get_factory(self, factory):
         return factory or self.fs.File
 
@@ -127,7 +128,7 @@ class BaseTestCase(unittest.TestCase):
         self.deps = deps
         path = scanner.path(env)
         scanned = scanner(filename, env, path)
-        scanned_strs = map(lambda x: str(x), scanned)
+        scanned_strs = [str(x) for x in scanned]
 
         self.failUnless(self.filename == filename, "the filename was passed incorrectly")
         self.failUnless(self.env == env, "the environment was passed incorrectly")
@@ -280,7 +281,7 @@ class BaseTestCase(unittest.TestCase):
                         "recursive = 1 didn't return all nodes: %s" % n)
 
         def odd_only(nodes):
-            return filter(lambda n: n % 2, nodes)
+            return [n for n in nodes if n % 2]
         s = SCons.Scanner.Base(function = self.func, recursive = odd_only)
         n = s.recurse_nodes(nodes)
         self.failUnless(n == [1, 3],
@@ -595,7 +596,7 @@ def suite():
                ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     return suite
 
 if __name__ == "__main__":
diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py
index da820602..be08256d 100644
--- a/src/engine/SCons/Scanner/__init__.py
+++ b/src/engine/SCons/Scanner/__init__.py
@@ -30,7 +30,6 @@ The Scanner package for the SCons software construction utility.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 
 import SCons.Node.FS
 import SCons.Util
@@ -56,9 +55,9 @@ def Scanner(function, *args, **kw):
     patterned on SCons code.
     """
     if SCons.Util.is_Dict(function):
-        return apply(Selector, (function,) + args, kw)
+        return Selector(function, *args, **kw)
     else:
-        return apply(Base, (function,) + args, kw)
+        return Base(function, *args, **kw)
 
 
 
@@ -218,7 +217,7 @@ class Base:
         nodes = []
         for l in list:
             if self.node_class and not isinstance(l, self.node_class):
-                l = apply(node_factory, (l,), kw)
+                l = node_factory(l, **kw)
             nodes.append(l)
         return nodes
 
@@ -280,7 +279,7 @@ class Selector(Base):
     for custom modules that may be out there.)
     """
     def __init__(self, dict, *args, **kw):
-        apply(Base.__init__, (self, None,)+args, kw)
+        Base.__init__(self, None, *args, **kw)
         self.dict = dict
         self.skeys = dict.keys()
 
@@ -309,7 +308,7 @@ class Current(Base):
         def current_check(node, env):
             return not node.has_builder() or node.is_up_to_date()
         kw['scan_check'] = current_check
-        apply(Base.__init__, (self,) + args, kw)
+        Base.__init__(self, *args, **kw)
 
 class Classic(Current):
     """
@@ -339,7 +338,7 @@ class Classic(Current):
         kw['skeys'] = suffixes
         kw['name'] = name
 
-        apply(Current.__init__, (self,) + args, kw)
+        Current.__init__(self, *args, **kw)
 
     def find_include(self, include, source_dir, path):
         n = SCons.Node.FS.find_file(include, (source_dir,) + tuple(path))
@@ -360,7 +359,7 @@ class Classic(Current):
             includes = self.find_include_names (node)
             # Intern the names of the include files. Saves some memory
             # if the same header is included many times.
-            node.includes = map(SCons.Util.silent_intern, includes)
+            node.includes = list(map(SCons.Util.silent_intern, includes))
 
         # This is a hand-coded DSU (decorate-sort-undecorate, or
         # Schwartzian transform) pattern.  The sort key is the raw name
@@ -383,7 +382,7 @@ class Classic(Current):
                 nodes.append((sortkey, n))
 
         nodes.sort()
-        nodes = map(lambda pair: pair[1], nodes)
+        nodes = [pair[1] for pair in nodes]
         return nodes
 
 class ClassicCPP(Classic):
@@ -408,7 +407,7 @@ class ClassicCPP(Classic):
         return n, i
 
     def sort_key(self, include):
-        return SCons.Node.FS._my_normcase(string.join(include))
+        return SCons.Node.FS._my_normcase(' '.join(include))
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py
index 206f9410..c546fc90 100644
--- a/src/engine/SCons/Script/Interactive.py
+++ b/src/engine/SCons/Script/Interactive.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -90,7 +91,6 @@ import copy
 import os
 import re
 import shlex
-import string
 import sys
 
 try:
@@ -134,7 +134,7 @@ class SConsInteractiveCmd(cmd.Cmd):
         print "*** Unknown command: %s" % argv[0]
 
     def onecmd(self, line):
-        line = string.strip(line)
+        line = line.strip()
         if not line:
             print self.lastcmd
             return self.emptyline()
@@ -144,7 +144,7 @@ class SConsInteractiveCmd(cmd.Cmd):
         elif line[0] == '?':
             line = 'help ' + line[1:]
         if os.sep == '\\':
-            line = string.replace(line, '\\', '\\\\')
+            line = line.replace('\\', '\\\\')
         argv = shlex.split(line)
         argv[0] = self.synonyms.get(argv[0], argv[0])
         if not argv[0]:
@@ -222,8 +222,8 @@ class SConsInteractiveCmd(cmd.Cmd):
 
         def get_unseen_children(node, parent, seen_nodes=seen_nodes):
             def is_unseen(node, seen_nodes=seen_nodes):
-                return not seen_nodes.has_key(node)
-            return filter(is_unseen, node.children(scan=1))
+                return node not in seen_nodes
+            return list(filter(is_unseen, node.children(scan=1)))
 
         def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
             seen_nodes[node] = 1
@@ -307,7 +307,7 @@ class SConsInteractiveCmd(cmd.Cmd):
 
     def _strip_initial_spaces(self, s):
         #lines = s.split('\n')
-        lines = string.split(s, '\n')
+        lines = s.split('\n')
         spaces = re.match(' *', lines[0]).group(0)
         #def strip_spaces(l):
         #    if l.startswith(spaces):
@@ -318,8 +318,8 @@ class SConsInteractiveCmd(cmd.Cmd):
             if l[:len(spaces)] == spaces:
                 l = l[len(spaces):]
             return l
-        lines = map(strip_spaces, lines)
-        return string.join(lines, '\n')
+        lines = list(map(strip_spaces, lines))
+        return '\n'.join(lines)
 
     def do_exit(self, argv):
         """\
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 082de341..7173f1b4 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -33,12 +33,12 @@ it goes here.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import sys
 import time
 import traceback
@@ -107,7 +107,7 @@ class Progressor:
             self.func = obj
         elif SCons.Util.is_List(obj):
             self.func = self.spinner
-        elif string.find(obj, self.target_string) != -1:
+        elif obj.find(self.target_string) != -1:
             self.func = self.replace_string
         else:
             self.func = self.string
@@ -132,7 +132,7 @@ class Progressor:
         self.write(self.obj)
 
     def replace_string(self, node):
-        self.write(string.replace(self.obj, self.target_string, str(node)))
+        self.write(self.obj.replace(self.target_string, str(node)))
 
     def __call__(self, node):
         self.count = self.count + 1
@@ -145,7 +145,7 @@ ProgressObject = SCons.Util.Null()
 
 def Progress(*args, **kw):
     global ProgressObject
-    ProgressObject = apply(Progressor, args, kw)
+    ProgressObject = Progressor(*args, **kw)
 
 # Task control.
 #
@@ -208,7 +208,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
         if self.top and not t.has_builder() and not t.side_effect:
             if not t.exists():
                 def classname(obj):
-                    return string.split(str(obj.__class__), '.')[-1]
+                    return str(obj.__class__).split('.')[-1]
                 if classname(t) in ('File', 'Dir', 'Entry'):
                     errstr="Do not know how to make %s target `%s' (%s)." % (classname(t), t, t.abspath)
                 else: # Alias or Python or ...
@@ -262,7 +262,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
         node = buildError.node
         if not SCons.Util.is_List(node):
                 node = [ node ]
-        nodename = string.join(map(str, node), ', ')
+        nodename = ', '.join(map(str, node))
 
         errfmt = "scons: *** [%s] %s\n"
         sys.stderr.write(errfmt % (nodename, buildError))
@@ -345,7 +345,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
             for t in self.targets:
                 if not t.isdir():
                     display("Removed " + str(t))
-        if SCons.Environment.CleanTargets.has_key(target):
+        if target in SCons.Environment.CleanTargets:
             files = SCons.Environment.CleanTargets[target]
             for f in files:
                 self.fs_delete(f.abspath, str(f), 0)
@@ -366,7 +366,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
                 else:
                     if removed:
                         display("Removed " + str(t))
-        if SCons.Environment.CleanTargets.has_key(target):
+        if target in SCons.Environment.CleanTargets:
             files = SCons.Environment.CleanTargets[target]
             for f in files:
                 self.fs_delete(f.abspath, str(f))
@@ -414,7 +414,7 @@ class TreePrinter:
         return node.all_children()
     def get_derived_children(self, node):
         children = node.all_children(None)
-        return filter(lambda x: x.has_builder(), children)
+        return [x for x in children if x.has_builder()]
     def display(self, t):
         if self.derived:
             func = self.get_derived_children
@@ -425,7 +425,7 @@ class TreePrinter:
 
 
 def python_version_string():
-    return string.split(sys.version)[0]
+    return sys.version.split()[0]
 
 def python_version_unsupported(version=sys.version_info):
     return version < (1, 5, 2)
@@ -469,9 +469,9 @@ class FakeOptionParser:
 OptionsParser = FakeOptionParser()
 
 def AddOption(*args, **kw):
-    if not kw.has_key('default'):
+    if 'default' not in kw:
         kw['default'] = None
-    result = apply(OptionsParser.add_local_option, args, kw)
+    result = OptionsParser.add_local_option(*args, **kw)
     return result
 
 def GetOption(name):
@@ -501,7 +501,7 @@ class CountStats(Stats):
     def do_print(self):
         stats_table = {}
         for s in self.stats:
-            for n in map(lambda t: t[0], s):
+            for n in [t[0] for t in s]:
                 stats_table[n] = [0, 0, 0, 0]
         i = 0
         for s in self.stats:
@@ -514,12 +514,12 @@ class CountStats(Stats):
         pre = ["   "]
         post = ["   %s\n"]
         l = len(self.stats)
-        fmt1 = string.join(pre + [' %7s']*l + post, '')
-        fmt2 = string.join(pre + [' %7d']*l + post, '')
+        fmt1 = ''.join(pre + [' %7s']*l + post)
+        fmt2 = ''.join(pre + [' %7d']*l + post)
         labels = self.labels[:l]
         labels.append(("", "Class"))
-        self.outfp.write(fmt1 % tuple(map(lambda x: x[0], labels)))
-        self.outfp.write(fmt1 % tuple(map(lambda x: x[1], labels)))
+        self.outfp.write(fmt1 % tuple([x[0] for x in labels]))
+        self.outfp.write(fmt1 % tuple([x[1] for x in labels]))
         for k in keys:
             r = stats_table[k][:l] + [k]
             self.outfp.write(fmt2 % tuple(r))
@@ -563,7 +563,7 @@ def find_deepest_user_frame(tb):
     # of SCons:
     for frame in tb:
         filename = frame[0]
-        if string.find(filename, os.sep+'SCons'+os.sep) == -1:
+        if filename.find(os.sep+'SCons'+os.sep) == -1:
             return frame
     return tb[0]
 
@@ -1087,7 +1087,7 @@ def _build_targets(fs, options, targets, target_top):
                         # or not a file, so go ahead and keep it as a default
                         # target and let the engine sort it out:
                         return 1                
-                d = filter(check_dir, SCons.Script.DEFAULT_TARGETS)
+                d = list(filter(check_dir, SCons.Script.DEFAULT_TARGETS))
                 SCons.Script.DEFAULT_TARGETS[:] = d
                 target_top = None
                 lookup_top = None
@@ -1122,7 +1122,7 @@ def _build_targets(fs, options, targets, target_top):
                 node = None
         return node
 
-    nodes = filter(None, map(Entry, targets))
+    nodes = [_f for _f in map(Entry, targets) if _f]
 
     task_class = BuildTask      # default action is to build targets
     opening_message = "Building targets ..."
@@ -1224,7 +1224,7 @@ def _build_targets(fs, options, targets, target_top):
 
 def _exec_main(parser, values):
     sconsflags = os.environ.get('SCONSFLAGS', '')
-    all_args = string.split(sconsflags) + sys.argv[1:]
+    all_args = sconsflags.split() + sys.argv[1:]
 
     options, args = parser.parse_args(all_args, values)
 
@@ -1285,7 +1285,7 @@ def main():
         pass 
     parts.append(version_string("engine", SCons))
     parts.append("__COPYRIGHT__")
-    version = string.join(parts, '')
+    version = ''.join(parts)
 
     import SConsOptions
     parser = SConsOptions.Parser(version)
diff --git a/src/engine/SCons/Script/MainTests.py b/src/engine/SCons/Script/MainTests.py
index 4fe760c4..c44c4268 100644
--- a/src/engine/SCons/Script/MainTests.py
+++ b/src/engine/SCons/Script/MainTests.py
@@ -42,7 +42,7 @@ if __name__ == "__main__":
     tclasses = []
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py
index 1ffcc830..0f364d6a 100644
--- a/src/engine/SCons/Script/SConsOptions.py
+++ b/src/engine/SCons/Script/SConsOptions.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import optparse
 import re
-import string
 import sys
 import textwrap
 
@@ -55,9 +54,10 @@ def diskcheck_convert(value):
     if value is None:
         return []
     if not SCons.Util.is_List(value):
-        value = string.split(value, ',')
+        value = value.split(',')
     result = []
-    for v in map(string.lower, value):
+    for v in value:
+        v = v.lower()
         if v == 'all':
             result = diskcheck_all
         elif v == 'none':
@@ -168,7 +168,7 @@ class SConsValues(optparse.Values):
                 value = diskcheck_convert(value)
             except ValueError, v:
                 raise SCons.Errors.UserError, "Not a valid diskcheck value: %s"%v
-            if not self.__dict__.has_key('diskcheck'):
+            if 'diskcheck' not in self.__dict__:
                 # No --diskcheck= option was specified on the command line.
                 # Set this right away so it can affect the rest of the
                 # file/Node lookups while processing the SConscript files.
@@ -197,7 +197,7 @@ class SConsOption(optparse.Option):
             if self.nargs in (1, '?'):
                 return self.check_value(opt, value)
             else:
-                return tuple(map(lambda v, o=opt, s=self: s.check_value(o, v), value))
+                return tuple([self.check_value(opt, v) for v in value])
 
     def process(self, opt, value, values, parser):
 
@@ -292,7 +292,7 @@ class SConsOptionParser(optparse.OptionParser):
         # Value explicitly attached to arg?  Pretend it's the next
         # argument.
         if "=" in arg:
-            (opt, next_arg) = string.split(arg, "=", 1)
+            (opt, next_arg) = arg.split("=", 1)
             rargs.insert(0, next_arg)
             had_explicit_value = True
         else:
@@ -356,7 +356,7 @@ class SConsOptionParser(optparse.OptionParser):
             group = self.add_option_group(group)
             self.local_option_group = group
 
-        result = apply(group.add_option, args, kw)
+        result = group.add_option(*args, **kw)
 
         if result:
             # The option was added succesfully.  We now have to add the
@@ -461,7 +461,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
                 result.append("%*s%s\n" % (self.help_position, "", line))
         elif opts[-1] != "\n":
             result.append("\n")
-        return string.join(result, "")
+        return "".join(result)
 
     # For consistent help output across Python versions, we provide a
     # subclass copy of format_option_strings() and these two variables.
@@ -473,7 +473,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
     def format_option_strings(self, option):
         """Return a comma-separated list of option strings & metavariables."""
         if option.takes_value():
-            metavar = option.metavar or string.upper(option.dest)
+            metavar = option.metavar or option.dest.upper()
             short_opts = []
             for sopt in option._short_opts:
                 short_opts.append(self._short_opt_fmt % (sopt, metavar))
@@ -489,7 +489,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
         else:
             opts = long_opts + short_opts
 
-        return string.join(opts, ", ")
+        return ", ".join(opts)
 
 def Parser(version):
     """
@@ -580,7 +580,7 @@ def Parser(version):
             raise OptionValueError("Warning:  %s is not a valid config type" % value)
         setattr(parser.values, option.dest, value)
     opt_config_help = "Controls Configure subsystem: %s." \
-                      % string.join(config_options, ", ")
+                      % ", ".join(config_options)
     op.add_option('--config',
                   nargs=1, type="string",
                   dest="config", default="auto",
@@ -623,7 +623,7 @@ def Parser(version):
         else:
             raise OptionValueError("Warning:  %s is not a valid debug type" % value)
     opt_debug_help = "Print various types of debugging information: %s." \
-                     % string.join(debug_options, ", ")
+                     % ", ".join(debug_options)
     op.add_option('--debug',
                   nargs=1, type="string",
                   dest="debug", default=[],
@@ -654,7 +654,7 @@ def Parser(version):
         SCons.Node.FS.set_duplicate(value)
 
     opt_duplicate_help = "Set the preferred duplication methods. Must be one of " \
-                         + string.join(SCons.Node.FS.Valid_Duplicates, ", ")
+                         + ", ".join(SCons.Node.FS.Valid_Duplicates)
 
     op.add_option('--duplicate',
                   nargs=1, type="string",
@@ -802,7 +802,7 @@ def Parser(version):
     def opt_tree(option, opt, value, parser, tree_options=tree_options):
         import Main
         tp = Main.TreePrinter()
-        for o in string.split(value, ','):
+        for o in value.split(','):
             if o == 'all':
                 tp.derived = False
             elif o == 'derived':
@@ -816,7 +816,7 @@ def Parser(version):
         parser.values.tree_printers.append(tp)
 
     opt_tree_help = "Print a dependency tree in various formats: %s." \
-                    % string.join(tree_options, ", ")
+                    % ", ".join(tree_options)
 
     op.add_option('--tree',
                   nargs=1, type="string",
@@ -846,7 +846,7 @@ def Parser(version):
 
     def opt_warn(option, opt, value, parser, tree_options=tree_options):
         if SCons.Util.is_String(value):
-            value = string.split(value, ',')
+            value = value.split(',')
         parser.values.warn.extend(value)
 
     op.add_option('--warn', '--warning',
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index a34278a6..10219210 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -27,6 +27,7 @@ files.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -48,7 +49,6 @@ import SCons.Util
 import os
 import os.path
 import re
-import string
 import sys
 import traceback
 import types
@@ -145,7 +145,7 @@ def Return(*vars, **kw):
     try:
         fvars = SCons.Util.flatten(vars)
         for var in fvars:
-            for v in string.split(var):
+            for v in var.split():
                 retval.append(call_stack[-1].globals[v])
     except KeyError, x:
         raise SCons.Errors.UserError, "Return of non-existent variable '%s'"%x
@@ -312,7 +312,7 @@ def SConscript_exception(file=sys.stderr):
     up to where we exec the SConscript."""
     exc_type, exc_value, exc_tb = sys.exc_info()
     tb = exc_tb
-    while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
+    while tb and stack_bottom not in tb.tb_frame.f_locals:
         tb = tb.tb_next
     if not tb:
         # We did not find our exec statement, so this was actually a bug
@@ -334,7 +334,7 @@ def annotate(node):
     """Annotate a node with the stack frame describing the
     SConscript file and line number that created it."""
     tb = sys.exc_info()[2]
-    while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
+    while tb and stack_bottom not in tb.tb_frame.f_locals:
         tb = tb.tb_next
     if not tb:
         # We did not find any exec of an SConscript file: what?!
@@ -369,7 +369,7 @@ class SConsEnvironment(SCons.Environment.Base):
 
         This is complicated by the fact that a version string can be
         something like 3.2b1."""
-        version = string.split(string.split(version_string, ' ')[0], '.')
+        version = version_string.split(' ')[0].split('.')
         v_major = int(version[0])
         v_minor = int(re.match('\d+', version[1]).group())
         if len(version) >= 3:
@@ -396,11 +396,11 @@ class SConsEnvironment(SCons.Environment.Base):
 
             if not SCons.Util.is_List(dirs):
                 dirs = [ dirs ]
-            dirs = map(str, dirs)
+            dirs = list(map(str, dirs))
 
             name = kw.get('name', 'SConscript')
 
-            files = map(lambda n, name = name: os.path.join(n, name), dirs)
+            files = [os.path.join(n, name) for n in dirs]
 
         elif len(ls) == 1:
 
@@ -459,7 +459,7 @@ class SConsEnvironment(SCons.Environment.Base):
         if not SCons.Script.sconscript_reading:
             raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
         kw['_depth'] = kw.get('_depth', 0) + 1
-        return apply(SCons.Environment.Base.Configure, (self,)+args, kw)
+        return SCons.Environment.Base.Configure(self, *args, **kw)
 
     def Default(self, *targets):
         SCons.Script._Set_Default_Targets(self, targets)
@@ -484,7 +484,7 @@ class SConsEnvironment(SCons.Environment.Base):
         except AttributeError:
             python_ver = self._get_major_minor_revision(sys.version)[:2]
         if python_ver < (major, minor):
-            v = string.split(sys.version, " ", 1)[0]
+            v = sys.version.split(" ", 1)[0]
             print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v)
             sys.exit(2)
 
@@ -520,7 +520,7 @@ class SConsEnvironment(SCons.Environment.Base):
                         globals.update(global_exports)
                         globals.update(exports)
                     else:
-                        if exports.has_key(v):
+                        if v in exports:
                             globals[v] = exports[v]
                         else:
                             globals[v] = global_exports[v]
@@ -530,11 +530,11 @@ class SConsEnvironment(SCons.Environment.Base):
     def SConscript(self, *ls, **kw):
         def subst_element(x, subst=self.subst):
             if SCons.Util.is_List(x):
-                x = map(subst, x)
+                x = list(map(subst, x))
             else:
                 x = subst(x)
             return x
-        ls = map(subst_element, ls)
+        ls = list(map(subst_element, ls))
         subst_kw = {}
         for key, val in kw.items():
             if SCons.Util.is_String(val):
@@ -550,7 +550,7 @@ class SConsEnvironment(SCons.Environment.Base):
 
         files, exports = self._get_SConscript_filenames(ls, subst_kw)
         subst_kw['exports'] = exports
-        return apply(_SConscript, [self.fs,] + files, subst_kw)
+        return _SConscript(self.fs, *files, **subst_kw)
 
     def SConscriptChdir(self, flag):
         global sconscript_chdir
@@ -569,7 +569,7 @@ def Configure(*args, **kw):
     if not SCons.Script.sconscript_reading:
         raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
     kw['_depth'] = 1
-    return apply(SCons.SConf.SConf, args, kw)
+    return SCons.SConf.SConf(*args, **kw)
 
 # It's very important that the DefaultEnvironmentCall() class stay in this
 # file, with the get_calling_namespaces() function, the compute_exports()
@@ -613,7 +613,7 @@ class DefaultEnvironmentCall:
     def __call__(self, *args, **kw):
         env = self.factory()
         method = getattr(env, self.method_name)
-        return apply(method, args, kw)
+        return method(*args, **kw)
 
 
 def BuildDefaultGlobals():
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 18ef1146..7763210a 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -40,7 +40,6 @@ import time
 start_time = time.time()
 
 import os
-import string
 import sys
 import UserList
 
@@ -58,7 +57,7 @@ import UserList
 # the "--debug=memoizer" flag and enable Memoizer before we import any
 # of the other modules that use it.
 
-_args = sys.argv + string.split(os.environ.get('SCONSFLAGS', ''))
+_args = sys.argv + os.environ.get('SCONSFLAGS', '').split()
 if "--debug=memoizer" in _args:
     import SCons.Memoize
     import SCons.Warnings
@@ -211,7 +210,7 @@ _build_plus_default = TargetList()
 
 def _Add_Arguments(alist):
     for arg in alist:
-        a, b = string.split(arg, '=', 1)
+        a, b = arg.split('=', 1)
         ARGUMENTS[a] = b
         ARGLIST.append((a, b))
 
diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py
index f3b4168c..936348a2 100644
--- a/src/engine/SCons/Subst.py
+++ b/src/engine/SCons/Subst.py
@@ -26,11 +26,11 @@ SCons string substitution.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 import types
 import UserList
 import UserString
@@ -50,7 +50,7 @@ AllowableExceptions = (IndexError, NameError)
 
 def SetAllowableExceptions(*excepts):
     global AllowableExceptions
-    AllowableExceptions = filter(None, excepts)
+    AllowableExceptions = [_f for _f in excepts if _f]
 
 def raise_exception(exception, target, s):
     name = exception.__class__.__name__
@@ -152,7 +152,7 @@ class CmdStringHolder(UserString.UserString):
         else:
             return self.data
 
-def escape_list(list, escape_func):
+def escape_list(mylist, escape_func):
     """Escape a list of arguments by running the specified escape_func
     on every object in the list that has an escape() method."""
     def escape(obj, escape_func=escape_func):
@@ -162,7 +162,7 @@ def escape_list(list, escape_func):
             return obj
         else:
             return e(escape_func)
-    return map(escape, list)
+    return list(map(escape, mylist))
 
 class NLWrapper:
     """A wrapper class that delays turning a list of sources or targets
@@ -183,14 +183,14 @@ class NLWrapper:
     def _return_nodelist(self):
         return self.nodelist
     def _gen_nodelist(self):
-        list = self.list
-        if list is None:
-            list = []
-        elif not is_Sequence(list):
-            list = [list]
+        mylist = self.list
+        if mylist is None:
+            mylist = []
+        elif not is_Sequence(mylist):
+            mylist = [mylist]
         # The map(self.func) call is what actually turns
         # a list into appropriate proxies.
-        self.nodelist = SCons.Util.NodeList(map(self.func, list))
+        self.nodelist = SCons.Util.NodeList(list(map(self.func, mylist)))
         self._create_nodelist = self._return_nodelist
         return self.nodelist
     _create_nodelist = _gen_nodelist
@@ -344,7 +344,7 @@ _regex_remove = [ _rm, None, _remove ]
 
 def _rm_list(list):
     #return [ l for l in list if not l in ('$(', '$)') ]
-    return filter(lambda l: not l in ('$(', '$)'), list)
+    return [l for l in list if not l in ('$(', '$)')]
 
 def _remove_list(list):
     result = []
@@ -399,7 +399,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
     handles separating command lines into lists of arguments, so see
     that function if that's what you're looking for.
     """
-    if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
+    if type(strSubst) == types.StringType and strSubst.find('$') < 0:
         return strSubst
 
     class StringSubber:
@@ -438,7 +438,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
                     return s
                 else:
                     key = s[1:]
-                    if key[0] == '{' or string.find(key, '.') >= 0:
+                    if key[0] == '{' or key.find('.') >= 0:
                         if key[0] == '{':
                             key = key[1:-1]
                         try:
@@ -450,9 +450,9 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
                                 return ''
                             raise_exception(e, lvars['TARGETS'], s)
                     else:
-                        if lvars.has_key(key):
+                        if key in lvars:
                             s = lvars[key]
-                        elif self.gvars.has_key(key):
+                        elif key in self.gvars:
                             s = self.gvars[key]
                         elif not NameError in AllowableExceptions:
                             raise_exception(NameError(key), lvars['TARGETS'], s)
@@ -472,13 +472,13 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
                     # are probably more the exception than the norm,
                     # so it should be tolerable for now.
                     lv = lvars.copy()
-                    var = string.split(key, '.')[0]
+                    var = key.split('.')[0]
                     lv[var] = ''
                     return self.substitute(s, lv)
             elif is_Sequence(s):
                 def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars):
                     return conv(substitute(l, lvars))
-                return map(func, s)
+                return list(map(func, s))
             elif callable(s):
                 try:
                     s = s(target=lvars['TARGETS'],
@@ -523,7 +523,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
                     if len(result) == 1:
                         result = result[0]
                     else:
-                        result = string.join(map(str, result), '')
+                        result = ''.join(map(str, result))
                 return result
             else:
                 return self.expand(args, lvars)
@@ -540,7 +540,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
     # If we dropped that behavior (or found another way to cover it),
     # we could get rid of this call completely and just rely on the
     # Executor setting the variables.
-    if not lvars.has_key('TARGET'):
+    if 'TARGET' not in lvars:
         d = subst_dict(target, source)
         if d:
             lvars = lvars.copy()
@@ -571,7 +571,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
         if mode != SUBST_RAW:
             # Compress strings of white space characters into
             # a single space.
-            result = string.strip(_space_sep.sub(' ', result))
+            result = _space_sep.sub(' ', result).strip()
     elif is_Sequence(result):
         remove = _list_remove[mode]
         if remove:
@@ -619,9 +619,9 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
             self.gvars = gvars
 
             if self.mode == SUBST_RAW:
-                self.add_strip = lambda x, s=self: s.append(x)
+                self.add_strip = lambda x: self.append(x)
             else:
-                self.add_strip = lambda x, s=self: None
+                self.add_strip = lambda x: None
             self.in_strip = None
             self.next_line()
 
@@ -653,7 +653,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
                     self.close_strip('$)')
                 else:
                     key = s[1:]
-                    if key[0] == '{' or string.find(key, '.') >= 0:
+                    if key[0] == '{' or key.find('.') >= 0:
                         if key[0] == '{':
                             key = key[1:-1]
                         try:
@@ -665,9 +665,9 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
                                 return
                             raise_exception(e, lvars['TARGETS'], s)
                     else:
-                        if lvars.has_key(key):
+                        if key in lvars:
                             s = lvars[key]
-                        elif self.gvars.has_key(key):
+                        elif key in self.gvars:
                             s = self.gvars[key]
                         elif not NameError in AllowableExceptions:
                             raise_exception(NameError(), lvars['TARGETS'], s)
@@ -680,7 +680,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
                     # string for the value of the variable name
                     # we just expanded.
                     lv = lvars.copy()
-                    var = string.split(key, '.')[0]
+                    var = key.split('.')[0]
                     lv[var] = ''
                     self.substitute(s, lv, 0)
                     self.this_word()
@@ -834,7 +834,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
     # If we dropped that behavior (or found another way to cover it),
     # we could get rid of this call completely and just rely on the
     # Executor setting the variables.
-    if not lvars.has_key('TARGET'):
+    if 'TARGET' not in lvars:
         d = subst_dict(target, source)
         if d:
             lvars = lvars.copy()
@@ -870,7 +870,7 @@ def scons_subst_once(strSubst, env, key):
 
     We do this with some straightforward, brute-force code here...
     """
-    if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
+    if type(strSubst) == types.StringType and strSubst.find('$') < 0:
         return strSubst
 
     matchlist = ['$' + key, '${' + key + '}']
@@ -880,7 +880,7 @@ def scons_subst_once(strSubst, env, key):
         if a in matchlist:
             a = val
         if is_Sequence(a):
-            return string.join(map(str, a))
+            return ' '.join(map(str, a))
         else:
             return str(a)
 
diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py
index 0dda3a22..6ef15cf2 100644
--- a/src/engine/SCons/SubstTests.py
+++ b/src/engine/SCons/SubstTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import StringIO
 import sys
 import types
@@ -101,7 +100,7 @@ if os.sep == '/':
         return str
 else:
     def cvt(str):
-        return string.replace(str, '/', os.sep)
+        return str.replace('/', os.sep)
 
 class SubstTestCase(unittest.TestCase):
     class MyNode(DummyNode):
@@ -242,7 +241,7 @@ class SubstTestCase(unittest.TestCase):
             input, expect = cases[:2]
             expect = convert(expect)
             try:
-                result = apply(function, (input, env), kwargs)
+                result = function(input, env, **kwargs)
             except Exception, e:
                 fmt = "    input %s generated %s (%s)"
                 print fmt % (repr(input), e.__class__.__name__, repr(e))
@@ -798,7 +797,7 @@ class scons_subst_list_TestCase(SubstTestCase):
     def test_scons_subst_list(self):
         """Test scons_subst_list():  basic substitution"""
         def convert_lists(expect):
-            return map(lambda l: map(cvt, l), expect)
+            return [list(map(cvt, l)) for l in expect]
         return self.basic_comparisons(scons_subst_list, convert_lists)
 
     subst_list_cases = [
@@ -1181,11 +1180,11 @@ class subst_dict_TestCase(unittest.TestCase):
         s1 = DummyNode('s1')
         s2 = DummyNode('s2')
         d = subst_dict(target=[t1, t2], source=[s1, s2])
-        TARGETS = map(lambda x: str(x), d['TARGETS'])
+        TARGETS = [str(x) for x in d['TARGETS']]
         TARGETS.sort()
         assert TARGETS == ['t1', 't2'], d['TARGETS']
         assert str(d['TARGET']) == 't1', d['TARGET']
-        SOURCES = map(lambda x: str(x), d['SOURCES'])
+        SOURCES = [str(x) for x in d['SOURCES']]
         SOURCES.sort()
         assert SOURCES == ['s1', 's2'], d['SOURCES']
         assert str(d['SOURCE']) == 's1', d['SOURCE']
@@ -1210,10 +1209,10 @@ class subst_dict_TestCase(unittest.TestCase):
         s4 = N('s4')
         s5 = V('s5')
         d = subst_dict(target=[t3, t4, t5], source=[s3, s4, s5])
-        TARGETS = map(lambda x: str(x), d['TARGETS'])
+        TARGETS = [str(x) for x in d['TARGETS']]
         TARGETS.sort()
         assert TARGETS == ['t4', 'v-t3', 'v-t5'], TARGETS
-        SOURCES = map(lambda x: str(x), d['SOURCES'])
+        SOURCES = [str(x) for x in d['SOURCES']]
         SOURCES.sort()
         assert SOURCES == ['s3', 'v-rstr-s4', 'v-s5'], SOURCES
 
@@ -1231,7 +1230,7 @@ if __name__ == "__main__":
     ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index c123ca52..66bcdfaf 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __doc__ = """
 Generic Taskmaster module for the SCons build engine.
@@ -52,7 +53,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 from itertools import chain
 import operator
-import string
 import sys
 import traceback
 
@@ -1001,14 +1001,14 @@ class Taskmaster:
 
         # TODO(1.5)
         #nclist = [ (n, find_cycle([n], set())) for n in self.pending_children ]
-        nclist = map(lambda n: (n, find_cycle([n], set())), self.pending_children)
+        nclist = [(n, find_cycle([n], set())) for n in self.pending_children]
 
         # TODO(1.5)
         #genuine_cycles = [
         #    node for node, cycle in nclist
         #             if cycle or node.get_state() != NODE_EXECUTED
         #]
-        genuine_cycles = filter(lambda t: t[1] or t[0].get_state() != NODE_EXECUTED, nclist)
+        genuine_cycles = [t for t in nclist if t[1] or t[0].get_state() != NODE_EXECUTED]
         if not genuine_cycles:
             # All of the "cycles" found were single nodes in EXECUTED state,
             # which is to say, they really weren't cycles.  Just return.
@@ -1017,7 +1017,7 @@ class Taskmaster:
         desc = 'Found dependency cycle(s):\n'
         for node, cycle in nclist:
             if cycle:
-                desc = desc + "  " + string.join(map(str, cycle), " -> ") + "\n"
+                desc = desc + "  " + " -> ".join(map(str, cycle)) + "\n"
             else:
                 desc = desc + \
                     "  Internal Error: no cycle found for node %s (%s) in state %s\n" %  \
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index 7137967e..4a0e13a8 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -660,7 +660,7 @@ class TaskmasterTestCase(unittest.TestCase):
         t = tm.next_task()
         assert t.targets == [n1], t.targets
         t.fail_stop()
-        assert t.targets == [n3], map(str, t.targets)
+        assert t.targets == [n3], list(map(str, t.targets))
         assert t.top == 1, t.top
 
     def test_stop(self):
diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py
index 2863f18d..f2c828c8 100644
--- a/src/engine/SCons/Tool/FortranCommon.py
+++ b/src/engine/SCons/Tool/FortranCommon.py
@@ -30,7 +30,6 @@ Stuff for processing Fortran, common to all fortran dialects.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 import os.path
 
 import SCons.Action
@@ -73,7 +72,7 @@ def _fortranEmitter(target, source, env):
     # Convert module name to a .mod filename
     suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
     moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
-    modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+    modules = [x.lower() + suffix for x in modules]
     for m in modules:
        target.append(env.fs.File(m, moddir))
     return (target, source)
@@ -91,8 +90,8 @@ def ComputeFortranSuffixes(suffixes, ppsuffixes):
     pre-processed. Both should be sequences, not strings."""
     assert len(suffixes) > 0
     s = suffixes[0]
-    sup = string.upper(s)
-    upper_suffixes = map(string.upper, suffixes)
+    sup = s.upper()
+    upper_suffixes = [_.upper() for _ in suffixes]
     if SCons.Util.case_sensitive_suffixes(s, sup):
         ppsuffixes.extend(upper_suffixes)
     else:
@@ -135,17 +134,17 @@ def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0):
         static_obj.add_emitter(suffix, FortranEmitter)
         shared_obj.add_emitter(suffix, ShFortranEmitter)
 
-    if not env.has_key('%sFLAGS' % dialect):
+    if '%sFLAGS' % dialect not in env:
         env['%sFLAGS' % dialect] = SCons.Util.CLVar('')
 
-    if not env.has_key('SH%sFLAGS' % dialect):
+    if 'SH%sFLAGS' % dialect not in env:
         env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
 
     # If a tool does not define fortran prefix/suffix for include path, use C ones
-    if not env.has_key('INC%sPREFIX' % dialect):
+    if 'INC%sPREFIX' % dialect not in env:
         env['INC%sPREFIX' % dialect] = '$INCPREFIX'
 
-    if not env.has_key('INC%sSUFFIX' % dialect):
+    if 'INC%sSUFFIX' % dialect not in env:
         env['INC%sSUFFIX' % dialect] = '$INCSUFFIX'
 
     env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect)
diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py
index cc2c536f..1dfeefb9 100644
--- a/src/engine/SCons/Tool/JavaCommon.py
+++ b/src/engine/SCons/Tool/JavaCommon.py
@@ -32,7 +32,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import os
 import os.path
 import re
-import string
 
 java_parsing = 1
 
@@ -127,7 +126,7 @@ if java_parsing:
             self.brackets = self.brackets - 1
             if len(self.stackBrackets) and \
                self.brackets == self.stackBrackets[-1]:
-                self.listOutputs.append(string.join(self.listClasses, '$'))
+                self.listOutputs.append('$'.join(self.listClasses))
                 self.localClasses.pop()
                 self.listClasses.pop()
                 self.anonStacksStack.pop()
@@ -179,7 +178,7 @@ if java_parsing:
                 self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1
                 for anon in self.__getAnonStack():
                     className.append(str(anon))
-                self.listOutputs.append(string.join(className, '$'))
+                self.listOutputs.append('$'.join(className))
 
             self.nextAnon = self.nextAnon + 1
             self.__getAnonStack().append(0)
@@ -298,7 +297,7 @@ if java_parsing:
             currstate = currstate.parseToken(token)
             if trace: trace(token, currstate)
         if initial.package:
-            package = string.replace(initial.package, '.', os.sep)
+            package = initial.package.replace('.', os.sep)
         return (package, initial.listOutputs)
 
 else:
diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py
index 92649b22..76944c15 100644
--- a/src/engine/SCons/Tool/JavaCommonTests.py
+++ b/src/engine/SCons/Tool/JavaCommonTests.py
@@ -569,7 +569,7 @@ if __name__ == "__main__":
     tclasses = [ parse_javaTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
index bb13e9b2..3e9f62c8 100644
--- a/src/engine/SCons/Tool/MSCommon/common.py
+++ b/src/engine/SCons/Tool/MSCommon/common.py
@@ -113,7 +113,7 @@ def normalize_env(env, keys):
             normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
 
         for k in keys:
-            if os.environ.has_key(k):
+            if k in os.environ:
                 normenv[k] = os.environ[k].encode('mbcs')
 
     return normenv
@@ -149,7 +149,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
 
     # TODO(1.5):  replace with the following list comprehension:
     #dkeep = dict([(i, []) for i in keep])
-    dkeep = dict(map(lambda i: (i, []), keep))
+    dkeep = dict([(i, []) for i in keep])
 
     # rdk will  keep the regex to match the .bat file output line starts
     rdk = {}
diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py
index 8fee916a..c5f28808 100644
--- a/src/engine/SCons/Tool/MSCommon/netframework.py
+++ b/src/engine/SCons/Tool/MSCommon/netframework.py
@@ -20,6 +20,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -28,7 +29,6 @@ __doc__ = """
 
 import os
 import re
-import string
 
 from common import read_reg, debug
 
@@ -58,14 +58,14 @@ def query_versions():
         contents = os.listdir(froot)
 
         l = re.compile('v[0-9]+.*')
-        versions = filter(lambda e, l=l: l.match(e), contents)
+        versions = [e for e in contents if l.match(e)]
 
         def versrt(a,b):
             # since version numbers aren't really floats...
             aa = a[1:]
             bb = b[1:]
-            aal = string.split(aa, '.')
-            bbl = string.split(bb, '.')
+            aal = aa.split('.')
+            bbl = bb.split('.')
             # sequence comparison in python is lexicographical
             # which is exactly what we want.
             # Note we sort backwards so the highest version is first.
diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py
index fcf07a0e..dc07192e 100644
--- a/src/engine/SCons/Tool/MSCommon/sdk.py
+++ b/src/engine/SCons/Tool/MSCommon/sdk.py
@@ -131,7 +131,7 @@ class WindowsSDK(SDKDefinition):
     """
     HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder'
     def __init__(self, *args, **kw):
-        apply(SDKDefinition.__init__, (self,)+args, kw)
+        SDKDefinition.__init__(self, *args, **kw)
         self.hkey_data = self.version
 
 class PlatformSDK(SDKDefinition):
@@ -140,7 +140,7 @@ class PlatformSDK(SDKDefinition):
     """
     HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir'
     def __init__(self, *args, **kw):
-        apply(SDKDefinition.__init__, (self,)+args, kw)
+        SDKDefinition.__init__(self, *args, **kw)
         self.hkey_data = self.uuid
 
 #
@@ -310,7 +310,7 @@ def get_cur_sdk_dir_from_reg():
     return val
 
 def get_sdk_by_version(mssdk):
-    if not SupportedSDKMap.has_key(mssdk):
+    if mssdk not in SupportedSDKMap:
         msg = "SDK version %s is not supported" % repr(mssdk)
         raise SCons.Errors.UserError, msg
     get_installed_sdks()
@@ -328,13 +328,13 @@ def get_default_sdk():
 
 def mssdk_setup_env(env):
     debug('sdk.py:mssdk_setup_env()')
-    if env.has_key('MSSDK_DIR'):
+    if 'MSSDK_DIR' in env:
         sdk_dir = env['MSSDK_DIR']
         if sdk_dir is None:
             return
         sdk_dir = env.subst(sdk_dir)
         debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir)
-    elif env.has_key('MSSDK_VERSION'):
+    elif 'MSSDK_VERSION' in env:
         sdk_version = env['MSSDK_VERSION']
         if sdk_version is None:
             msg = "SDK version %s is not installed" % repr(mssdk)
@@ -343,7 +343,7 @@ def mssdk_setup_env(env):
         mssdk = get_sdk_by_version(sdk_version)
         sdk_dir = mssdk.get_sdk_dir()
         debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir)
-    elif env.has_key('MSVS_VERSION'):
+    elif 'MSVS_VERSION' in env:
         msvs_version = env['MSVS_VERSION']
         debug('sdk.py:mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version)
         if msvs_version is None:
@@ -382,7 +382,7 @@ def mssdk_exists(version=None):
     sdks = get_installed_sdks()
     if version is None:
         return len(sdks) > 0
-    return sdks.has_key(version)
+    return version in sdks
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py
index b1133408..264166f6 100644
--- a/src/engine/SCons/Tool/MSCommon/vs.py
+++ b/src/engine/SCons/Tool/MSCommon/vs.py
@@ -385,7 +385,7 @@ def get_vs_by_version(msvs):
     global SupportedVSMap
 
     debug('vs.py:get_vs_by_version()')
-    if not SupportedVSMap.has_key(msvs):
+    if msvs not in SupportedVSMap:
         msg = "Visual Studio version %s is not supported" % repr(msvs)
         raise SCons.Errors.UserError, msg
     get_installed_visual_studios()
@@ -415,15 +415,15 @@ def get_default_version(env):
     version: str
         the default version.
     """
-    if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
+    if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
         # TODO(1.5):
         #versions = [vs.version for vs in get_installed_visual_studios()]
-        versions = map(lambda vs: vs.version, get_installed_visual_studios())
+        versions = [vs.version for vs in get_installed_visual_studios()]
         env['MSVS'] = {'VERSIONS' : versions}
     else:
         versions = env['MSVS'].get('VERSIONS', [])
 
-    if not env.has_key('MSVS_VERSION'):
+    if 'MSVS_VERSION' not in env:
         if versions:
             env['MSVS_VERSION'] = versions[0] #use highest version by default
         else:
@@ -475,7 +475,7 @@ def msvs_setup_env(env):
         msvs_list = get_installed_visual_studios()
         # TODO(1.5):
         #vscommonvarnames = [ vs.common_tools_var for vs in msvs_list ]
-        vscommonvarnames = map(lambda vs: vs.common_tools_var, msvs_list)
+        vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
         nenv = normalize_env(env['ENV'], vscommonvarnames + ['COMSPEC'])
         output = get_output(batfilename, arch, env=nenv)
         vars = parse_output(output, vars)
@@ -489,7 +489,7 @@ def query_versions():
     msvs_list = get_installed_visual_studios()
     # TODO(1.5)
     #versions = [ msvs.version for msvs in msvs_list ]
-    versions = map(lambda msvs:  msvs.version, msvs_list)
+    versions = [msvs.version for msvs in msvs_list]
     return versions
 
 # Local Variables:
diff --git a/src/engine/SCons/Tool/PharLapCommon.py b/src/engine/SCons/Tool/PharLapCommon.py
index ca19b8a3..dc124b50 100644
--- a/src/engine/SCons/Tool/PharLapCommon.py
+++ b/src/engine/SCons/Tool/PharLapCommon.py
@@ -36,7 +36,6 @@ import os.path
 import SCons.Errors
 import SCons.Util
 import re
-import string
 
 def getPharLapPath():
     """Reads the registry to find the installed path of the Phar Lap ETS
@@ -97,14 +96,14 @@ def addPathIfNotExists(env_dict, key, path, sep=os.pathsep):
         is_list = 1
         paths = env_dict[key]
         if not SCons.Util.is_List(env_dict[key]):
-            paths = string.split(paths, sep)
+            paths = paths.split(sep)
             is_list = 0
-        if not os.path.normcase(path) in map(os.path.normcase, paths):
+        if os.path.normcase(path) not in list(map(os.path.normcase, paths)):
             paths = [ path ] + paths
         if is_list:
             env_dict[key] = paths
         else:
-            env_dict[key] = string.join(paths, sep)
+            env_dict[key] = sep.join(paths)
     except KeyError:
         env_dict[key] = path
 
diff --git a/src/engine/SCons/Tool/ToolTests.py b/src/engine/SCons/Tool/ToolTests.py
index adcd40ad..723ae564 100644
--- a/src/engine/SCons/Tool/ToolTests.py
+++ b/src/engine/SCons/Tool/ToolTests.py
@@ -45,8 +45,10 @@ class ToolTestCase(unittest.TestCase):
                 return self.dict[key]
             def __setitem__(self, key, val):
                 self.dict[key] = val
+            def __contains__(self, key):
+                return self.dict.__contains__(key)
             def has_key(self, key):
-                return self.dict.has_key(key)
+                return key in self.dict
         env = Environment()
         env['BUILDERS'] = {}
         env['ENV'] = {}
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 910e6a1c..b22fb59f 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -35,6 +35,7 @@ tool definition.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -170,7 +171,7 @@ class Tool:
         env.Append(TOOLS = [ self.name ])
         if hasattr(self, 'options'):
             import SCons.Variables
-            if not env.has_key('options'):
+            if 'options' not in env:
                 from SCons.Script import ARGUMENTS
                 env['options']=SCons.Variables.Variables(args=ARGUMENTS)
             opts=env['options']
@@ -178,7 +179,7 @@ class Tool:
             self.options(opts)
             opts.Update(env)
 
-        apply(self.generate, ( env, ) + args, kw)
+        self.generate(env, *args, **kw)
 
     def __str__(self):
         return self.name
@@ -474,7 +475,7 @@ class ToolInitializerMethod:
         builder = self.get_builder(env)
         if builder is None:
             return [], []
-        return apply(builder, args, kw)
+        return builder(*args, **kw)
 
 class ToolInitializer:
     """
@@ -530,9 +531,9 @@ class ToolInitializer:
 def Initializers(env):
     ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
     def Install(self, *args, **kw):
-        return apply(self._InternalInstall, args, kw)
+        return self._InternalInstall(*args, **kw)
     def InstallAs(self, *args, **kw):
-        return apply(self._InternalInstallAs, args, kw)
+        return self._InternalInstallAs(*args, **kw)
     env.AddMethod(Install)
     env.AddMethod(InstallAs)
 
@@ -546,7 +547,7 @@ def FindTool(tools, env):
 def FindAllTools(tools, env):
     def ToolExists(tool, env=env):
         return Tool(tool).exists(env)
-    return filter (ToolExists, tools)
+    return list(filter (ToolExists, tools))
 
 def tool_list(platform, env):
 
@@ -666,7 +667,7 @@ def tool_list(platform, env):
               fortran_compiler, assembler, ar]
              + other_tools)
 
-    return filter(lambda x: x, tools)
+    return [x for x in tools if x]
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Tool/bcc32.py b/src/engine/SCons/Tool/bcc32.py
index 023ad22d..55f871b7 100644
--- a/src/engine/SCons/Tool/bcc32.py
+++ b/src/engine/SCons/Tool/bcc32.py
@@ -31,7 +31,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 
 import SCons.Defaults
 import SCons.Tool
diff --git a/src/engine/SCons/Tool/cc.py b/src/engine/SCons/Tool/cc.py
index da169fed..9b404b2b 100644
--- a/src/engine/SCons/Tool/cc.py
+++ b/src/engine/SCons/Tool/cc.py
@@ -45,7 +45,7 @@ def add_common_cc_variables(env):
     Add underlying common "C compiler" variables that
     are used by multiple tools (specifically, c++).
     """
-    if not env.has_key('_CCCOMCOM'):
+    if '_CCCOMCOM' not in env:
         env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
         # It's a hack to test for darwin here, but the alternative
         # of creating an applecc.py to contain this seems overkill.
@@ -56,10 +56,10 @@ def add_common_cc_variables(env):
         if env['PLATFORM'] == 'darwin':
             env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH'
 
-    if not env.has_key('CCFLAGS'):
+    if 'CCFLAGS' not in env:
         env['CCFLAGS']   = SCons.Util.CLVar('')
 
-    if not env.has_key('SHCCFLAGS'):
+    if 'SHCCFLAGS' not in env:
         env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
 
 def generate(env):
@@ -73,18 +73,6 @@ def generate(env):
         shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
         static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
         shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
-#<<<<<<< .working
-#
-#    env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
-#    # It's a hack to test for darwin here, but the alternative of creating
-#    # an applecc.py to contain this seems overkill.  Maybe someday the Apple
-#    # platform will require more setup and this logic will be moved.
-#    env['FRAMEWORKS'] = SCons.Util.CLVar('')
-#    env['FRAMEWORKPATH'] = SCons.Util.CLVar('')
-#    if env['PLATFORM'] == 'darwin':
-#        env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH'
-#=======
-#>>>>>>> .merge-right.r1907
 
     add_common_cc_variables(env)
 
diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py
index 4429d4a5..d7156ddd 100644
--- a/src/engine/SCons/Tool/dmd.py
+++ b/src/engine/SCons/Tool/dmd.py
@@ -57,7 +57,6 @@ Lib tool variables:
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import SCons.Action
 import SCons.Builder
@@ -112,7 +111,7 @@ def generate(env):
         # This is merely for the convenience of the dependency scanner.
         dmd_path = env.WhereIs(dc)
         if dmd_path:
-            x = string.rindex(dmd_path, dc)
+            x = dmd_path.rindex(dc)
             phobosDir = dmd_path[:x] + '/../src/phobos'
             if os.path.isdir(phobosDir):
                 env.Append(DPATH = [phobosDir])
diff --git a/src/engine/SCons/Tool/dvipdf.py b/src/engine/SCons/Tool/dvipdf.py
index 80a4b07f..ef4d1ee2 100644
--- a/src/engine/SCons/Tool/dvipdf.py
+++ b/src/engine/SCons/Tool/dvipdf.py
@@ -30,6 +30,7 @@ selection method.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -88,7 +89,7 @@ def PDFEmitter(target, source, env):
     """
     def strip_suffixes(n):
         return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log']
-    source = filter(strip_suffixes, source)
+    source = list(filter(strip_suffixes, source))
     return (target, source)
 
 def generate(env):
diff --git a/src/engine/SCons/Tool/filesystem.py b/src/engine/SCons/Tool/filesystem.py
index 4cecb126..31c8abc0 100644
--- a/src/engine/SCons/Tool/filesystem.py
+++ b/src/engine/SCons/Tool/filesystem.py
@@ -44,12 +44,12 @@ def copyto_emitter(target, source, env):
     n_target = []
 
     for t in target:
-        n_target = n_target + map( lambda s, t=t: t.File( str( s ) ), source )
+        n_target = n_target + [t.File( str( s ) ) for s in source]
 
     return (n_target, source)
 
 def copy_action_func(target, source, env):
-    assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(map(str, target),map(str, source))
+    assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(map(str, source)))
 
     for t, s in zip(target, source):
         if copyFunc(t.get_path(), s.get_path(), env):
diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py
index b944ca2a..26c6ff5d 100644
--- a/src/engine/SCons/Tool/fortran.py
+++ b/src/engine/SCons/Tool/fortran.py
@@ -34,7 +34,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import re
-import string
 
 import SCons.Action
 import SCons.Defaults
diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py
index 591eef0d..ada169ac 100644
--- a/src/engine/SCons/Tool/gs.py
+++ b/src/engine/SCons/Tool/gs.py
@@ -69,7 +69,7 @@ def generate(env):
 
 
 def exists(env):
-    if env.has_key('PS2PDF'):
+    if 'PS2PDF' in env:
         return env.Detect(env['PS2PDF'])
     else:
         return env.Detect(gs) or SCons.Util.WhereIs(gs)
diff --git a/src/engine/SCons/Tool/hpc++.py b/src/engine/SCons/Tool/hpc++.py
index e1a00407..2b8ed3fc 100644
--- a/src/engine/SCons/Tool/hpc++.py
+++ b/src/engine/SCons/Tool/hpc++.py
@@ -34,7 +34,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 import SCons.Util
 
@@ -67,8 +66,8 @@ def generate(env):
         env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z')
         # determine version of aCC
         line = os.popen(acc + ' -V 2>&1').readline().rstrip()
-        if string.find(line, 'aCC: HP ANSI C++') == 0:
-            env['CXXVERSION'] = string.split(line)[-1]
+        if line.find('aCC: HP ANSI C++') == 0:
+            env['CXXVERSION'] = line.split()[-1]
 
         if env['PLATFORM'] == 'cygwin':
             env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
diff --git a/src/engine/SCons/Tool/icl.py b/src/engine/SCons/Tool/icl.py
index 2d1636e9..caa22814 100644
--- a/src/engine/SCons/Tool/icl.py
+++ b/src/engine/SCons/Tool/icl.py
@@ -40,10 +40,10 @@ import SCons.Tool.intelc
 
 def generate(*args, **kw):
     """Add Builders and construction variables for icl to an Environment."""
-    return apply(SCons.Tool.intelc.generate, args, kw)
+    return SCons.Tool.intelc.generate(*args, **kw)
 
 def exists(*args, **kw):
-    return apply(SCons.Tool.intelc.exists, args, kw)
+    return SCons.Tool.intelc.exists(*args, **kw)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Tool/ifl.py b/src/engine/SCons/Tool/ifl.py
index 88dcf598..30b3672e 100644
--- a/src/engine/SCons/Tool/ifl.py
+++ b/src/engine/SCons/Tool/ifl.py
@@ -43,12 +43,12 @@ def generate(env):
     SCons.Tool.SourceFileScanner.add_scanner('.i', fscan)
     SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan)
 
-    if not env.has_key('FORTRANFILESUFFIXES'):
+    if 'FORTRANFILESUFFIXES' not in env:
         env['FORTRANFILESUFFIXES'] = ['.i']
     else:
         env['FORTRANFILESUFFIXES'].append('.i')
 
-    if not env.has_key('F90FILESUFFIXES'):
+    if 'F90FILESUFFIXES' not in env:
         env['F90FILESUFFIXES'] = ['.i90']
     else:
         env['F90FILESUFFIXES'].append('.i90')
diff --git a/src/engine/SCons/Tool/ifort.py b/src/engine/SCons/Tool/ifort.py
index e4165de6..4b2fd658 100644
--- a/src/engine/SCons/Tool/ifort.py
+++ b/src/engine/SCons/Tool/ifort.py
@@ -34,8 +34,6 @@ selection method.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import SCons.Defaults
 from SCons.Scanner.Fortran import FortranScan
 from FortranCommon import add_all_to_env
@@ -48,12 +46,12 @@ def generate(env):
     SCons.Tool.SourceFileScanner.add_scanner('.i', fscan)
     SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan)
 
-    if not env.has_key('FORTRANFILESUFFIXES'):
+    if 'FORTRANFILESUFFIXES' not in env:
         env['FORTRANFILESUFFIXES'] = ['.i']
     else:
         env['FORTRANFILESUFFIXES'].append('.i')
 
-    if not env.has_key('F90FILESUFFIXES'):
+    if 'F90FILESUFFIXES' not in env:
         env['F90FILESUFFIXES'] = ['.i90']
     else:
         env['F90FILESUFFIXES'].append('.i90')
@@ -75,7 +73,7 @@ def generate(env):
         for dialect in ['F77', 'F90', 'FORTRAN', 'F95']:
             for var in ['%sCOM' % dialect, '%sPPCOM' % dialect,
                         'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]:
-                env[var] = string.replace(env[var], '-o $TARGET', '-object:$TARGET')
+                env[var] = env[var].replace('-o $TARGET', '-object:$TARGET')
         env['FORTRANMODDIRPREFIX'] = "/module:"
     else:
         env['FORTRANMODDIRPREFIX'] = "-module "
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index 06bcfdd1..abdd4797 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -76,7 +76,7 @@ def installFunc(target, source, env):
         raise SCons.Errors.UserError('Missing INSTALL construction variable.')
 
     assert len(target)==len(source), \
-           "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target))
+           "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target)))
     for t,s in zip(target,source):
         if install(t.get_path(),s.get_path(),env):
             return 1
@@ -159,14 +159,14 @@ def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
             # be relative to the top-level SConstruct directory.
             target = env.fs.Entry('.'+os.sep+src.name, dnode)
             #tgt.extend(BaseInstallBuilder(env, target, src, **kw))
-            tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw))
+            tgt.extend(BaseInstallBuilder(env, target, src, **kw))
     return tgt
 
 def InstallAsBuilderWrapper(env, target=None, source=None, **kw):
     result = []
     for src, tgt in map(lambda x, y: (x, y), source, target):
         #result.extend(BaseInstallBuilder(env, tgt, src, **kw))
-        result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw))
+        result.extend(BaseInstallBuilder(env, tgt, src, **kw))
     return result
 
 added = None
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
index 2cd38bbf..e1936952 100644
--- a/src/engine/SCons/Tool/intelc.py
+++ b/src/engine/SCons/Tool/intelc.py
@@ -38,7 +38,7 @@ import math, sys, os.path, glob, string, re
 
 is_windows = sys.platform == 'win32'
 is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or 
-                           (os.environ.has_key('PROCESSOR_ARCHITEW6432') and
+                           ('PROCESSOR_ARCHITEW6432' in os.environ and
                             os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64'))
 is_linux = sys.platform == 'linux2'
 is_mac     = sys.platform == 'darwin'
@@ -406,7 +406,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
                     # Couldn't get it from registry: use default subdir of topdir
                     env.PrependENVPath(p[0], os.path.join(topdir, p[2]))
                 else:
-                    env.PrependENVPath(p[0], string.split(path, os.pathsep))
+                    env.PrependENVPath(p[0], path.split(os.pathsep))
                     # print "ICL %s: %s, final=%s"%(p[0], path, str(env['ENV'][p[0]]))
 
     if is_windows:
@@ -445,7 +445,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
         for ld in [envlicdir, reglicdir]:
             # If the string contains an '@', then assume it's a network
             # license (port@system) and good by definition.
-            if ld and (string.find(ld, '@') != -1 or os.path.exists(ld)):
+            if ld and (ld.find('@') != -1 or os.path.exists(ld)):
                 licdir = ld
                 break
         if not licdir:
diff --git a/src/engine/SCons/Tool/ipkg.py b/src/engine/SCons/Tool/ipkg.py
index 10fbc98e..8e0940a1 100644
--- a/src/engine/SCons/Tool/ipkg.py
+++ b/src/engine/SCons/Tool/ipkg.py
@@ -36,7 +36,6 @@ packages fake_root.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import SCons.Builder
 
@@ -56,8 +55,8 @@ def generate(env):
     # TODO(1.5)
     #env['IPKGUSER']   = os.popen('id -un').read().strip()
     #env['IPKGGROUP']  = os.popen('id -gn').read().strip()
-    env['IPKGUSER']   = string.strip(os.popen('id -un').read())
-    env['IPKGGROUP']  = string.strip(os.popen('id -gn').read())
+    env['IPKGUSER']   = os.popen('id -un').read().strip()
+    env['IPKGGROUP']  = os.popen('id -gn').read().strip()
     env['IPKGFLAGS']  = SCons.Util.CLVar('-o $IPKGUSER -g $IPKGGROUP')
     env['IPKGSUFFIX'] = '.ipk'
 
diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py
index 78d641a5..d080af5f 100644
--- a/src/engine/SCons/Tool/javac.py
+++ b/src/engine/SCons/Tool/javac.py
@@ -30,12 +30,12 @@ selection method.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 
 import SCons.Action
 import SCons.Builder
@@ -45,7 +45,7 @@ import SCons.Util
 
 def classname(path):
     """Turn a string (path name) into a Java class name."""
-    return string.replace(os.path.normpath(path), os.sep, '.')
+    return os.path.normpath(path).replace(os.sep, '.')
 
 def emit_java_classes(target, source, env):
     """Create and return lists of source java files
@@ -67,20 +67,19 @@ def emit_java_classes(target, source, env):
 
     slist = []
     js = _my_normcase(java_suffix)
-    find_java = lambda n, js=js, ljs=len(js): _my_normcase(n[-ljs:]) == js
     for entry in source:
         entry = entry.rentry().disambiguate()
         if isinstance(entry, SCons.Node.FS.File):
             slist.append(entry)
         elif isinstance(entry, SCons.Node.FS.Dir):
             result = SCons.Util.OrderedDict()
-            def visit(arg, dirname, names, fj=find_java, dirnode=entry.rdir()):
-                java_files = filter(fj, names)
+            def visit(arg, dirname, names, dirnode=entry.rdir()):
+                java_files = [n for n in names if _my_normcase(n[-len(js):]) == js]
                 # The on-disk entries come back in arbitrary order.  Sort
                 # them so our target and source lists are determinate.
                 java_files.sort()
                 mydir = dirnode.Dir(dirname)
-                java_paths = map(lambda f, d=mydir: d.File(f), java_files)
+                java_paths = [mydir.File(f) for f in java_files]
                 for jp in java_paths:
                      arg[jp] = True
 
@@ -156,8 +155,8 @@ class pathopt:
         if self.default:
             path = path + [ env[self.default] ]
         if path:
-            return [self.opt, string.join(path, os.pathsep)]
-            #return self.opt + " " + string.join(path, os.pathsep)
+            return [self.opt, os.pathsep.join(path)]
+            #return self.opt + " " + os.pathsep.join(path)
         else:
             return []
             #return ""
@@ -194,7 +193,7 @@ def Java(env, target, source, *args, **kw):
                 b = env.JavaClassFile
             else:
                 b = env.JavaClassDir
-        result.extend(apply(b, (t, s) + args, kw))
+        result.extend(b(t, s, *args, **kw))
 
     return result
 
diff --git a/src/engine/SCons/Tool/javah.py b/src/engine/SCons/Tool/javah.py
index dda5ebbb..c0922731 100644
--- a/src/engine/SCons/Tool/javah.py
+++ b/src/engine/SCons/Tool/javah.py
@@ -34,7 +34,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 import SCons.Action
 import SCons.Builder
@@ -93,7 +92,7 @@ def emit_java_headers(target, source, env):
             target[0]._morph()
         tlist = []
         for s in source:
-            fname = string.replace(s.attributes.java_classname, '.', '_') + '.h'
+            fname = s.attributes.java_classname.replace('.', '_') + '.h'
             t = target[0].File(fname)
             t.attributes.java_lookupdir = target[0]
             tlist.append(t)
@@ -112,7 +111,7 @@ def JavaHOutFlagGenerator(target, source, env, for_signature):
 
 def getJavaHClassPath(env,target, source, for_signature):
     path = "${SOURCE.attributes.java_classdir}"
-    if env.has_key('JAVACLASSPATH') and env['JAVACLASSPATH']:
+    if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']:
         path = SCons.Util.AppendPath(path, env['JAVACLASSPATH'])
     return "-classpath %s" % (path)
 
diff --git a/src/engine/SCons/Tool/lex.py b/src/engine/SCons/Tool/lex.py
index dd7fe25b..280c768e 100644
--- a/src/engine/SCons/Tool/lex.py
+++ b/src/engine/SCons/Tool/lex.py
@@ -35,8 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
 
-import string
-
 import SCons.Action
 import SCons.Tool
 import SCons.Util
@@ -62,7 +60,7 @@ def lexEmitter(target, source, env):
             if option[:l] == fileGenOption:
                 # A file generating option is present, so add the
                 # file name to the target list.
-                fileName = string.strip(option[l:])
+                fileName = option[l:].strip()
                 target.append(fileName)
     return (target, source)
 
diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py
index bf1f2ace..64b927a0 100644
--- a/src/engine/SCons/Tool/midl.py
+++ b/src/engine/SCons/Tool/midl.py
@@ -33,8 +33,6 @@ selection method.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import SCons.Action
 import SCons.Builder
 import SCons.Defaults
@@ -53,10 +51,10 @@ def midl_emitter(target, source, env):
 
     midlcom = env['MIDLCOM']
 
-    if string.find(midlcom, '/proxy') != -1:
+    if midlcom.find('/proxy') != -1:
         proxy = base + '_p.c'
         t.append(proxy)
-    if string.find(midlcom, '/dlldata') != -1:
+    if midlcom.find('/dlldata') != -1:
         dlldata = base + '_data.c'
         t.append(dlldata)
     
diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py
index da8a59e6..8d40a0bc 100644
--- a/src/engine/SCons/Tool/mingw.py
+++ b/src/engine/SCons/Tool/mingw.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 
 import SCons.Action
 import SCons.Builder
diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py
index 5daae515..b1ba1df0 100644
--- a/src/engine/SCons/Tool/mslink.py
+++ b/src/engine/SCons/Tool/mslink.py
@@ -123,7 +123,7 @@ def _dllEmitter(target, source, env, paramtp):
                             '%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
                             "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
 
-    if env.has_key('PDB') and env['PDB']:
+    if 'PDB' in env and env['PDB']:
         pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
         extratargets.append(pdb)
         target[0].attributes.pdb = pdb
@@ -171,7 +171,7 @@ def prog_emitter(target, source, env):
                             "PROGPREFIX", "PROGSUFFIX",
                             "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
 
-    if env.has_key('PDB') and env['PDB']:
+    if 'PDB' in env and env['PDB']:
         pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
         extratargets.append(pdb)
         target[0].attributes.pdb = pdb
@@ -179,7 +179,7 @@ def prog_emitter(target, source, env):
     return (target+extratargets,source)
 
 def RegServerFunc(target, source, env):
-    if env.has_key('register') and env['register']:
+    if 'register' in env and env['register']:
         ret = regServerAction([target[0]], [source[0]], env)
         if ret:
             raise SCons.Errors.UserError, "Unable to register %s" % target[0]
diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py
index 920ac7c1..fde93ea8 100644
--- a/src/engine/SCons/Tool/msvc.py
+++ b/src/engine/SCons/Tool/msvc.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
 import re
-import string
 import sys
 
 import SCons.Action
@@ -55,8 +54,8 @@ CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
 
 def validate_vars(env):
     """Validate the PCH and PCHSTOP construction variables."""
-    if env.has_key('PCH') and env['PCH']:
-        if not env.has_key('PCHSTOP'):
+    if 'PCH' in env and env['PCH']:
+        if 'PCHSTOP' not in env:
             raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
         if not SCons.Util.is_String(env['PCHSTOP']):
             raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
@@ -99,7 +98,7 @@ def object_emitter(target, source, env, parent_emitter):
     # See issue #2505 for a discussion of what to do if it turns
     # out this assumption causes trouble in the wild:
     # http://scons.tigris.org/issues/show_bug.cgi?id=2505
-    if env.has_key('PCH'):
+    if 'PCH' in env:
         pch = env['PCH']
         if str(target[0]) != SCons.Util.splitext(str(pch))[0] + '.obj':
             env.Depends(target, pch)
@@ -254,9 +253,9 @@ def generate(env):
     env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
     env['BUILDERS']['PCH'] = pch_builder
 
-    if not env.has_key('ENV'):
+    if 'ENV' not in env:
         env['ENV'] = {}
-    if not env['ENV'].has_key('SystemRoot'):    # required for dlls in the winsxs folders
+    if 'SystemRoot' not in env['ENV']:    # required for dlls in the winsxs folders
         env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
 
 def exists(env):
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index f43dd945..57098a80 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -30,6 +30,7 @@ selection method.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -39,7 +40,6 @@ import ntpath
 import os
 import pickle
 import re
-import string
 import sys
 
 import SCons.Builder
@@ -57,23 +57,10 @@ from SCons.Defaults import processDefines
 # DSP/DSW/SLN/VCPROJ files.
 ##############################################################################
 
-def _hexdigest(s):
-    """Return a string as a string of hex characters.
-    """
-    # NOTE:  This routine is a method in the Python 2.0 interface
-    # of the native md5 module, but we want SCons to operate all
-    # the way back to at least Python 1.5.2, which doesn't have it.
-    h = string.hexdigits
-    r = ''
-    for c in s:
-        i = ord(c)
-        r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
-    return r
-
 def xmlify(s):
-    s = string.replace(s, "&", "&amp;") # do this first
-    s = string.replace(s, "'", "&apos;")
-    s = string.replace(s, '"', "&quot;")
+    s = s.replace("&", "&amp;") # do this first
+    s = s.replace("'", "&apos;")
+    s = s.replace('"', "&quot;")
     return s
 
 external_makefile_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}'
@@ -88,9 +75,7 @@ def _generateGUID(slnfile, name):
     # the generated file has a consistent GUID even if we generate
     # it on a non-Windows platform.
     m.update(ntpath.normpath(str(slnfile)) + str(name))
-    # TODO(1.5)
-    #solution = m.hexdigest().upper()
-    solution = string.upper(_hexdigest(m.digest()))
+    solution = m.hexdigest().upper()
     # convert most of the signature to GUID form (discard the rest)
     solution = "{" + solution[:8] + "-" + solution[8:12] + "-" + solution[12:16] + "-" + solution[16:20] + "-" + solution[20:32] + "}"
     return solution
@@ -116,7 +101,7 @@ def msvs_parse_version(s):
 # which works regardless of how we were invoked.
 def getExecScriptMain(env, xml=None):
     scons_home = env.get('SCONS_HOME')
-    if not scons_home and os.environ.has_key('SCONS_LIB_DIR'):
+    if not scons_home and 'SCONS_LIB_DIR' in os.environ:
         scons_home = os.environ['SCONS_LIB_DIR']
     if scons_home:
         exec_script_main = "from os.path import join; import sys; sys.path = [ r'%s' ] + sys.path; import SCons.Script; SCons.Script.main()" % scons_home
@@ -161,7 +146,7 @@ def makeHierarchy(sources):
         if len(path):
             dict = hierarchy
             for part in path[:-1]:
-                if not dict.has_key(part):
+                if part not in dict:
                     dict[part] = {}
                 dict = dict[part]
             dict[path[-1]] = file
@@ -188,7 +173,7 @@ class _DSPGenerator:
         else:
             self.dspabs = get_abspath()
 
-        if not env.has_key('variant'):
+        if 'variant' not in env:
             raise SCons.Errors.InternalError, \
                   "You must specify a 'variant' argument (i.e. 'Debug' or " +\
                   "'Release') to create an MSVSProject."
@@ -197,7 +182,7 @@ class _DSPGenerator:
         elif SCons.Util.is_List(env['variant']):
             variants = env['variant']
 
-        if not env.has_key('buildtarget') or env['buildtarget'] == None:
+        if 'buildtarget' not in env or env['buildtarget'] == None:
             buildtarget = ['']
         elif SCons.Util.is_String(env['buildtarget']):
             buildtarget = [env['buildtarget']]
@@ -219,7 +204,7 @@ class _DSPGenerator:
             for _ in variants:
                 buildtarget.append(bt)
 
-        if not env.has_key('outdir') or env['outdir'] == None:
+        if 'outdir' not in env or env['outdir'] == None:
             outdir = ['']
         elif SCons.Util.is_String(env['outdir']):
             outdir = [env['outdir']]
@@ -241,7 +226,7 @@ class _DSPGenerator:
             for v in variants:
                 outdir.append(s)
 
-        if not env.has_key('runfile') or env['runfile'] == None:
+        if 'runfile' not in env or env['runfile'] == None:
             runfile = buildtarget[-1:]
         elif SCons.Util.is_String(env['runfile']):
             runfile = [env['runfile']]
@@ -269,7 +254,7 @@ class _DSPGenerator:
 
         self.env = env
 
-        if self.env.has_key('name'):
+        if 'name' in self.env:
             self.name = self.env['name']
         else:
             self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0])
@@ -289,14 +274,14 @@ class _DSPGenerator:
         self.configs = {}
 
         self.nokeep = 0
-        if env.has_key('nokeep') and env['variant'] != 0:
+        if 'nokeep' in env and env['variant'] != 0:
             self.nokeep = 1
 
         if self.nokeep == 0 and os.path.exists(self.dspabs):
             self.Parse()
 
         for t in zip(sourcenames,self.srcargs):
-            if self.env.has_key(t[1]):
+            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]]:
@@ -308,7 +293,7 @@ class _DSPGenerator:
         for n in sourcenames:
             # TODO(1.5):
             #self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower()))
-            self.sources[n].sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
+            self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower()))
 
         def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile):
             config = Config()
@@ -399,7 +384,7 @@ class _GenerateV6DSP(_DSPGenerator):
             else:
                 self.file.write('\n!ELSEIF  "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind))
 
-            env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET')
+            env_has_buildtarget = 'MSVSBUILDTARGET' in self.env
             if not env_has_buildtarget:
                 self.env['MSVSBUILDTARGET'] = buildtarget
 
@@ -409,7 +394,7 @@ class _GenerateV6DSP(_DSPGenerator):
                                 '# PROP %sUse_Debug_Libraries ' % (base, base))
                 # TODO(1.5):
                 #if kind.lower().find('debug') < 0:
-                if string.find(string.lower(kind), 'debug') < 0:
+                if kind.lower().find('debug') < 0:
                     self.file.write('0\n')
                 else:
                     self.file.write('1\n')
@@ -462,7 +447,7 @@ class _GenerateV6DSP(_DSPGenerator):
         cats = categories.keys()
         # TODO(1.5):
         #cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
-        cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
+        cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
         for kind in cats:
             if not self.sources[kind]:
                 continue # skip empty groups
@@ -470,7 +455,7 @@ class _GenerateV6DSP(_DSPGenerator):
             self.file.write('# Begin Group "' + kind + '"\n\n')
             # TODO(1.5)
             #typelist = categories[kind].replace('|', ';')
-            typelist = string.replace(categories[kind], '|', ';')
+            typelist = categories[kind].replace('|', ';')
             self.file.write('# PROP Default_Filter "' + typelist + '"\n')
 
             for file in self.sources[kind]:
@@ -495,7 +480,7 @@ class _GenerateV6DSP(_DSPGenerator):
         while line:
             # TODO(1.5):
             #if line.find("# End Project") > -1:
-            if string.find(line, "# End Project") > -1:
+            if line.find("# End Project") > -1:
                 break
             line = dspfile.readline()
 
@@ -674,7 +659,7 @@ class _GenerateV7DSP(_DSPGenerator):
             runfile     = self.configs[kind].runfile
             cmdargs = self.configs[kind].cmdargs
 
-            env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET')
+            env_has_buildtarget = 'MSVSBUILDTARGET' in self.env
             if not env_has_buildtarget:
                 self.env['MSVSBUILDTARGET'] = buildtarget
 
@@ -690,8 +675,8 @@ class _GenerateV7DSP(_DSPGenerator):
             # TODO(1.5)
             #preprocdefs = xmlify(';'.join(self.env.get('CPPDEFINES', [])))
             #includepath = xmlify(';'.join(self.env.get('CPPPATH', [])))
-            preprocdefs = xmlify(string.join(processDefines(self.env.get('CPPDEFINES', [])), ';'))
-            includepath = xmlify(string.join(self.env.get('CPPPATH', []), ';'))
+            preprocdefs = xmlify(';'.join(processDefines(self.env.get('CPPDEFINES', []))))
+            includepath = xmlify(';'.join(self.env.get('CPPPATH', [])))
 
             if not env_has_buildtarget:
                 del self.env['MSVSBUILDTARGET']
@@ -721,7 +706,7 @@ class _GenerateV7DSP(_DSPGenerator):
         sorteditems = hierarchy.items()
         # TODO(1.5):
         #sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
-        sorteditems.sort(lambda a, b: cmp(string.lower(a[0]), string.lower(b[0])))
+        sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
 
         # First folders, then files
         for key, value in sorteditems:
@@ -754,8 +739,8 @@ class _GenerateV7DSP(_DSPGenerator):
         cats = categories.keys()
         # TODO(1.5)
         #cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
-        cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
-        cats = filter(lambda k, s=self: s.sources[k], cats)
+        cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
+        cats = [k for k in cats if self.sources[k]]
         for kind in cats:
             if len(cats) > 1:
                 self.file.write('\t\t<Filter\n'
@@ -767,14 +752,14 @@ class _GenerateV7DSP(_DSPGenerator):
             # First remove any common prefix
             commonprefix = None
             if len(sources) > 1:
-                s = map(os.path.normpath, sources)
+                s = list(map(os.path.normpath, sources))
                 # take the dirname because the prefix may include parts
                 # of the filenames (e.g. if you have 'dir\abcd' and
                 # 'dir\acde' then the cp will be 'dir\a' )
                 cp = os.path.dirname( os.path.commonprefix(s) )
                 if cp and s[0][len(cp)] == os.sep:
                     # +1 because the filename starts after the separator
-                    sources = map(lambda s, l=len(cp)+1: s[l:], sources)
+                    sources = [s[len(cp)+1:] for s in sources]
                     commonprefix = cp
             elif len(sources) == 1:
                 commonprefix = os.path.dirname( sources[0] )
@@ -805,7 +790,7 @@ class _GenerateV7DSP(_DSPGenerator):
         while line:
             # TODO(1.5)
             #if line.find('<!-- SCons Data:') > -1:
-            if string.find(line, '<!-- SCons Data:') > -1:
+            if line.find('<!-- SCons Data:') > -1:
                 break
             line = dspfile.readline()
 
@@ -860,7 +845,7 @@ class _DSWGenerator:
         self.dswfile = os.path.normpath(str(dswfile))
         self.env = env
 
-        if not env.has_key('projects'):
+        if 'projects' not in env:
             raise SCons.Errors.UserError, \
                 "You must specify a 'projects' argument to create an MSVSSolution."
         projects = env['projects']
@@ -871,9 +856,9 @@ class _DSWGenerator:
         if len(projects) < 1:
             raise SCons.Errors.UserError, \
                 "You must specify at least one project to create an MSVSSolution."
-        self.dspfiles = map(str, projects)
+        self.dspfiles = list(map(str, projects))
 
-        if self.env.has_key('name'):
+        if 'name' in self.env:
             self.name = self.env['name']
         else:
             self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0])
@@ -898,7 +883,7 @@ class _GenerateV7DSW(_DSWGenerator):
         if self.version_num >= 8.0:
             self.versionstr = '9.00'
 
-        if env.has_key('slnguid') and env['slnguid']:
+        if 'slnguid' in env and env['slnguid']:
             self.slnguid = env['slnguid']
         else:
             self.slnguid = _generateGUID(dswfile, self.name)
@@ -906,7 +891,7 @@ class _GenerateV7DSW(_DSWGenerator):
         self.configs = {}
 
         self.nokeep = 0
-        if env.has_key('nokeep') and env['variant'] != 0:
+        if 'nokeep' in env and env['variant'] != 0:
             self.nokeep = 1
 
         if self.nokeep == 0 and os.path.exists(self.dswfile):
@@ -926,7 +911,7 @@ class _GenerateV7DSW(_DSWGenerator):
             self.configs[variant] = config
             print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'"
 
-        if not env.has_key('variant'):
+        if 'variant' not in env:
             raise SCons.Errors.InternalError, \
                   "You must specify a 'variant' argument (i.e. 'Debug' or " +\
                   "'Release') to create an MSVS Solution File."
@@ -992,11 +977,11 @@ class _GenerateV7DSW(_DSWGenerator):
         self.file.write('Global\n')
 
         env = self.env
-        if env.has_key('MSVS_SCC_PROVIDER'):
+        if 'MSVS_SCC_PROVIDER' in env:
             dspfile_base = os.path.basename(self.dspfile)
             slnguid = self.slnguid
             scc_provider = env.get('MSVS_SCC_PROVIDER', '')
-            scc_provider = string.replace(scc_provider, ' ', r'\u0020')
+            scc_provider = scc_provider.replace(' ', r'\u0020')
             scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '')
             # scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '')
             scc_local_path = env.get('MSVS_SCC_LOCAL_PATH', '')
@@ -1136,7 +1121,7 @@ def GenerateDSP(dspfile, source, env):
     """Generates a Project file based on the version of MSVS that is being used"""
 
     version_num = 6.0
-    if env.has_key('MSVS_VERSION'):
+    if 'MSVS_VERSION' in env:
         version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
     if version_num >= 7.0:
         g = _GenerateV7DSP(dspfile, source, env)
@@ -1149,7 +1134,7 @@ def GenerateDSW(dswfile, source, env):
     """Generates a Solution/Workspace file based on the version of MSVS that is being used"""
 
     version_num = 6.0
-    if env.has_key('MSVS_VERSION'):
+    if 'MSVS_VERSION' in env:
         version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
     if version_num >= 7.0:
         g = _GenerateV7DSW(dswfile, source, env)
@@ -1225,7 +1210,7 @@ def projectEmitter(target, source, env):
         source = source + env.subst('$MSVSSCONSCOM', 1)
         source = source + env.subst('$MSVSENCODING', 1)
 
-        if env.has_key('buildtarget') and env['buildtarget'] != None:
+        if 'buildtarget' in env and env['buildtarget'] != None:
             if SCons.Util.is_String(env['buildtarget']):
                 source = source + ' "%s"' % env['buildtarget']
             elif SCons.Util.is_List(env['buildtarget']):
@@ -1241,7 +1226,7 @@ def projectEmitter(target, source, env):
                 except AttributeError: raise SCons.Errors.InternalError, \
                     "buildtarget can be a string, a node, a list of strings or nodes, or None"
 
-        if env.has_key('outdir') and env['outdir'] != None:
+        if 'outdir' in env and env['outdir'] != None:
             if SCons.Util.is_String(env['outdir']):
                 source = source + ' "%s"' % env['outdir']
             elif SCons.Util.is_List(env['outdir']):
@@ -1257,13 +1242,13 @@ def projectEmitter(target, source, env):
                 except AttributeError: raise SCons.Errors.InternalError, \
                     "outdir can be a string, a node, a list of strings or nodes, or None"
 
-        if env.has_key('name'):
+        if 'name' in env:
             if SCons.Util.is_String(env['name']):
                 source = source + ' "%s"' % env['name']
             else:
                 raise SCons.Errors.InternalError, "name must be a string"
 
-        if env.has_key('variant'):
+        if 'variant' in env:
             if SCons.Util.is_String(env['variant']):
                 source = source + ' "%s"' % env['variant']
             elif SCons.Util.is_List(env['variant']):
@@ -1278,7 +1263,7 @@ def projectEmitter(target, source, env):
             raise SCons.Errors.InternalError, "variant must be specified"
 
         for s in _DSPGenerator.srcargs:
-            if env.has_key(s):
+            if s in env:
                 if SCons.Util.is_String(env[s]):
                     source = source + ' "%s' % env[s]
                 elif SCons.Util.is_List(env[s]):
@@ -1320,13 +1305,13 @@ def solutionEmitter(target, source, env):
     if not source:
         source = 'sln_inputs:'
 
-        if env.has_key('name'):
+        if 'name' in env:
             if SCons.Util.is_String(env['name']):
                 source = source + ' "%s"' % env['name']
             else:
                 raise SCons.Errors.InternalError, "name must be a string"
 
-        if env.has_key('variant'):
+        if 'variant' in env:
             if SCons.Util.is_String(env['variant']):
                 source = source + ' "%s"' % env['variant']
             elif SCons.Util.is_List(env['variant']):
@@ -1340,13 +1325,13 @@ def solutionEmitter(target, source, env):
         else:
             raise SCons.Errors.InternalError, "variant must be specified"
 
-        if env.has_key('slnguid'):
+        if 'slnguid' in env:
             if SCons.Util.is_String(env['slnguid']):
                 source = source + ' "%s"' % env['slnguid']
             else:
                 raise SCons.Errors.InternalError, "slnguid must be a string"
 
-        if env.has_key('projects'):
+        if 'projects' in env:
             if SCons.Util.is_String(env['projects']):
                 source = source + ' "%s"' % env['projects']
             elif SCons.Util.is_List(env['projects']):
@@ -1410,11 +1395,11 @@ def generate(env):
     # Set-up ms tools paths for default version
     msvc_setup_env_once(env)
 
-    if env.has_key('MSVS_VERSION'):
+    if 'MSVS_VERSION' in env:
         version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
     else:
         (version_num, suite) = (7.0, None) # guess at a default
-    if not env.has_key('MSVS'):
+    if 'MSVS' not in env:
         env['MSVS'] = {}
     if (version_num < 7.0):
         env['MSVS']['PROJECTSUFFIX']  = '.dsp'
diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py
index 0f88ad3f..00d4754e 100644
--- a/src/engine/SCons/Tool/msvsTests.py
+++ b/src/engine/SCons/Tool/msvsTests.py
@@ -24,7 +24,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 import TestCmd
 import unittest
@@ -39,7 +38,7 @@ from SCons.Tool.MSCommon.common import debug
 from SCons.Tool.MSCommon import get_default_version, \
                                 query_versions
 
-regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
+regdata_6a = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0]
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks]
 "sp3"=""
@@ -49,9 +48,9 @@ regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudi
 "ProductDir"="C:\Program Files\Microsoft Visual Studio\MSDN98\98VSa\1033"
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++]
 "ProductDir"="C:\Program Files\Microsoft Visual Studio\VC98"
-''','\n')
+'''.split('\n')
 
-regdata_6b = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
+regdata_6b = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0]
 "InstallDir"="C:\VS6\Common\IDE\IDE98"
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks]
@@ -68,9 +67,9 @@ regdata_6b = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudi
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft VSEE Client]
 "ProductDir"="C:\VS6\Common\Tools"
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Visual Studio 98]
-''','\n')
+'''.split('\n')
 
-regdata_7 = string.split(r'''
+regdata_7 = r'''
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0]
 "InstallDir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\"
 "Source Directories"="C:\Program Files\Microsoft Visual Studio .NET\Vc7\crt\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\atl\"
@@ -134,9 +133,9 @@ regdata_7 = string.split(r'''
 "Include Dirs"="$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(VCInstallDir)PlatformSDK\include\prerelease;$(VCInstallDir)PlatformSDK\include;$(FrameworkSDKDir)include"
 "Source Dirs"="$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src"
 "Reference Dirs"=""
-''','\n')
+'''.split('\n')
 
-regdata_7_1 = string.split(r'''
+regdata_7_1 = r'''
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1]
 @=""
 "Source Directories"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\atl\"
@@ -240,9 +239,9 @@ regdata_7_1 = string.split(r'''
 "VCManagedWrapperGeneratorTool"=""
 "VCAuxiliaryManagedWrapperGeneratorTool"=""
 "VCPrimaryInteropTool"=""
-''','\n')
+'''.split('\n')
 
-regdata_8exp = string.split(r'''
+regdata_8exp = r'''
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0]
 "CLR Version"="v2.0.50727"
 "ApplicationID"="VCExpress"
@@ -284,9 +283,9 @@ regdata_8exp = string.split(r'''
 "VCXMLDataGeneratorTool"="*.xsd"
 "VCManifestTool"="*.manifest"
 "VCXDCMakeTool"="*.xdc"
-''','\n')
+'''.split('\n')
 
-regdata_80 = string.split(r'''
+regdata_80 = r'''
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0]
 "CLR Version"="v2.0.50727"
 "ApplicationID"="VisualStudio"
@@ -346,13 +345,13 @@ regdata_80 = string.split(r'''
 "VCXMLDataGeneratorTool"="*.xsd"
 "VCManifestTool"="*.manifest"
 "VCXDCMakeTool"="*.xdc"
-''','\n')
+'''.split('\n')
 
-regdata_cv = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
+regdata_cv = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
 "ProgramFilesDir"="C:\Program Files"
 "CommonFilesDir"="C:\Program Files\Common Files"
 "MediaPath"="C:\WINDOWS\Media"
-''','\n')
+'''.split('\n')
 
 
 regdata_none = []
@@ -376,7 +375,7 @@ class DummyEnv:
         return self.dict[key]
 
     def has_key(self,name):
-        return self.dict.has_key(name)
+        return name in self.dict
 
 class RegKey:
     """key class for storing an 'open' registry key"""
@@ -395,7 +394,7 @@ class RegNode:
         self.name = name
 
     def value(self,val):
-        if self.valdict.has_key(val):
+        if val in self.valdict:
             return (self.valdict[val],1)
         else:
             raise SCons.Util.RegError
@@ -428,13 +427,13 @@ class RegNode:
             raise SCons.Util.RegError
 
     def addKey(self,name,sep = '\\'):
-        if string.find(name, sep) != -1:
-            keyname, subkeys = string.split(name, sep, 1)
+        if name.find(sep) != -1:
+            keyname, subkeys = name.split(sep, 1)
         else:
             keyname = name
             subkeys = ""
 
-        if not self.keydict.has_key(keyname):
+        if keyname not in self.keydict:
             self.keydict[keyname] = RegNode(keyname)
             self.keyarray.append(keyname)
 
@@ -739,7 +738,7 @@ if __name__ == "__main__":
             for k in ['VS71COMNTOOLS',
                       'VS80COMNTOOLS',
                       'VS90COMNTOOLS']:
-                if os.environ.has_key(k):
+                if k in os.environ:
                     del os.environ[k]
 
             suite = unittest.makeSuite(test_class, 'test_')
diff --git a/src/engine/SCons/Tool/mwcc.py b/src/engine/SCons/Tool/mwcc.py
index e83043fe..c720956e 100644
--- a/src/engine/SCons/Tool/mwcc.py
+++ b/src/engine/SCons/Tool/mwcc.py
@@ -34,7 +34,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 
 import SCons.Util
 
@@ -80,8 +79,8 @@ def set_vars(env):
     ENV['CWFolder'] = version.path
     ENV['LM_LICENSE_FILE'] = version.license
     plus = lambda x: '+%s' % x
-    ENV['MWCIncludes'] = string.join(map(plus, version.includes), os.pathsep)
-    ENV['MWLibraries'] = string.join(map(plus, version.libs), os.pathsep)
+    ENV['MWCIncludes'] = os.pathsep.join(map(plus, version.includes))
+    ENV['MWLibraries'] = os.pathsep.join(map(plus, version.libs))
     return 1
 
 
diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py
index c4ae1702..b80f1281 100644
--- a/src/engine/SCons/Tool/packaging/__init__.py
+++ b/src/engine/SCons/Tool/packaging/__init__.py
@@ -25,6 +25,7 @@ SCons Packaging Tool.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -105,16 +106,16 @@ def Package(env, target=None, source=None, **kw):
         kw['PACKAGETYPE'] = GetOption('package_type')
 
     if kw['PACKAGETYPE'] == None:
-        if env['BUILDERS'].has_key('Tar'):
+        if 'Tar' in env['BUILDERS']:
             kw['PACKAGETYPE']='targz'
-        elif env['BUILDERS'].has_key('Zip'):
+        elif 'Zip' in env['BUILDERS']:
             kw['PACKAGETYPE']='zip'
         else:
             raise UserError, "No type for Package() given"
 
     PACKAGETYPE=kw['PACKAGETYPE']
     if not is_List(PACKAGETYPE):
-        PACKAGETYPE=string.split(PACKAGETYPE, ',')
+        PACKAGETYPE=PACKAGETYPE.split(',')
 
     # load the needed packagers.
     def load_packager(type):
@@ -124,7 +125,7 @@ def Package(env, target=None, source=None, **kw):
         except ImportError, e:
             raise EnvironmentError("packager %s not available: %s"%(type,str(e)))
 
-    packagers=map(load_packager, PACKAGETYPE)
+    packagers=list(map(load_packager, PACKAGETYPE))
 
     # set up targets and the PACKAGEROOT
     try:
@@ -139,7 +140,7 @@ def Package(env, target=None, source=None, **kw):
             default_target = default_name%kw
             target.extend( [default_target]*size_diff )
 
-        if not kw.has_key('PACKAGEROOT'):
+        if 'PACKAGEROOT' not in kw:
             kw['PACKAGEROOT'] = default_name%kw
 
     except KeyError, e:
@@ -153,7 +154,7 @@ def Package(env, target=None, source=None, **kw):
     try:
         for packager in packagers:
             t=[target.pop(0)]
-            t=apply(packager.package, [env,t,source], kw)
+            t=packager.package(env,t,source, **kw)
             targets.extend(t)
 
         assert( len(target) == 0 )
@@ -173,8 +174,7 @@ def Package(env, target=None, source=None, **kw):
         args.remove('target')
         args.remove('source')
         # now remove any args for which we have a value in kw.
-        #args=[x for x in args if not kw.has_key(x)]
-        args=filter(lambda x, kw=kw: not kw.has_key(x), args)
+        args=[x for x in args if x not in kw]
 
         if len(args)==0:
             raise # must be a different error, so reraise
@@ -222,7 +222,7 @@ def options(opts):
     opts.AddVariables(
         EnumVariable( 'PACKAGETYPE',
                      'the type of package to create.',
-                     None, allowed_values=map( str, __all__ ),
+                     None, allowed_values=list(map( str, __all__ )),
                      ignorecase=2
                   )
     )
@@ -236,8 +236,8 @@ def copy_attr(f1, f2):
     """
     #pattrs = [x for x in dir(f1) if not hasattr(f2, x) and\
     #                                x.startswith('PACKAGING_')]
-    copyit = lambda x, f2=f2: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
-    pattrs = filter(copyit, dir(f1))
+    copyit = lambda x: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
+    pattrs = list(filter(copyit, dir(f1)))
     for attr in pattrs:
         setattr(f2, attr, getattr(f1, attr))
 def putintopackageroot(target, source, env, pkgroot, honor_install_location=1):
@@ -291,7 +291,7 @@ def stripinstallbuilder(target, source, env):
             (file.builder.name=="InstallBuilder" or\
              file.builder.name=="InstallAsBuilder"))
 
-    if len(filter(has_no_install_location, source)):
+    if len(list(filter(has_no_install_location, source))):
         warn(Warning, "there are files to package which have no\
         InstallBuilder attached, this might lead to irreproducible packages")
 
diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py
index 8575de6c..65494459 100644
--- a/src/engine/SCons/Tool/packaging/ipk.py
+++ b/src/engine/SCons/Tool/packaging/ipk.py
@@ -58,7 +58,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
     buildarchitecture = os.uname()[4]
     buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
 
-    if kw.has_key('ARCHITECTURE'):
+    if 'ARCHITECTURE' in kw:
         buildarchitecture = kw['ARCHITECTURE']
 
     # setup the kw to contain the mandatory arguments to this fucntion.
@@ -76,7 +76,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
         target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ]
 
     # now apply the Ipkg builder
-    return apply(bld, [env, target, specfile], kw)
+    return bld(env, target, specfile, **kw)
 
 def gen_ipk_dir(proot, source, env, kw):
     # make sure the packageroot is a Dir object.
@@ -98,7 +98,7 @@ def gen_ipk_dir(proot, source, env, kw):
     spec_target.append(control.File('preinst'))
 
     # apply the builder to the specfile targets
-    apply(s_bld, [env, spec_target, source], kw)
+    s_bld(env, spec_target, source, **kw)
 
     # the packageroot directory does now contain the specfiles.
     return proot
@@ -125,7 +125,7 @@ def build_specfiles(source, target, env):
 
     control_file=open_file('control', target)
 
-    if not env.has_key('X_IPK_DESCRIPTION'):
+    if 'X_IPK_DESCRIPTION' not in env:
         env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'],
                                             env['DESCRIPTION'].replace('\n', '\n '))
 
@@ -173,7 +173,7 @@ Description: $X_IPK_DESCRIPTION
         f.close()
 
     # call a user specified function
-    if env.has_key('CHANGE_SPECFILE'):
+    if 'CHANGE_SPECFILE' in env:
         content += env['CHANGE_SPECFILE'](target)
 
     return 0
diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py
index 41ea0b33..95adbedd 100644
--- a/src/engine/SCons/Tool/packaging/msi.py
+++ b/src/engine/SCons/Tool/packaging/msi.py
@@ -25,6 +25,7 @@ The msi packager.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -65,14 +66,14 @@ def convert_to_id(s, id_set):
     charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789_.'
     if s[0] in '0123456789.':
         s += '_'+s
-    id = filter( lambda c : c in charset, s )
+    id = [c for c in s if c in charset]
 
     # did we already generate an id for this file?
     try:
         return id_set[id][s]
     except KeyError:
         # no we did not so initialize with the id
-        if not id_set.has_key(id): id_set[id] = { s : id }
+        if id not in id_set: id_set[id] = { s : id }
         # there is a collision, generate an id which is unique by appending
         # the collision number
         else: id_set[id][s] = id + str(len(id_set[id]))
@@ -109,7 +110,7 @@ def gen_dos_short_file_name(file, filename_set):
 
     # strip forbidden characters.
     forbidden = '."/[]:;=, '
-    fname = filter( lambda c : c not in forbidden, fname )
+    fname = [c for c in fname if c not in forbidden]
 
     # check if we already generated a filename with the same number:
     # thisis1.txt, thisis2.txt etc.
@@ -137,7 +138,7 @@ def create_feature_dict(files):
             feature = [ feature ]
 
         for f in feature:
-            if not dict.has_key( f ):
+            if f not in dict:
                 dict[ f ] = [ file ]
             else:
                 dict[ f ].append( file )
@@ -214,7 +215,7 @@ def build_wxsfile(target, source, env):
         file.write( doc.toprettyxml() )
 
         # call a user specified function
-        if env.has_key('CHANGE_SPECFILE'):
+        if 'CHANGE_SPECFILE' in env:
             env['CHANGE_SPECFILE'](target, source)
 
     except KeyError, e:
@@ -296,9 +297,11 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set,
         upper_dir = ''
 
         # walk down the xml tree finding parts of the directory
-        dir_parts = filter( lambda d: d != '', dir_parts )
+        dir_parts = [d for d in dir_parts if d != '']
         for d in dir_parts[:]:
-            already_created = filter( lambda c: c.nodeName == 'Directory' and c.attributes['LongName'].value == escape(d), Directory.childNodes ) 
+            already_created = [c for c in Directory.childNodes
+                               if c.nodeName == 'Directory'
+                               and c.attributes['LongName'].value == escape(d)] 
 
             if already_created != []:
                 Directory = already_created[0]
@@ -464,7 +467,7 @@ def build_wxsfile_header_section(root, spec):
     Product.childNodes.append( Package )
 
     # set "mandatory" default values
-    if not spec.has_key('X_MSI_LANGUAGE'):
+    if 'X_MSI_LANGUAGE' not in spec:
         spec['X_MSI_LANGUAGE'] = '1033' # select english
 
     # mandatory sections, will throw a KeyError if the tag is not available
@@ -475,10 +478,10 @@ def build_wxsfile_header_section(root, spec):
     Package.attributes['Description']  = escape( spec['SUMMARY'] )
 
     # now the optional tags, for which we avoid the KeyErrror exception
-    if spec.has_key( 'DESCRIPTION' ):
+    if 'DESCRIPTION' in spec:
         Package.attributes['Comments'] = escape( spec['DESCRIPTION'] )
 
-    if spec.has_key( 'X_MSI_UPGRADE_CODE' ):
+    if 'X_MSI_UPGRADE_CODE' in spec:
         Package.attributes['X_MSI_UPGRADE_CODE'] = escape( spec['X_MSI_UPGRADE_CODE'] )
 
     # We hardcode the media tag as our current model cannot handle it.
@@ -511,7 +514,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
 
     # put the arguments into the env and call the specfile builder.
     env['msi_spec'] = kw
-    specfile = apply( wxs_builder, [env, target, source], kw )
+    specfile = wxs_builder(* [env, target, source], **kw)
 
     # now call the WiX Tool with the built specfile added as a source.
     msifile  = env.WiX(target, specfile)
diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py
index c2a532c4..74805429 100644
--- a/src/engine/SCons/Tool/packaging/rpm.py
+++ b/src/engine/SCons/Tool/packaging/rpm.py
@@ -25,11 +25,11 @@ The rpm packager.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import SCons.Builder
 
@@ -65,7 +65,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
         buildarchitecture = os.uname()[4]
         buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
 
-        if kw.has_key('ARCHITECTURE'):
+        if 'ARCHITECTURE' in kw:
             buildarchitecture = kw['ARCHITECTURE']
 
         fmt = '%s-%s-%s.%s.rpm'
@@ -81,9 +81,9 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
     del kw['source'], kw['target'], kw['env']
 
     # if no "SOURCE_URL" tag is given add a default one.
-    if not kw.has_key('SOURCE_URL'):
+    if 'SOURCE_URL' not in kw:
         #kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
-        kw['SOURCE_URL']=string.replace(str(target[0])+".tar.gz", '.rpm', '')
+        kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
 
     # mangle the source and target list for the rpmbuild
     env = OverrideEnvironment(env, kw)
@@ -92,7 +92,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
     target, source = collectintargz(target, source, env)
 
     # now call the rpm builder to actually build the packet.
-    return apply(bld, [env, target, source], kw)
+    return bld(env, target, source, **kw)
 
 def collectintargz(target, source, env):
     """ Puts all source files into a tar.gz file. """
@@ -102,21 +102,21 @@ def collectintargz(target, source, env):
 
     # filter out the target we are building the source list for.
     #sources = [s for s in sources if not (s in target)]
-    sources = filter(lambda s, t=target: not (s in t), sources)
+    sources = [s for s in sources if s not in target]
 
     # find the .spec file for rpm and add it since it is not necessarily found
     # by the FindSourceFiles function.
     #sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] )
-    spec_file = lambda s: string.rfind(str(s), '.spec') != -1
-    sources.extend( filter(spec_file, source) )
+    spec_file = lambda s: str(s).rfind('.spec') != -1
+    sources.extend( list(filter(spec_file, source)) )
 
     # as the source contains the url of the source package this rpm package
     # is built from, we extract the target name
     #tarball = (str(target[0])+".tar.gz").replace('.rpm', '')
-    tarball = string.replace(str(target[0])+".tar.gz", '.rpm', '')
+    tarball = (str(target[0])+".tar.gz").replace('.rpm', '')
     try:
         #tarball = env['SOURCE_URL'].split('/')[-1]
-        tarball = string.split(env['SOURCE_URL'], '/')[-1]
+        tarball = env['SOURCE_URL'].split('/')[-1]
     except KeyError, e:
         raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] )
 
@@ -150,7 +150,7 @@ def build_specfile(target, source, env):
         file.close()
 
         # call a user specified function
-        if env.has_key('CHANGE_SPECFILE'):
+        if 'CHANGE_SPECFILE' in env:
             env['CHANGE_SPECFILE'](target, source)
 
     except KeyError, e:
@@ -188,16 +188,16 @@ def build_specfile_sections(spec):
 
     # Default prep, build, install and clean rules
     # TODO: optimize those build steps, to not compile the project a second time
-    if not spec.has_key('X_RPM_PREP'):
+    if 'X_RPM_PREP' not in spec:
         spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q'
 
-    if not spec.has_key('X_RPM_BUILD'):
+    if 'X_RPM_BUILD' not in spec:
         spec['X_RPM_BUILD'] = 'mkdir "$RPM_BUILD_ROOT"'
 
-    if not spec.has_key('X_RPM_INSTALL'):
+    if 'X_RPM_INSTALL' not in spec:
         spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"'
 
-    if not spec.has_key('X_RPM_CLEAN'):
+    if 'X_RPM_CLEAN' not in spec:
         spec['X_RPM_CLEAN'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"'
 
     str = str + SimpleTagCompiler(optional_sections, mandatory=0).compile( spec )
@@ -254,7 +254,7 @@ def build_specfile_header(spec):
 #    if not s.has_key('x_rpm_BuildRequires'):
 #        s['x_rpm_BuildRequires'] = 'scons'
 
-    if not spec.has_key('X_RPM_BUILDROOT'):
+    if 'X_RPM_BUILDROOT' not in spec:
         spec['X_RPM_BUILDROOT'] = '%{_tmppath}/%{name}-%{version}-%{release}'
 
     str = str + SimpleTagCompiler(optional_header_fields, mandatory=0).compile( spec )
@@ -268,7 +268,7 @@ def build_specfile_filesection(spec, files):
     """
     str  = '%files\n'
 
-    if not spec.has_key('X_RPM_DEFATTR'):
+    if 'X_RPM_DEFATTR' not in spec:
         spec['X_RPM_DEFATTR'] = '(-,root,root)'
 
     str = str + '%%defattr %s\n' % spec['X_RPM_DEFATTR']
@@ -337,7 +337,7 @@ class SimpleTagCompiler:
 
         str = ""
         #domestic = [ (k,v) for k,v in replacements if not is_international(k) ]
-        domestic = filter(lambda t, i=is_international: not i(t[0]), replacements)
+        domestic = [t for t in replacements if not is_international(t[0])]
         for key, replacement in domestic:
             try:
                 str = str + replacement % values[key]
@@ -346,12 +346,12 @@ class SimpleTagCompiler:
                     raise e
 
         #international = [ (k,v) for k,v in replacements if is_international(k) ]
-        international = filter(lambda t, i=is_international: i(t[0]), replacements)
+        international = [t for t in replacements if is_international(t[0])]
         for key, replacement in international:
             try:
                 #int_values_for_key = [ (get_country_code(k),v) for k,v in values.items() if strip_country_code(k) == key ]
-                x = filter(lambda t,key=key,s=strip_country_code: s(t[0]) == key, values.items())
-                int_values_for_key = map(lambda t,g=get_country_code: (g(t[0]),t[1]), x)
+                x = [t for t in values.items() if strip_country_code(t[0]) == key]
+                int_values_for_key = [(get_country_code(t[0]),t[1]) for t in x]
                 for v in int_values_for_key:
                     str = str + replacement % v
             except KeyError, e:
diff --git a/src/engine/SCons/Tool/rmic.py b/src/engine/SCons/Tool/rmic.py
index 8720d3dd..75096721 100644
--- a/src/engine/SCons/Tool/rmic.py
+++ b/src/engine/SCons/Tool/rmic.py
@@ -34,7 +34,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 import SCons.Action
 import SCons.Builder
@@ -86,7 +85,7 @@ def emit_rmic_classes(target, source, env):
     tlist = []
     for s in source:
         for suff in stub_suffixes:
-            fname = string.replace(s.attributes.java_classname, '.', os.sep) + \
+            fname = s.attributes.java_classname.replace('.', os.sep) + \
                     suff + class_suffix
             t = target[0].File(fname)
             t.attributes.java_lookupdir = target[0]
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index c473b103..c6815f7c 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
 import re
-import string
 import subprocess
 
 import SCons.Action
@@ -72,7 +71,7 @@ def _find_modules(src):
 
     for m in matches:
         mnames.append(m[2])
-        directors = directors or string.find(m[0], 'directors') >= 0
+        directors = directors or m[0].find('directors') >= 0
     return mnames, directors
 
 def _add_director_header_targets(target, env):
@@ -97,29 +96,26 @@ def _swigEmitter(target, source, env):
                 mnames, directors = _find_modules(src)
             if directors:
                 _add_director_header_targets(target, env)
-            python_files = map(lambda m: m + ".py", mnames)
+            python_files = [m + ".py" for m in mnames]
             outdir = env.subst('$SWIGOUTDIR', target=target, source=source)
             # .py files should be generated in SWIGOUTDIR if specified,
             # otherwise in the same directory as the target
             if outdir:
-                python_files = map(lambda j, o=outdir, e=env:
-                                   e.fs.File(os.path.join(o, j)),
-                                   python_files)
+                python_files = [env.fs.File(os.path.join(outdir, j)) for j in python_files]
             else:
-                python_files = map(lambda m, d=target[0].dir:
-                                   d.File(m), python_files)
+                python_files = [target[0].dir.File(m) for m in python_files]
             target.extend(python_files)
         if "-java" in flags:
             if mnames is None:
                 mnames, directors = _find_modules(src)
             if directors:
                 _add_director_header_targets(target, env)
-            java_files = map(lambda m: [m + ".java", m + "JNI.java"], mnames)
+            java_files = [[m + ".java", m + "JNI.java"] for m in mnames]
             java_files = SCons.Util.flatten(java_files)
             outdir = env.subst('$SWIGOUTDIR', target=target, source=source)
             if outdir:
-                 java_files = map(lambda j, o=outdir: os.path.join(o, j), java_files)
-            java_files = map(env.fs.File, java_files)
+                 java_files = [os.path.join(outdir, j) for j in java_files]
+            java_files = list(map(env.fs.File, java_files))
             for jf in java_files:
                 t_from_s = lambda t, p, s, x: t.dir
                 SCons.Util.AddMethod(jf, t_from_s, 'target_from_source')
diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py
index 11e06bfc..4960c5d7 100644
--- a/src/engine/SCons/Tool/tex.py
+++ b/src/engine/SCons/Tool/tex.py
@@ -36,7 +36,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
 import re
-import string
 import shutil
 
 import SCons.Action
@@ -292,7 +291,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
                 target_aux = os.path.join(targetdir, auxfilename)
                 if os.path.exists(target_aux):
                     content = open(target_aux, "rb").read()
-                    if string.find(content, "bibdata") != -1:
+                    if content.find("bibdata") != -1:
                         if Verbose:
                             print "Need to run bibtex"
                         bibfile = env.fs.File(targetbase)
@@ -422,7 +421,7 @@ def is_LaTeX(flist,env,abspath):
         # Split at os.pathsep to convert into absolute path
         # TODO(1.5)
         #paths = paths.split(os.pathsep)
-        paths = string.split(paths, os.pathsep)
+        paths = paths.split(os.pathsep)
 
     # now that we have the path list restore the env
     if savedpath is _null:
@@ -648,7 +647,7 @@ def tex_emitter_core(target, source, env, graphics_extensions):
         # Split at os.pathsep to convert into absolute path
         # TODO(1.5)
         #paths = paths.split(os.pathsep)
-        paths = string.split(paths, os.pathsep)
+        paths = paths.split(os.pathsep)
 
     # now that we have the path list restore the env
     if savedpath is _null:
diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py
index 67b61f49..57330148 100644
--- a/src/engine/SCons/Tool/textfile.py
+++ b/src/engine/SCons/Tool/textfile.py
@@ -84,7 +84,7 @@ def _action(target, source, env):
                                          % repr(linesep), None)
 
     # create a dictionary to use for the substitutions
-    if not env.has_key('SUBST_DICT'):
+    if 'SUBST_DICT' not in env:
         subs = None    # no substitutions
     else:
         d = env['SUBST_DICT']
diff --git a/src/engine/SCons/Tool/wix.py b/src/engine/SCons/Tool/wix.py
index 5737df21..32cc1f1e 100644
--- a/src/engine/SCons/Tool/wix.py
+++ b/src/engine/SCons/Tool/wix.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import SCons.Builder
 import SCons.Action
 import os
-import string
 
 def generate(env):
     """Add Builders and construction variables for WiX to an Environment."""
@@ -68,7 +67,7 @@ def exists(env):
     # try to find the candle.exe and light.exe tools and 
     # add the install directory to light libpath.
     #for path in os.environ['PATH'].split(os.pathsep):
-    for path in string.split(os.environ['PATH'], os.pathsep):
+    for path in os.environ['PATH'].split(os.pathsep):
         if not path:
             continue
 
diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py
index 4d551e6b..ca5e2fc0 100644
--- a/src/engine/SCons/Tool/yacc.py
+++ b/src/engine/SCons/Tool/yacc.py
@@ -34,7 +34,6 @@ selection method.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 import SCons.Defaults
 import SCons.Tool
@@ -71,7 +70,7 @@ def _yaccEmitter(target, source, env, ysuf, hsuf):
             if option[:l] == fileGenOption:
                 # A file generating option is present, so add the file
                 # name to the list of targets.
-                fileName = string.strip(option[l:])
+                fileName = option[l:].strip()
                 target.append(fileName)
 
     return (target, source)
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 9e5fe38d..709cf1f0 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -33,7 +33,6 @@ import copy
 import os
 import os.path
 import re
-import string
 import sys
 import types
 
@@ -59,11 +58,11 @@ if _altsep is None and sys.platform == 'win32':
     # My ActivePython 2.0.1 doesn't set os.altsep!  What gives?
     _altsep = '/'
 if _altsep:
-    def rightmost_separator(path, sep, _altsep=_altsep):
-        rfind = string.rfind
-        return max(rfind(path, sep), rfind(path, _altsep))
+    def rightmost_separator(path, sep):
+        return max(path.rfind(sep), path.rfind(_altsep))
 else:
-    rightmost_separator = string.rfind
+    def rightmost_separator(path, sep):
+        return path.rfind(sep)
 
 # First two from the Python Cookbook, just for completeness.
 # (Yeah, yeah, YAGNI...)
@@ -88,7 +87,7 @@ def containsOnly(str, set):
 def splitext(path):
     "Same as os.path.splitext() but faster."
     sep = rightmost_separator(path, os.sep)
-    dot = string.rfind(path, '.')
+    dot = path.rfind('.')
     # An ext is only real if it has at least one non-digit char
     if dot > sep and not containsOnly(path[dot:], "0123456789."):
         return path[:dot],path[dot:]
@@ -104,7 +103,7 @@ def updrive(path):
     """
     drive, rest = os.path.splitdrive(path)
     if drive:
-        path = string.upper(drive) + rest
+        path = drive.upper() + rest
     return path
 
 class NodeList(UserList):
@@ -121,20 +120,17 @@ class NodeList(UserList):
         return len(self.data) != 0
 
     def __str__(self):
-        return string.join(map(str, self.data))
+        return ' '.join(map(str, self.data))
 
     def __iter__(self):
         return iter(self.data)
 
     def __call__(self, *args, **kwargs):
-        result = map(lambda x, args=args, kwargs=kwargs: apply(x,
-                                                               args,
-                                                               kwargs),
-                     self.data)
+        result = [x(*args, **kwargs) for x in self.data]
         return self.__class__(result)
 
     def __getattr__(self, name):
-        result = map(lambda x, n=name: getattr(x, n), self.data)
+        result = [getattr(x, name) for x in self.data]
         return self.__class__(result)
 
 
@@ -204,7 +200,7 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}):
         else:
             retval = retval + "  "
 
-    if visited.has_key(rname):
+    if rname in visited:
         return retval + "+-[" + rname + "]\n"
 
     retval = retval + "+-" + rname + "\n"
@@ -273,15 +269,15 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}):
 
     def MMM(m):
         return ["  ","| "][m]
-    margins = map(MMM, margin[:-1])
+    margins = list(map(MMM, margin[:-1]))
 
     children = child_func(root)
 
-    if prune and visited.has_key(rname) and children:
-        print string.join(tags + margins + ['+-[', rname, ']'], '')
+    if prune and rname in visited and children:
+        print ''.join(tags + margins + ['+-[', rname, ']'])
         return
 
-    print string.join(tags + margins + ['+-', rname], '')
+    print ''.join(tags + margins + ['+-', rname])
 
     visited[rname] = 1
 
@@ -426,7 +422,7 @@ except TypeError:
 
     def to_String_for_subst(s):
         if is_Sequence( s ):
-            return string.join( map(to_String_for_subst, s) )
+            return ' '.join( map(to_String_for_subst, s) )
 
         return to_String( s )
 
@@ -543,7 +539,7 @@ else:
             return str(s)
 
     def to_String_for_subst(s, 
-                            isinstance=isinstance, join=string.join, str=str, to_String=to_String,
+                            isinstance=isinstance, str=str, to_String=to_String,
                             BaseStringTypes=BaseStringTypes, SequenceTypes=SequenceTypes,
                             UserString=UserString):
                             
@@ -554,7 +550,7 @@ else:
             l = []
             for e in s:
                 l.append(to_String_for_subst(e))
-            return join( s )
+            return ' '.join( s )
         elif isinstance(s, UserString):
             # s.data can only be either a unicode or a regular
             # string. Please see the UserString initializer.
@@ -602,7 +598,7 @@ def _semi_deepcopy_dict(x):
 d[types.DictionaryType] = _semi_deepcopy_dict
 
 def _semi_deepcopy_list(x):
-    return map(semi_deepcopy, x)
+    return list(map(semi_deepcopy, x))
 d[types.ListType] = _semi_deepcopy_list
 
 def _semi_deepcopy_tuple(x):
@@ -766,16 +762,16 @@ if sys.platform == 'win32':
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if pathext is None:
             try:
                 pathext = os.environ['PATHEXT']
             except KeyError:
                 pathext = '.COM;.EXE;.BAT;.CMD'
         if is_String(pathext):
-            pathext = string.split(pathext, os.pathsep)
+            pathext = pathext.split(os.pathsep)
         for ext in pathext:
-            if string.lower(ext) == string.lower(file[-len(ext):]):
+            if ext.lower() == file[-len(ext):].lower():
                 pathext = ['']
                 break
         if not is_List(reject) and not is_Tuple(reject):
@@ -801,11 +797,11 @@ elif os.name == 'os2':
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if pathext is None:
             pathext = ['.exe', '.cmd']
         for ext in pathext:
-            if string.lower(ext) == string.lower(file[-len(ext):]):
+            if ext.lower() == file[-len(ext):].lower():
                 pathext = ['']
                 break
         if not is_List(reject) and not is_Tuple(reject):
@@ -832,7 +828,7 @@ else:
             except KeyError:
                 return None
         if is_String(path):
-            path = string.split(path, os.pathsep)
+            path = path.split(os.pathsep)
         if not is_List(reject) and not is_Tuple(reject):
             reject = [reject]
         for d in path:
@@ -881,18 +877,18 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
     is_list = 1
     paths = orig
     if not is_List(orig) and not is_Tuple(orig):
-        paths = string.split(paths, sep)
+        paths = paths.split(sep)
         is_list = 0
 
     if is_String(newpath):
-        newpaths = string.split(newpath, sep)
+        newpaths = newpath.split(sep)
     elif not is_List(newpath) and not is_Tuple(newpath):
         newpaths = [ newpath ]  # might be a Dir
     else:
         newpaths = newpath
 
     if canonicalize:
-        newpaths=map(canonicalize, newpaths)
+        newpaths=list(map(canonicalize, newpaths))
 
     if not delete_existing:
         # First uniquify the old paths, making sure to 
@@ -934,7 +930,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
     if is_list:
         return paths
     else:
-        return string.join(paths, sep)
+        return sep.join(paths)
 
 def AppendPath(oldpath, newpath, sep = os.pathsep, 
                delete_existing=1, canonicalize=None):
@@ -962,18 +958,18 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
     is_list = 1
     paths = orig
     if not is_List(orig) and not is_Tuple(orig):
-        paths = string.split(paths, sep)
+        paths = paths.split(sep)
         is_list = 0
 
     if is_String(newpath):
-        newpaths = string.split(newpath, sep)
+        newpaths = newpath.split(sep)
     elif not is_List(newpath) and not is_Tuple(newpath):
         newpaths = [ newpath ]  # might be a Dir
     else:
         newpaths = newpath
 
     if canonicalize:
-        newpaths=map(canonicalize, newpaths)
+        newpaths=list(map(canonicalize, newpaths))
 
     if not delete_existing:
         # add old paths to result, then
@@ -1015,13 +1011,13 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
     if is_list:
         return paths
     else:
-        return string.join(paths, sep)
+        return sep.join(paths)
 
 if sys.platform == 'cygwin':
     def get_native_path(path):
         """Transforms an absolute path into a native path for the system.  In
         Cygwin, this converts from a Cygwin path to a Windows one."""
-        return string.replace(os.popen('cygpath -w ' + path).read(), '\n', '')
+        return os.popen('cygpath -w ' + path).read().replace('\n', '')
 else:
     def get_native_path(path):
         """Transforms an absolute path into a native path for the system.
@@ -1034,7 +1030,7 @@ def Split(arg):
     if is_List(arg) or is_Tuple(arg):
         return arg
     elif is_String(arg):
-        return string.split(arg)
+        return arg.split()
     else:
         return [arg]
 
@@ -1057,7 +1053,7 @@ class CLVar(UserList):
     def __coerce__(self, other):
         return (self, CLVar(other))
     def __str__(self):
-        return string.join(self.data)
+        return ' '.join(self.data)
 
 # A dictionary that preserves the order in which items are added.
 # Submitted by David Benjamin to ActiveState's Python Cookbook web site:
@@ -1111,7 +1107,7 @@ class OrderedDict(UserDict):
             self.__setitem__(key, val)
 
     def values(self):
-        return map(self.get, self._keys)
+        return list(map(self.get, self._keys))
 
 class Selector(OrderedDict):
     """A callable ordered dictionary that maps file suffixes to
@@ -1132,7 +1128,7 @@ class Selector(OrderedDict):
             for (k,v) in self.items():
                 if k is not None:
                     s_k = env.subst(k)
-                    if s_dict.has_key(s_k):
+                    if s_k in s_dict:
                         # We only raise an error when variables point
                         # to the same suffix.  If one suffix is literal
                         # and a variable suffix contains this literal,
@@ -1279,7 +1275,7 @@ def uniquer_hashables(seq):
     result = []
     for item in seq:
         #if not item in seen:
-        if not seen.has_key(item):
+        if item not in seen:
             seen[item] = 1
             result.append(item)
     return result
@@ -1304,7 +1300,7 @@ class LogicalLines:
             else:
                 result.append(line)
                 break
-        return string.join(result, '')
+        return ''.join(result)
 
     def readlines(self):
         result = []
@@ -1402,8 +1398,7 @@ class UniqueList(UserList):
         UserList.reverse(self)
     def sort(self, *args, **kwds):
         self.__make_unique()
-        #return UserList.sort(self, *args, **kwds)
-        return apply(UserList.sort, (self,)+args, kwds)
+        return UserList.sort(self, *args, **kwds)
     def extend(self, other):
         UserList.extend(self, other)
         self.unique = False
@@ -1568,7 +1563,7 @@ def MD5collect(signatures):
     if len(signatures) == 1:
         return signatures[0]
     else:
-        return MD5signature(string.join(signatures, ', '))
+        return MD5signature(', '.join(signatures))
 
 
 
@@ -1605,8 +1600,7 @@ class Null:
     """ Null objects always and reliably "do nothing." """
     def __new__(cls, *args, **kwargs):
         if not '_inst' in vars(cls):
-            #cls._inst = type.__new__(cls, *args, **kwargs)
-            cls._inst = apply(type.__new__, (cls,) + args, kwargs)
+            cls._inst = type.__new__(cls, *args, **kwargs)
         return cls._inst
     def __init__(self, *args, **kwargs):
         pass
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
index 9d013ca4..670fc83c 100644
--- a/src/engine/SCons/UtilTests.py
+++ b/src/engine/SCons/UtilTests.py
@@ -25,7 +25,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
-import string
 import StringIO
 import sys
 import types
@@ -112,9 +111,9 @@ class UtilTestCase(unittest.TestCase):
       +-windows.h
 """
 
-        lines = string.split(expect, '\n')[:-1]
-        lines = map(lambda l: '[E BSPACN ]'+l, lines)
-        withtags = string.join(lines, '\n') + '\n'
+        lines = expect.split('\n')[:-1]
+        lines = ['[E BSPACN ]'+l for l in lines]
+        withtags = '\n'.join(lines) + '\n'
 
         return foo, expect, withtags
 
@@ -137,12 +136,12 @@ class UtilTestCase(unittest.TestCase):
 """
 
         if not prune:
-            expect = string.replace(expect, '[', '')
-            expect = string.replace(expect, ']', '')
+            expect = expect.replace('[', '')
+            expect = expect.replace(']', '')
 
-        lines = string.split(expect, '\n')[:-1]
-        lines = map(lambda l: '[E BSPACN ]'+l, lines)
-        withtags = string.join(lines, '\n') + '\n'
+        lines = expect.split('\n')[:-1]
+        lines = ['[E BSPACN ]'+l for l in lines]
+        withtags = '\n'.join(lines) + '\n'
 
         return blat_o, expect, withtags
 
@@ -333,20 +332,20 @@ class UtilTestCase(unittest.TestCase):
                               test.workpath('sub2'),
                               test.workpath('sub3'),
                               test.workpath('sub4'),
-                            ] + string.split(env_path, os.pathsep)
+                            ] + env_path.split(os.pathsep)
 
             pathdirs_1243 = [ test.workpath('sub1'),
                               test.workpath('sub2'),
                               test.workpath('sub4'),
                               test.workpath('sub3'),
-                            ] + string.split(env_path, os.pathsep)
+                            ] + env_path.split(os.pathsep)
 
-            os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
+            os.environ['PATH'] = os.pathsep.join(pathdirs_1234)
             wi = WhereIs('xxx.exe')
             assert wi == test.workpath(sub3_xxx_exe), wi
             wi = WhereIs('xxx.exe', pathdirs_1243)
             assert wi == test.workpath(sub4_xxx_exe), wi
-            wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
+            wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
             assert wi == test.workpath(sub4_xxx_exe), wi
 
             wi = WhereIs('xxx.exe',reject = sub3_xxx_exe)
@@ -354,12 +353,12 @@ class UtilTestCase(unittest.TestCase):
             wi = WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
             assert wi == test.workpath(sub4_xxx_exe), wi
 
-            os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
+            os.environ['PATH'] = os.pathsep.join(pathdirs_1243)
             wi = WhereIs('xxx.exe')
             assert wi == test.workpath(sub4_xxx_exe), wi
             wi = WhereIs('xxx.exe', pathdirs_1234)
             assert wi == test.workpath(sub3_xxx_exe), wi
-            wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
+            wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
             assert wi == test.workpath(sub3_xxx_exe), wi
 
             if sys.platform == 'win32':
@@ -370,13 +369,13 @@ class UtilTestCase(unittest.TestCase):
                 assert wi == test.workpath(sub4_xxx_exe), wi
 
                 wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
-                assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+                assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
 
                 # Test that we return a normalized path even when
                 # the path contains forward slashes.
                 forward_slash = test.workpath('') + '/sub3'
                 wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
-                assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+                assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
 
             del os.environ['PATH']
             wi = WhereIs('xxx.exe')
@@ -710,7 +709,7 @@ class MD5TestCase(unittest.TestCase):
     def test_collect(self):
         """Test collecting a list of signatures into a new signature value
         """
-        s = map(MD5signature, ('111', '222', '333'))
+        s = list(map(MD5signature, ('111', '222', '333')))
         
         assert '698d51a19d8a121ce581499d7b701668' == MD5collect(s[0:1])
         assert '8980c988edc2c78cc43ccb718c06efd5' == MD5collect(s[0:2])
@@ -791,7 +790,7 @@ if __name__ == "__main__":
                ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Variables/BoolVariable.py b/src/engine/SCons/Variables/BoolVariable.py
index c1a20e39..6bc66bb1 100644
--- a/src/engine/SCons/Variables/BoolVariable.py
+++ b/src/engine/SCons/Variables/BoolVariable.py
@@ -38,8 +38,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 __all__ = ['BoolVariable',]
 
-import string
-
 import SCons.Errors
 
 __true_strings  = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
@@ -57,7 +55,7 @@ def _text2bool(val):
 
     This is usable as 'converter' for SCons' Variables.
     """
-    lval = string.lower(val)
+    lval = val.lower()
     if lval in __true_strings: return True
     if lval in __false_strings: return False
     raise ValueError("Invalid value for boolean option: %s" % val)
diff --git a/src/engine/SCons/Variables/EnumVariable.py b/src/engine/SCons/Variables/EnumVariable.py
index b8f30bf5..71302eeb 100644
--- a/src/engine/SCons/Variables/EnumVariable.py
+++ b/src/engine/SCons/Variables/EnumVariable.py
@@ -41,7 +41,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 __all__ = ['EnumVariable',]
 
-import string
 
 import SCons.Errors
 
@@ -80,24 +79,21 @@ def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0):
     given 'map'-dictionary (unmapped input values are returned
     unchanged). 
     """
-    help = '%s (%s)' % (help, string.join(allowed_values, '|'))
+    help = '%s (%s)' % (help, '|'.join(allowed_values))
     # define validator
     if ignorecase >= 1:
-        validator = lambda key, val, env, vals=allowed_values: \
-                    _validator(key, string.lower(val), env, vals)
+        validator = lambda key, val, env: \
+                    _validator(key, val.lower(), env, allowed_values)
     else:
-        validator = lambda key, val, env, vals=allowed_values: \
-                    _validator(key, val, env, vals)
+        validator = lambda key, val, env: \
+                    _validator(key, val, env, allowed_values)
     # define converter
     if ignorecase == 2:
-        converter = lambda val, map=map: \
-                    string.lower(map.get(string.lower(val), val))
+        converter = lambda val: map.get(val.lower(), val).lower()
     elif ignorecase == 1:
-        converter = lambda val, map=map: \
-                    map.get(string.lower(val), val)
+        converter = lambda val: map.get(val.lower(), val)
     else:
-        converter = lambda val, map=map: \
-                    map.get(val, val)
+        converter = lambda val: map.get(val, val)
     return (key, help, default, validator, converter)
 
 # Local Variables:
diff --git a/src/engine/SCons/Variables/ListVariable.py b/src/engine/SCons/Variables/ListVariable.py
index 521fa4f9..36b530a9 100644
--- a/src/engine/SCons/Variables/ListVariable.py
+++ b/src/engine/SCons/Variables/ListVariable.py
@@ -46,6 +46,7 @@ Usage example:
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -54,7 +55,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 __all__ = ['ListVariable',]
 
-import string
 import UserList
 
 import SCons.Util
@@ -62,7 +62,7 @@ import SCons.Util
 
 class _ListVariable(UserList.UserList):
     def __init__(self, initlist=[], allowedElems=[]):
-        UserList.UserList.__init__(self, filter(None, initlist))
+        UserList.UserList.__init__(self, [_f for _f in initlist if _f])
         self.allowedElems = allowedElems[:]
         self.allowedElems.sort()
 
@@ -85,7 +85,7 @@ class _ListVariable(UserList.UserList):
         if self.data == self.allowedElems:
             return 'all'
         else:
-            return string.join(self, ',')
+            return ','.join(self)
     def prepare_to_store(self):
         return self.__str__()
 
@@ -97,12 +97,12 @@ def _converter(val, allowedElems, mapdict):
     elif val == 'all':
         val = allowedElems
     else:
-        val = filter(None, string.split(val, ','))
-        val = map(lambda v, m=mapdict: m.get(v, v), val)
-        notAllowed = filter(lambda v, aE=allowedElems: not v in aE, val)
+        val = [_f for _f in val.split(',') if _f]
+        val = [mapdict.get(v, v) for v in val]
+        notAllowed = [v for v in val if not v in allowedElems]
         if notAllowed:
             raise ValueError("Invalid value(s) for option: %s" %
-                             string.join(notAllowed, ','))
+                             ','.join(notAllowed))
     return _ListVariable(val, allowedElems)
 
 
@@ -122,15 +122,14 @@ def ListVariable(key, help, default, names, map={}):
     A 'package list' option may either be 'all', 'none' or a list of
     package names (separated by space).
     """
-    names_str = 'allowed names: %s' % string.join(names, ' ')
+    names_str = 'allowed names: %s' % ' '.join(names)
     if SCons.Util.is_List(default):
-        default = string.join(default, ',')
-    help = string.join(
-        (help, '(all|none|comma-separated list of names)', names_str),
-        '\n    ')
+        default = ','.join(default)
+    help = '\n    '.join(
+        (help, '(all|none|comma-separated list of names)', names_str))
     return (key, help, default,
             None, #_validator,
-            lambda val, elems=names, m=map: _converter(val, elems, m))
+            lambda val: _converter(val, names, map))
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Variables/PackageVariable.py b/src/engine/SCons/Variables/PackageVariable.py
index 294a3988..440d0f65 100644
--- a/src/engine/SCons/Variables/PackageVariable.py
+++ b/src/engine/SCons/Variables/PackageVariable.py
@@ -54,8 +54,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 __all__ = ['PackageVariable',]
 
-import string
-
 import SCons.Errors
 
 __enable_strings  = ('1', 'yes', 'true',  'on', 'enable', 'search')
@@ -64,7 +62,7 @@ __disable_strings = ('0', 'no',  'false', 'off', 'disable')
 def _converter(val):
     """
     """
-    lval = string.lower(val)
+    lval = val.lower()
     if lval in __enable_strings: return True
     if lval in __disable_strings: return False
     #raise ValueError("Invalid value for boolean option: %s" % val)
@@ -95,11 +93,10 @@ def PackageVariable(key, help, default, searchfunc=None):
     A 'package list' option may either be 'all', 'none' or a list of
     package names (seperated by space).
     """
-    help = string.join(
-        (help, '( yes | no | /path/to/%s )' % key),
-        '\n    ')
+    help = '\n    '.join(
+        (help, '( yes | no | /path/to/%s )' % key))
     return (key, help, default,
-            lambda k, v, e, f=searchfunc: _validator(k,v,e,f),
+            lambda k, v, e: _validator(k,v,e,searchfunc),
             _converter)
 
 # Local Variables:
diff --git a/src/engine/SCons/Variables/VariablesTests.py b/src/engine/SCons/Variables/VariablesTests.py
index 493d69f4..4fa08792 100644
--- a/src/engine/SCons/Variables/VariablesTests.py
+++ b/src/engine/SCons/Variables/VariablesTests.py
@@ -41,8 +41,10 @@ class Environment:
         self.dict[key] = value
     def __getitem__(self, key):
         return self.dict[key]
+    def __contains__(self, key):
+        return self.dict.__contains__(key)
     def has_key(self, key):
-        return self.dict.has_key(key)
+        return key in self.dict
 
 
 def check(key, value, env):
@@ -253,7 +255,7 @@ class VariablesTestCase(unittest.TestCase):
 
         env = Environment()
         opts.Update(env, {})
-        assert not env.has_key('ANSWER')
+        assert 'ANSWER' not in env
 
         # Test that a default value of None is all right.
         test = TestSCons.TestSCons()
@@ -267,7 +269,7 @@ class VariablesTestCase(unittest.TestCase):
 
         env = Environment()
         opts.Update(env, {})
-        assert not env.has_key('ANSWER')
+        assert 'ANSWER' not in env
 
     def test_args(self):
         """Test updating an Environment with arguments overridden"""
@@ -527,12 +529,12 @@ B 42 54 b - alpha test ['B']
         env = Environment()
         opts.Update(env, {'ANSWER' : 'answer'})
         
-        assert env.has_key('ANSWER')
+        assert 'ANSWER' in env
         
         env = Environment()
         opts.Update(env, {'ANSWERALIAS' : 'answer'})
         
-        assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS')
+        assert 'ANSWER' in env and 'ANSWERALIAS' not in env
         
         # test alias as a list
         opts = SCons.Variables.Variables()
@@ -545,12 +547,12 @@ B 42 54 b - alpha test ['B']
         env = Environment()
         opts.Update(env, {'ANSWER' : 'answer'})
         
-        assert env.has_key('ANSWER')
+        assert 'ANSWER' in env
         
         env = Environment()
         opts.Update(env, {'ANSWERALIAS' : 'answer'})
         
-        assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS')
+        assert 'ANSWER' in env and 'ANSWERALIAS' not in env
 
 
 
@@ -652,7 +654,7 @@ if __name__ == "__main__":
                  UnknownVariablesTestCase ]
     for tclass in tclasses:
         names = unittest.getTestCaseNames(tclass, 'test_')
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py
index b1a22886..27f694fe 100644
--- a/src/engine/SCons/Variables/__init__.py
+++ b/src/engine/SCons/Variables/__init__.py
@@ -26,11 +26,11 @@ customizable variables to an SCons build.
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 import sys
 
 import SCons.Environment
@@ -108,7 +108,7 @@ class Variables:
         """
         Returns the keywords for the options
         """
-        return map(lambda o: o.key, self.options)
+        return [o.key for o in self.options]
 
     def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
         """
@@ -124,7 +124,7 @@ class Variables:
         """
 
         if SCons.Util.is_List(key) or type(key) == type(()):
-            apply(self._do_add, key)
+            self._do_add(*key)
             return
 
         if not SCons.Util.is_String(key) or \
@@ -149,7 +149,7 @@ class Variables:
             )
         """
         for o in optlist:
-            apply(self._do_add, o)
+            self._do_add(*o)
 
 
     def Update(self, env, args=None):
@@ -203,7 +203,7 @@ class Variables:
 
         # Call the convert functions:
         for option in self.options:
-            if option.converter and values.has_key(option.key):
+            if option.converter and option.key in values:
                 value = env.subst('${%s}'%option.key)
                 try:
                     try:
@@ -216,7 +216,7 @@ class Variables:
 
         # Finally validate the values:
         for option in self.options:
-            if option.validator and values.has_key(option.key):
+            if option.validator and option.key in values:
                 option.validator(option.key, env.subst('${%s}'%option.key), env)
 
     def UnknownVariables(self):
@@ -285,26 +285,26 @@ class Variables:
 
         if sort:
             options = self.options[:]
-            options.sort(lambda x,y,func=sort: func(x.key,y.key))
+            options.sort(lambda x,y: sort(x.key,y.key))
         else:
             options = self.options
 
         def format(opt, self=self, env=env):
-            if env.has_key(opt.key):
+            if opt.key in env:
                 actual = env.subst('${%s}' % opt.key)
             else:
                 actual = None
             return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
-        lines = filter(None, map(format, options))
+        lines = [_f for _f in map(format, options) if _f]
 
-        return string.join(lines, '')
+        return ''.join(lines)
 
     format  = '\n%s: %s\n    default: %s\n    actual: %s\n'
     format_ = '\n%s: %s\n    default: %s\n    actual: %s\n    aliases: %s\n'
 
     def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]):
         # Don't display the key name itself as an alias.
-        aliases = filter(lambda a, k=key: a != k, aliases)
+        aliases = [a for a in aliases if a != key]
         if len(aliases)==0:
             return self.format % (key, help, default, actual)
         else:
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index 797ff41b..1fa63029 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -29,7 +29,6 @@ This file implements the warnings framework for SCons.
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import sys
 
 import SCons.Errors
@@ -194,11 +193,11 @@ def process_warn_strings(arguments):
         if s[:5] == "scons":
             return "SCons" + s[5:]
         else:
-            return string.capitalize(s)
+            return s.capitalize()
 
     for arg in arguments:
 
-        elems = string.split(string.lower(arg), '-')
+        elems = arg.lower().split('-')
         enable = 1
         if elems[0] == 'no':
             enable = 0
@@ -207,7 +206,7 @@ def process_warn_strings(arguments):
         if len(elems) == 1 and elems[0] == 'all':
             class_name = "Warning"
         else:
-            class_name = string.join(map(_capitalize, elems), '') + "Warning"
+            class_name = ''.join(map(_capitalize, elems)) + "Warning"
         try:
             clazz = globals()[class_name]
         except KeyError:
diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py
index 4d386179..d959518c 100644
--- a/src/engine/SCons/compat/__init__.py
+++ b/src/engine/SCons/compat/__init__.py
@@ -183,6 +183,15 @@ except ImportError:
     import_as('_scons_platform', 'platform')
 
 
+try:
+    import queue
+except ImportError:
+    # Before Python 3.0, the 'queue' module was named 'Queue'.
+    import imp
+    file, filename, suffix_mode_type = imp.find_module('Queue')
+    imp.load_module('queue', file, filename, suffix_mode_type)
+
+
 import shlex
 try:
     shlex.split
@@ -243,6 +252,24 @@ except ImportError:
     import_as('_scons_subprocess', 'subprocess')
 
 import sys
+try:
+    sys.intern
+except AttributeError:
+    # Pre-2.6 Python has no sys.intern() function.
+    import __builtin__
+    try:
+        sys.intern = __builtin__.intern
+    except AttributeError:
+        # Pre-2.x Python has no builtin intern() function.
+        def intern(x):
+           return x
+        sys.intern = intern
+        del intern
+try:
+    sys.maxsize
+except AttributeError:
+    # Pre-2.6 Python has no sys.maxsize attribute
+    sys.maxsize = sys.maxint
 try:
     sys.version_info
 except AttributeError:
diff --git a/src/engine/SCons/compat/_scons_optparse.py b/src/engine/SCons/compat/_scons_optparse.py
index 219adba3..5db4c90b 100644
--- a/src/engine/SCons/compat/_scons_optparse.py
+++ b/src/engine/SCons/compat/_scons_optparse.py
@@ -799,7 +799,7 @@ class Option:
             if self.nargs == 1:
                 return self.check_value(opt, value)
             else:
-                return tuple(map(lambda v, o=opt, s=self: s.check_value(o, v), value))
+                return tuple(map(lambda v: self.check_value(opt, v), value))
 
     def process(self, opt, value, values, parser):
 
@@ -1700,7 +1700,7 @@ def _match_abbrev(s, wordmap):
         return s
     else:
         # Isolate all words with s as a prefix.
-        possibilities = filter(lambda w, s=s: w[:len(s)] == s, wordmap.keys())
+        possibilities = filter(lambda w: w[:len(s)] == s, wordmap.keys())
         # No exact match, so there had better be just one possibility.
         if len(possibilities) == 1:
             return possibilities[0]
diff --git a/src/engine/SCons/compat/builtins.py b/src/engine/SCons/compat/builtins.py
index 19329f64..d52ea4de 100644
--- a/src/engine/SCons/compat/builtins.py
+++ b/src/engine/SCons/compat/builtins.py
@@ -158,7 +158,7 @@ except NameError:
         """
         result = []
         for i in xrange(min(map(len, lists))):
-            result.append(tuple(map(lambda l, i=i: l[i], lists)))
+            result.append(tuple(map(lambda l: l[i], lists)))
         return result
     __builtin__.zip = zip
 
diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py
index 47d664c1..4a826ba7 100644
--- a/src/engine/SCons/cpp.py
+++ b/src/engine/SCons/cpp.py
@@ -34,7 +34,6 @@ import SCons
 
 import os
 import re
-import string
 
 #
 # First "subsystem" of regular expressions that we set up:
@@ -91,7 +90,7 @@ del op_list
 override = {
     'if'                        : 'if(?!def)',
 }
-l = map(lambda x, o=override: o.get(x, x), Table.keys())
+l = [override.get(x, x) for x in Table.keys()]
 
 
 # Turn the list of expressions into one big honkin' regular expression
@@ -99,7 +98,7 @@ l = map(lambda x, o=override: o.get(x, x), Table.keys())
 # a list of tuples, one for each preprocessor line.  The preprocessor
 # directive will be the first element in each tuple, and the rest of
 # the line will be the second element.
-e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$'
+e = '^\s*#\s*(' + '|'.join(l) + ')(.*)$'
 
 # And last but not least, compile the expression.
 CPP_Expression = re.compile(e, re.M)
@@ -126,7 +125,7 @@ CPP_to_Python_Ops_Dict = {
     '\r'        : '',
 }
 
-CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)]
+CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)]
 
 # We have to sort the keys by length so that longer expressions
 # come *before* shorter expressions--in particular, "!=" must
@@ -139,7 +138,7 @@ l.sort(lambda a, b: cmp(len(b), len(a)))
 
 # Turn the list of keys into one regular expression that will allow us
 # to substitute all of the operators at once.
-expr = string.join(map(re.escape, l), '|')
+expr = '|'.join(map(re.escape, l))
 
 # ...and compile the expression.
 CPP_to_Python_Ops_Expression = re.compile(expr)
@@ -147,8 +146,8 @@ CPP_to_Python_Ops_Expression = re.compile(expr)
 # A separate list of expressions to be evaluated and substituted
 # sequentially, not all at once.
 CPP_to_Python_Eval_List = [
-    ['defined\s+(\w+)',         '__dict__.has_key("\\1")'],
-    ['defined\s*\((\w+)\)',     '__dict__.has_key("\\1")'],
+    ['defined\s+(\w+)',         '"\\1" in __dict__'],
+    ['defined\s*\((\w+)\)',     '"\\1" in __dict__'],
     ['/\*.*\*/',                ''],
     ['/\*.*',                   ''],
     ['//.*',                    ''],
@@ -192,7 +191,7 @@ class FunctionEvaluator:
         self.name = name
         self.args = function_arg_separator.split(args)
         try:
-            expansion = string.split(expansion, '##')
+            expansion = expansion.split('##')
         except (AttributeError, TypeError):
             # Python 1.5 throws TypeError if "expansion" isn't a string,
             # later versions throw AttributeError.
@@ -218,7 +217,7 @@ class FunctionEvaluator:
             if not s in self.args:
                 s = repr(s)
             parts.append(s)
-        statement = string.join(parts, ' + ')
+        statement = ' + '.join(parts)
 
         return eval(statement, globals(), locals)
 
@@ -292,9 +291,7 @@ class PreProcessor:
         global CPP_Expression, Table
         contents = line_continuations.sub('', contents)
         cpp_tuples = CPP_Expression.findall(contents)
-        return  map(lambda m, t=Table:
-                           (m[0],) + t[m[0]].match(m[1]).groups(),
-                    cpp_tuples)
+        return  [(m[0],) + Table[m[0]].match(m[1]).groups() for m in cpp_tuples]
 
     def __call__(self, file):
         """
@@ -363,7 +360,7 @@ class PreProcessor:
         eval()ing it in the C preprocessor namespace we use to
         track #define values.
         """
-        t = CPP_to_Python(string.join(t[1:]))
+        t = CPP_to_Python(' '.join(t[1:]))
         try: return eval(t, self.cpp_namespace)
         except (NameError, TypeError): return 0
 
@@ -446,13 +443,13 @@ class PreProcessor:
         """
         Default handling of a #ifdef line.
         """
-        self._do_if_else_condition(self.cpp_namespace.has_key(t[1]))
+        self._do_if_else_condition(t[1] in self.cpp_namespace)
 
     def do_ifndef(self, t):
         """
         Default handling of a #ifndef line.
         """
-        self._do_if_else_condition(not self.cpp_namespace.has_key(t[1]))
+        self._do_if_else_condition(t[1] not in self.cpp_namespace)
 
     def do_if(self, t):
         """
@@ -563,7 +560,7 @@ class PreProcessor:
                 s = self.cpp_namespace[m.group(1)]
                 if callable(s):
                     args = function_arg_separator.split(m.group(2))
-                    s = apply(s, args)
+                    s = s(*args)
             if not s:
                 return None
         return (t[0], s[0], s[1:-1])
@@ -584,7 +581,7 @@ class DumbPreProcessor(PreProcessor):
     to tailor its behavior.
     """
     def __init__(self, *args, **kw):
-        apply(PreProcessor.__init__, (self,)+args, kw)
+        PreProcessor.__init__(self, *args, **kw)
         d = self.default_table
         for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']:
             d[func] = d[func] = self.do_nothing
diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py
index 252a0642..bfb0b461 100644
--- a/src/engine/SCons/cppTests.py
+++ b/src/engine/SCons/cppTests.py
@@ -23,7 +23,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import sys
 import unittest
 
@@ -635,7 +634,7 @@ class fileTestCase(unittest.TestCase):
 
     def strip_initial_spaces(self, s):
         #lines = s.split('\n')
-        lines = string.split(s, '\n')
+        lines = s.split('\n')
         spaces = re.match(' *', lines[0]).group(0)
         def strip_spaces(l, spaces=spaces):
             #if l.startswith(spaces):
@@ -643,7 +642,7 @@ class fileTestCase(unittest.TestCase):
                 l = l[len(spaces):]
             return l
         #return '\n'.join([ strip_spaces(l) for l in lines ])
-        return string.join(map(strip_spaces, lines), '\n')
+        return '\n'.join(map(strip_spaces, lines))
 
     def write(self, file, contents):
         open(file, 'w').write(self.strip_initial_spaces(contents))
@@ -675,7 +674,7 @@ class fileTestCase(unittest.TestCase):
         """)
         class MyPreProcessor(cpp.DumbPreProcessor):
             def __init__(self, *args, **kw):
-                apply(cpp.DumbPreProcessor.__init__, (self,) + args, kw)
+                cpp.DumbPreProcessor.__init__(self, *args, **kw)
                 self.files = []
             def __call__(self, file):
                 self.files.append(file)
@@ -704,7 +703,7 @@ if __name__ == '__main__':
         except NameError:
             pass
         names.sort()
-        suite.addTests(map(tclass, names))
+        suite.addTests(list(map(tclass, names)))
     if not unittest.TextTestRunner().run(suite).wasSuccessful():
         sys.exit(1)
 
diff --git a/src/engine/SCons/exitfuncs.py b/src/engine/SCons/exitfuncs.py
index d911b526..250dd547 100644
--- a/src/engine/SCons/exitfuncs.py
+++ b/src/engine/SCons/exitfuncs.py
@@ -41,7 +41,7 @@ def _run_exitfuncs():
 
     while _exithandlers:
         func, targs, kargs =  _exithandlers.pop()
-        apply(func, targs, kargs)
+        func(*targs, **kargs)
 
 def register(func, *targs, **kargs):
     """register a function to be executed upon normal program termination
diff --git a/src/script/scons-time.py b/src/script/scons-time.py
index eeddd873..c75bc133 100644
--- a/src/script/scons-time.py
+++ b/src/script/scons-time.py
@@ -30,8 +30,8 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
-
 from __future__ import nested_scopes
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -41,7 +41,6 @@ import os
 import os.path
 import re
 import shutil
-import string
 import sys
 import tempfile
 import time
@@ -177,13 +176,13 @@ class Gnuplotter(Plotter):
         result = []
         for line in self.lines:
             result.extend(line.get_x_values())
-        return filter(lambda r: not r is None, result)
+        return [r for r in result if not r is None]
 
     def get_all_y_values(self):
         result = []
         for line in self.lines:
             result.extend(line.get_y_values())
-        return filter(lambda r: not r is None, result)
+        return [r for r in result if not r is None]
 
     def get_min_x(self):
         try:
@@ -539,7 +538,7 @@ class SConsTimer:
 
         for file in files:
             base = os.path.splitext(file)[0]
-            run, index = string.split(base, '-')[-2:]
+            run, index = base.split('-')[-2:]
 
             run = int(run)
             index = int(index)
@@ -577,11 +576,11 @@ class SConsTimer:
         and returns the next run number after the largest it finds.
         """
         x = re.compile(re.escape(prefix) + '-([0-9]+).*')
-        matches = map(lambda e, x=x: x.match(e), os.listdir(dir))
-        matches = filter(None, matches)
+        matches = [x.match(e) for e in os.listdir(dir)]
+        matches = [_f for _f in matches if _f]
         if not matches:
             return 0
-        run_numbers = map(lambda m: int(m.group(1)), matches)
+        run_numbers = [int(m.group(1)) for m in matches]
         return int(max(run_numbers)) + 1
 
     def gnuplot_results(self, results, fmt='%s %.3f'):
@@ -964,7 +963,7 @@ class SConsTimer:
 
         if self.chdir:
             os.chdir(self.chdir)
-            logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+            logfile_path = lambda x: os.path.join(self.chdir, x)
 
         if not args:
 
@@ -1084,7 +1083,7 @@ class SConsTimer:
 
         if self.chdir:
             os.chdir(self.chdir)
-            logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+            logfile_path = lambda x: os.path.join(self.chdir, x)
 
         if not args:
 
@@ -1462,7 +1461,7 @@ class SConsTimer:
 
         if self.chdir:
             os.chdir(self.chdir)
-            logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+            logfile_path = lambda x: os.path.join(self.chdir, x)
 
         if not args:
 
diff --git a/src/script/scons.py b/src/script/scons.py
index dec42229..010302fa 100644
--- a/src/script/scons.py
+++ b/src/script/scons.py
@@ -76,7 +76,7 @@ if script_dir in sys.path:
 
 libs = []
 
-if os.environ.has_key("SCONS_LIB_DIR"):
+if "SCONS_LIB_DIR" in os.environ:
     libs.append(os.environ["SCONS_LIB_DIR"])
 
 local_version = 'scons-local-' + __version__
@@ -137,12 +137,11 @@ else:
         # check only /foo/lib/scons*.
         prefs.append(sys.prefix)
 
-    temp = map(lambda x: os.path.join(x, 'lib'), prefs)
-    temp.extend(map(lambda x: os.path.join(x,
+    temp = [os.path.join(x, 'lib') for x in prefs]
+    temp.extend([os.path.join(x,
                                            'lib',
                                            'python' + sys.version[:3],
-                                           'site-packages'),
-                           prefs))
+                                           'site-packages') for x in prefs])
     prefs = temp
 
     # Add the parent directory of the current python's library to the
@@ -175,8 +174,8 @@ else:
 
 # Look first for 'scons-__version__' in all of our preference libs,
 # then for 'scons'.
-libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
-libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
+libs.extend([os.path.join(x, scons_version) for x in prefs])
+libs.extend([os.path.join(x, 'scons') for x in prefs])
 
 sys.path = libs + sys.path
 
diff --git a/src/script/sconsign.py b/src/script/sconsign.py
index 40c5daff..fb3bd5e1 100644
--- a/src/script/sconsign.py
+++ b/src/script/sconsign.py
@@ -23,6 +23,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -64,7 +65,7 @@ if script_dir in sys.path:
 
 libs = []
 
-if os.environ.has_key("SCONS_LIB_DIR"):
+if "SCONS_LIB_DIR" in os.environ:
     libs.append(os.environ["SCONS_LIB_DIR"])
 
 local_version = 'scons-local-' + __version__
@@ -125,12 +126,11 @@ else:
         # check only /foo/lib/scons*.
         prefs.append(sys.prefix)
 
-    temp = map(lambda x: os.path.join(x, 'lib'), prefs)
-    temp.extend(map(lambda x: os.path.join(x,
+    temp = [os.path.join(x, 'lib') for x in prefs]
+    temp.extend([os.path.join(x,
                                            'lib',
                                            'python' + sys.version[:3],
-                                           'site-packages'),
-                           prefs))
+                                           'site-packages') for x in prefs])
     prefs = temp
 
     # Add the parent directory of the current python's library to the
@@ -163,8 +163,8 @@ else:
 
 # Look first for 'scons-__version__' in all of our preference libs,
 # then for 'scons'.
-libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
-libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
+libs.extend([os.path.join(x, scons_version) for x in prefs])
+libs.extend([os.path.join(x, 'scons') for x in prefs])
 
 sys.path = libs + sys.path
 
@@ -174,7 +174,6 @@ sys.path = libs + sys.path
 
 import cPickle
 import imp
-import string
 import whichdb
 
 import SCons.SConsign
@@ -195,7 +194,7 @@ whichdb.whichdb = my_whichdb
 
 def my_import(mname):
     if '.' in mname:
-        i = string.rfind(mname, '.')
+        i = mname.rfind('.')
         parent = my_import(mname[:i])
         fp, pathname, description = imp.find_module(mname[i+1:],
                                                     parent.__path__)
@@ -254,7 +253,7 @@ def map_bkids(entry, name):
         result.append(nodeinfo_string(bkids[i], bkidsigs[i], "        "))
     if result == []:
         return None
-    return string.join(result, "\n        ")
+    return "\n        ".join(result)
 
 map_field = {
     'action'    : map_action,
@@ -290,22 +289,21 @@ def nodeinfo_raw(name, ninfo, prefix=""):
         l.append('%s: %s' % (repr(k), repr(d.get(k))))
     if '\n' in name:
         name = repr(name)
-    return name + ': {' + string.join(l, ', ') + '}'
+    return name + ': {' + ', '.join(l) + '}'
 
 def nodeinfo_cooked(name, ninfo, prefix=""):
     try:
         field_list = ninfo.field_list
     except AttributeError:
         field_list = []
-    f = lambda x, ni=ninfo, v=Verbose: field(x, ni, v)
     if '\n' in name:
         name = repr(name)
-    outlist = [name+':'] + filter(None, map(f, field_list))
+    outlist = [name+':'] + [_f for _f in [field(x, ninfo, Verbose) for x in field_list] if _f]
     if Verbose:
         sep = '\n    ' + prefix
     else:
         sep = ' '
-    return string.join(outlist, sep)
+    return sep.join(outlist)
 
 nodeinfo_string = nodeinfo_cooked
 
diff --git a/src/setup.py b/src/setup.py
index 93787704..0dbb0128 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -20,13 +20,13 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import os.path
 import stat
-import string
 import sys
 
 Version = "__VERSION__"
@@ -198,7 +198,7 @@ def get_scons_prefix(libdir, is_win32):
         if head == os.sep:
             break
         head, tail = os.path.split(head)
-        if string.lower(tail)[:6] == "python":
+        if tail.lower()[:6] == "python":
             # Found the Python library directory...
             if is_win32:
                 # ...on Win32 systems, "scons" goes in the directory:
@@ -297,8 +297,8 @@ class install_scripts(_install_scripts):
             create_version_script = self.do_nothing
 
         inputs = self.get_inputs()
-        bat_scripts = filter(lambda x: x[-4:] == '.bat', inputs)
-        non_bat_scripts = filter(lambda x: x[-4:] != '.bat', inputs)
+        bat_scripts = [x for x in inputs if x[-4:] == '.bat']
+        non_bat_scripts = [x for x in inputs if x[-4:] != '.bat']
 
         self.outfiles = []
         self.mkpath(self.install_dir)
@@ -415,10 +415,10 @@ arguments = {
                           'build_scripts'   : build_scripts}
 }
 
-apply(distutils.core.setup, (), arguments)
+distutils.core.setup(**arguments)
 
 if Installed:
-    print string.join(Installed, '\n')
+    print '\n'.join(Installed)
 
 # Local Variables:
 # tab-width:4
diff --git a/src/test_aegistests.py b/src/test_aegistests.py
index af290831..744f1418 100644
--- a/src/test_aegistests.py
+++ b/src/test_aegistests.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -35,7 +36,6 @@ name of this script doesn't end in *Tests.py.
 import os
 import popen2
 import re
-import string
 import sys
 
 import TestSCons
@@ -57,8 +57,8 @@ else:
 
 output = get_stdout('aegis -list -unformatted pf') +\
          get_stdout('aegis -list -unformatted cf')
-lines = string.split(output, '\n')[:-1]
-sources = filter(lambda x: x[:7] == 'source ', lines)
+lines = output.split('\n')[:-1]
+sources = [x for x in lines if x[:7] == 'source ']
 
 re1 = re.compile(r' src/.*Tests\.py')
 re2 = re.compile(r' src/test_.*\.py')
@@ -67,11 +67,11 @@ re3 = re.compile(r' test/.*\.py')
 def filename_is_a_test(x):
     return re1.search(x) or re2.search(x) or re3.search(x)
 
-test_files = filter(filename_is_a_test, sources)
+test_files = list(filter(filename_is_a_test, sources))
 
 if test_files:
     sys.stderr.write("Found the following files with test names not marked as Aegis tests:\n")
-    sys.stderr.write('\t' + string.join(test_files, '\n\t') + '\n')
+    sys.stderr.write('\t' + '\n\t'.join(test_files) + '\n')
     test.fail_test(1)
 
 test.pass_test()
diff --git a/src/test_files.py b/src/test_files.py
index b4138533..7d8e75e2 100644
--- a/src/test_files.py
+++ b/src/test_files.py
@@ -35,7 +35,6 @@ name of this script doesn't end in *Tests.py.
 import os
 import os.path
 import re
-import string
 
 import TestSCons
 
@@ -47,7 +46,7 @@ except KeyError:
     cwd = os.getcwd()
 
 def build_path(*args):
-    return apply(os.path.join, (cwd, 'build',) + args)
+    return os.path.join(cwd, 'build', *args)
 
 build_scons_tar_gz  = build_path('unpack-tar-gz', 'scons-'+test.scons_version)
 build_scons_zip     = build_path('unpack-zip', 'scons-'+test.scons_version)
@@ -89,12 +88,12 @@ for directory, check_list in check.items():
 
 if missing:
     print "Missing the following files:\n"
-    print "\t" + string.join(missing, "\n\t")
+    print "\t" + "\n\t".join(missing)
     test.fail_test(1)
 
 if no_result:
     print "Cannot check files, the following have apparently not been built:"
-    print "\t" + string.join(no_result, "\n\t")
+    print "\t" + "\n\t".join(no_result)
     test.no_result(1)
 
 test.pass_test()
diff --git a/src/test_interrupts.py b/src/test_interrupts.py
index 0c7c4df3..69e7a80f 100644
--- a/src/test_interrupts.py
+++ b/src/test_interrupts.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -32,7 +33,6 @@ keyboard interrupts (e.g. Ctrl-C).
 import os
 import os.path
 import re
-import string
 import time
 
 import TestSCons
@@ -76,8 +76,8 @@ try:
 except IOError:
     test.skip_test('%s does not exist; skipping test.\n' % MANIFEST)
 else:
-    files = string.split(fp.read())
-    files = filter(lambda f: f[-3:] == '.py', files)
+    files = fp.read().split()
+    files = [f for f in files if f[-3:] == '.py']
 
 # some regexps to parse the python files
 tryexc_pat = re.compile(
@@ -100,7 +100,7 @@ for f in files:
             indent_list = try_except_lines[match.group('indent')]
         except:
             indent_list = []
-        line_num = 1 + string.count(contents[:match.start()], '\n')
+        line_num = 1 + contents[:match.start()].count('\n')
         indent_list.append( (line_num, match.group('try_or_except') ) )
         try_except_lines[match.group('indent')] = indent_list
     uncaught_this_file = []
@@ -111,7 +111,7 @@ for f in files:
             #print "%4d %s" % (l,statement),
             m1 = keyboardint_pat.match(statement)
             m2 = exceptall_pat.match(statement)
-            if string.find(statement, indent + 'try') == 0:
+            if statement.find(indent + 'try') == 0:
                 if exc_all_seen and not exc_keyboardint_seen:
                     uncaught_this_file.append(line)
                 exc_keyboardint_seen = 0
diff --git a/src/test_pychecker.py b/src/test_pychecker.py
index 20aae697..fb60646a 100644
--- a/src/test_pychecker.py
+++ b/src/test_pychecker.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -30,7 +31,6 @@ Use pychecker to catch various Python coding errors.
 
 import os
 import os.path
-import string
 import sys
 
 import TestSCons
@@ -64,9 +64,9 @@ else:
 src_engine_ = os.path.join(src_engine, '')
 
 MANIFEST = os.path.join(src_engine, 'MANIFEST.in')
-files = string.split(open(MANIFEST).read())
+files = open(MANIFEST).read().split()
 
-files = filter(lambda f: f[-3:] == '.py', files)
+files = [f for f in files if f[-3:] == '.py']
 
 ignore = [
     'SCons/compat/__init__.py',
@@ -131,15 +131,15 @@ for file in files:
     test.run(program=program, arguments=args, status=None, stderr=None)
 
     stdout = test.stdout()
-    stdout = string.replace(stdout, src_engine_, '')
+    stdout = stdout.replace(src_engine_, '')
 
     stderr = test.stderr()
-    stderr = string.replace(stderr, src_engine_, '')
-    stderr = string.replace(stderr, pywintypes_warning, '')
+    stderr = stderr.replace(src_engine_, '')
+    stderr = stderr.replace(pywintypes_warning, '')
 
     if test.status or stdout or stderr:
         mismatches.append('\n')
-        mismatches.append(string.join([program] + args) + '\n')
+        mismatches.append(' '.join([program] + args) + '\n')
 
         mismatches.append('STDOUT =====================================\n')
         mismatches.append(stdout)
@@ -149,7 +149,7 @@ for file in files:
             mismatches.append(stderr)
 
 if mismatches:
-    print string.join(mismatches[1:], '')
+    print ''.join(mismatches[1:])
     test.fail_test()
 
 test.pass_test()
diff --git a/src/test_setup.py b/src/test_setup.py
index 7454b569..29d36bf3 100644
--- a/src/test_setup.py
+++ b/src/test_setup.py
@@ -34,7 +34,6 @@ name of this script doesn't end in *Tests.py.
 import os
 import os.path
 import shutil
-import string
 import sys
 
 try: WindowsError
@@ -109,51 +108,50 @@ class MyTestSCons(TestSCons.TestSCons):
             self.version_lib = os.path.join(self.lib_dir, scons_version)
             self.man_dir = os.path.join(self.prefix, 'man', 'man1')
 
-        self.prepend_bin_dir = lambda p, d=self.bin_dir: os.path.join(d, p)
-        self.prepend_bat_dir = lambda p, d=self.bat_dir: os.path.join(d, p)
-        self.prepend_man_dir = lambda p, d=self.man_dir: os.path.join(d, p)
+        self.prepend_bin_dir = lambda p: os.path.join(self.bin_dir, p)
+        self.prepend_bat_dir = lambda p: os.path.join(self.bat_dir, p)
+        self.prepend_man_dir = lambda p: os.path.join(self.man_dir, p)
 
     def run(self, *args, **kw):
         kw['chdir'] = scons_version
         kw['program'] = python
         kw['stderr'] = None
-        return apply(TestSCons.TestSCons.run, (self,)+args, kw)
+        return TestSCons.TestSCons.run(self, *args, **kw)
 
     def remove(self, dir):
         try: shutil.rmtree(dir)
         except (OSError, WindowsError): pass
 
     def stdout_lines(self):
-        return string.split(self.stdout(), '\n')
+        return self.stdout().split('\n')
 
 
     def lib_line(self, lib):
         return 'Installed SCons library modules into %s' % lib
 
     def lib_paths(self, lib_dir):
-        prepend_lib_dir = lambda p, d=lib_dir: os.path.join(d, 'SCons', p)
-        return map(prepend_lib_dir, self._lib_modules)
+        return [os.path.join(lib_dir, 'SCons', p) for p in self._lib_modules]
 
     def scripts_line(self):
         return 'Installed SCons scripts into %s' % self.bin_dir
 
     def base_script_paths(self):
         scripts = self._base_scripts
-        return map(self.prepend_bin_dir, scripts)
+        return list(map(self.prepend_bin_dir, scripts))
 
     def version_script_paths(self):
         scripts = self._version_scripts
-        return map(self.prepend_bin_dir, scripts)
+        return list(map(self.prepend_bin_dir, scripts))
 
     def bat_script_paths(self):
         scripts = self._bat_scripts + self._bat_version_scripts
-        return map(self.prepend_bat_dir, scripts)
+        return list(map(self.prepend_bat_dir, scripts))
 
     def man_page_line(self):
         return 'Installed SCons man pages into %s' % self.man_dir
 
     def man_page_paths(self):
-        return map(self.prepend_man_dir, self._man_pages)
+        return list(map(self.prepend_man_dir, self._man_pages))
 
 
     def must_have_installed(self, paths):
@@ -321,8 +319,7 @@ test.must_have_installed(test.man_page_paths())
 other_prefix = test.workpath('other-prefix')
 test.subdir(other_prefix)
 test.run(arguments = 'setup.py install --prefix=%s' % other_prefix)
-test.fail_test(string.find(test.stderr(),
-                           "you'll have to change the search path yourself")
+test.fail_test(test.stderr().find("you'll have to change the search path yourself")
                != -1)
 
 # All done.
diff --git a/src/test_strings.py b/src/test_strings.py
index 4ca2245e..eed42343 100644
--- a/src/test_strings.py
+++ b/src/test_strings.py
@@ -36,7 +36,6 @@ import fnmatch
 import os
 import os.path
 import re
-import string
 
 import TestCmd
 import TestSCons
@@ -47,7 +46,7 @@ test = TestCmd.TestCmd()
 scons_version = TestSCons.SConsVersion
 
 def build_path(*args):
-    return apply(os.path.join, ('build',)+args)
+    return os.path.join('build', *args)
 
 build_scons     = build_path('scons')
 build_local     = build_path('scons-local', 'scons-local-'+scons_version)
@@ -87,8 +86,7 @@ class Checker:
             return os.path.isfile(path)
 
     def visit(self, result, dirname, names):
-        make_path_tuple = lambda n, d=dirname: (n, os.path.join(d, n))
-        for name, path in map(make_path_tuple, names):
+        for name, path in [(n, os.path.join(dirname, n)) for n in names]:
             if self.remove_this(name, path):
                 names.remove(name)
             elif self.search_this(path):
@@ -263,12 +261,12 @@ for collector in check_list:
 
 if missing_strings:
     print "Found the following files with missing strings:"
-    print "\t" + string.join(missing_strings, "\n\t")
+    print "\t" + "\n\t".join(missing_strings)
     test.fail_test(1)
 
 if not_built:
     print "Cannot check all strings, the following have apparently not been built:"
-    print "\t" + string.join(not_built, "\n\t")
+    print "\t" + "\n\t".join(not_built)
     test.no_result(1)
 
 test.pass_test()
diff --git a/test/AR/AR.py b/test/AR/AR.py
index 41105da9..8fb80737 100644
--- a/test/AR/AR.py
+++ b/test/AR/AR.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -36,11 +35,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
diff --git a/test/AR/ARCOM.py b/test/AR/ARCOM.py
index 65cae2e3..f26ced68 100644
--- a/test/AR/ARCOM.py
+++ b/test/AR/ARCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ar*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ar*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AR/ARCOMSTR.py b/test/AR/ARCOMSTR.py
index c4a8c779..4c0bb854 100644
--- a/test/AR/ARCOMSTR.py
+++ b/test/AR/ARCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ar*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ar*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AR/ARFLAGS.py b/test/AR/ARFLAGS.py
index 87346599..be4e8bd4 100644
--- a/test/AR/ARFLAGS.py
+++ b/test/AR/ARFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -36,11 +35,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
diff --git a/test/AS/AS.py b/test/AS/AS.py
index 0857a629..38ea6552 100644
--- a/test/AS/AS.py
+++ b/test/AS/AS.py
@@ -43,7 +43,6 @@ test = TestSCons.TestSCons()
 if sys.platform == 'win32':
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -51,7 +50,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
diff --git a/test/AS/ASCOM.py b/test/AS/ASCOM.py
index 1be592c3..a874f32b 100644
--- a/test/AS/ASCOM.py
+++ b/test/AS/ASCOM.py
@@ -42,7 +42,7 @@ test.write('myas.py', r"""
 import sys
 infile = open(sys.argv[2], 'rb')
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != "#as\n", infile.readlines()):
+for l in [l for l in infile.readlines() if l != "#as\n"]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AS/ASCOMSTR.py b/test/AS/ASCOMSTR.py
index eaa344a4..f7cc34e3 100644
--- a/test/AS/ASCOMSTR.py
+++ b/test/AS/ASCOMSTR.py
@@ -43,7 +43,7 @@ test.write('myas.py', r"""
 import sys
 infile = open(sys.argv[2], 'rb')
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != "#as\n", infile.readlines()):
+for l in [l for l in infile.readlines() if l != "#as\n"]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AS/ASFLAGS.py b/test/AS/ASFLAGS.py
index 5581b07c..4f89c2ce 100644
--- a/test/AS/ASFLAGS.py
+++ b/test/AS/ASFLAGS.py
@@ -41,7 +41,6 @@ if sys.platform == 'win32':
     o_c = ' -x'
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -49,7 +48,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
diff --git a/test/AS/ASPP.py b/test/AS/ASPP.py
index d8fb3be5..f8bea474 100644
--- a/test/AS/ASPP.py
+++ b/test/AS/ASPP.py
@@ -38,7 +38,6 @@ test = TestSCons.TestSCons()
 if sys.platform == 'win32':
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -46,7 +45,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
diff --git a/test/AS/ASPPCOM.py b/test/AS/ASPPCOM.py
index 53f4addf..73b3ec34 100644
--- a/test/AS/ASPPCOM.py
+++ b/test/AS/ASPPCOM.py
@@ -40,7 +40,7 @@ test.write('myas.py', r"""
 import sys
 infile = open(sys.argv[2], 'rb')
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != "#as\n", infile.readlines()):
+for l in [l for l in infile.readlines() if l != "#as\n"]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AS/ASPPCOMSTR.py b/test/AS/ASPPCOMSTR.py
index 20e3de00..7de3b125 100644
--- a/test/AS/ASPPCOMSTR.py
+++ b/test/AS/ASPPCOMSTR.py
@@ -29,8 +29,6 @@ Test that the $ASPPCOMSTR construction variable allows you to customize
 the displayed assembler string.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -43,7 +41,7 @@ test.write('myas.py', r"""
 import sys
 infile = open(sys.argv[2], 'rb')
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != "#as\n", infile.readlines()):
+for l in [l for l in infile.readlines() if l != "#as\n"]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/AS/ASPPFLAGS.py b/test/AS/ASPPFLAGS.py
index e306c227..f27d0ad1 100644
--- a/test/AS/ASPPFLAGS.py
+++ b/test/AS/ASPPFLAGS.py
@@ -41,7 +41,6 @@ if sys.platform == 'win32':
     o_c = ' -x'
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -49,7 +48,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
diff --git a/test/AS/as-live.py b/test/AS/as-live.py
index 0ee7c169..0f7ec380 100644
--- a/test/AS/as-live.py
+++ b/test/AS/as-live.py
@@ -28,7 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Verify correct use of the live 'as' assembler.
 """
 
-import string
 import sys
 
 import TestSCons
@@ -43,7 +42,7 @@ test = TestSCons.TestSCons()
 if not test.detect('AS', 'as'):
     test.skip_test("as not found; skipping test\n")
 
-x86 = (sys.platform == 'win32' or string.find(sys.platform, 'linux') != -1)
+x86 = (sys.platform == 'win32' or sys.platform.find('linux') != -1)
 
 if not x86:
     test.skip_test("skipping as test on non-x86 platform '%s'\n" % sys.platform)
@@ -52,12 +51,11 @@ if not x86:
 
 test.write("wrapper.py", """\
 import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py: %%s\\n" %% sys.argv[-1])
-cmd = string.join(sys.argv[1:])
+cmd = " ".join(sys.argv[1:])
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """\
 aaa = Environment()
diff --git a/test/AS/ml.py b/test/AS/ml.py
index a731efb2..9491e36c 100644
--- a/test/AS/ml.py
+++ b/test/AS/ml.py
@@ -28,7 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Verify correct use of the live 'ml' assembler.
 """
 
-import string
 import sys
 
 import TestSCons
@@ -48,11 +47,10 @@ if not ml:
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 import os
diff --git a/test/AS/nasm.py b/test/AS/nasm.py
index b6d61a31..be7db3ef 100644
--- a/test/AS/nasm.py
+++ b/test/AS/nasm.py
@@ -29,7 +29,6 @@ Verify correct use of the live 'nasm' assembler.
 """
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -44,7 +43,7 @@ nasm = test.where_is('nasm')
 if not nasm:
     test.skip_test('nasm not found; skipping test\n')
 
-if string.find(sys.platform, 'linux') == -1:
+if sys.platform.find('linux') == -1:
     test.skip_test("skipping test on non-Linux platform '%s'\n" % sys.platform)
 
 try:
@@ -53,7 +52,7 @@ try:
 except OSError:
     test.skip_test('could not determine nasm version; skipping test\n')
 else:
-    version = string.split(stdout.read())[2]
+    version = stdout.read().split()[2]
     if version[:4] != '0.98':
         test.skip_test("skipping test of nasm version %s\n" % version)
 
@@ -71,17 +70,16 @@ else:
 nasm_format = 'elf'
 format_map = {}
 for k, v in format_map.items():
-    if string.find(sys.platform, k) != -1:
+    if sys.platform.find(k) != -1:
         nasm_format = v
         break
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 eee = Environment(tools = ['gcc', 'gnulink', 'nasm'],
diff --git a/test/Actions/actions.py b/test/Actions/actions.py
index aae2bb91..1837ee70 100644
--- a/test/Actions/actions.py
+++ b/test/Actions/actions.py
@@ -67,10 +67,9 @@ test.up_to_date(arguments = '.')
 
 test.write('SConstruct', """
 import os
-import string
 def func(env, target, source):
-    cmd = r'%(_python_)s build.py %%s 3 %%s' %% (string.join(map(str, target)),
-                                       string.join(map(str, source)))
+    cmd = r'%(_python_)s build.py %%s 3 %%s' %% (' '.join(map(str, target)),
+                                       ' '.join(map(str, source)))
     print cmd
     return os.system(cmd)
 B = Builder(action = func)
@@ -86,8 +85,7 @@ test.up_to_date(arguments = '.')
 
 test.write('SConstruct', """
 import os
-assert not globals().has_key('string')
-import string
+assert 'string' not in globals()
 class bld:
     def __init__(self):
         self.cmd = r'%(_python_)s build.py %%s 4 %%s'
@@ -96,8 +94,8 @@ class bld:
         print cmd
         return os.system(cmd)
     def get_contents(self, env, target, source):
-        return self.cmd %% (string.join(map(str, target)),
-                            string.join(map(str, source)))
+        return self.cmd %% (' '.join(map(str, target)),
+                            ' '.join(map(str, source)))
 B = Builder(action = bld())
 env = Environment(BUILDERS = { 'B' : B })
 env.B(target = 'foo.out', source = 'foo.in')
diff --git a/test/Actions/addpost-link.py b/test/Actions/addpost-link.py
index 9c796628..a1480510 100644
--- a/test/Actions/addpost-link.py
+++ b/test/Actions/addpost-link.py
@@ -39,9 +39,8 @@ _python_ = TestSCons._python_
 test = TestSCons.TestSCons()
 
 test.write('strip.py', """\
-import string
 import sys
-print "strip.py: %s" % string.join(sys.argv[1:])
+print "strip.py: %s" % " ".join(sys.argv[1:])
 """)
 
 test.write('SConstruct', """\
diff --git a/test/Actions/function.py b/test/Actions/function.py
index 6d18e5c3..20391979 100644
--- a/test/Actions/function.py
+++ b/test/Actions/function.py
@@ -136,7 +136,7 @@ genHeaderBld = SCons.Builder.Builder(
 env = Environment()
 env.Append(BUILDERS = {'GenHeader' : genHeaderBld})
 
-envdeps = map(str, range(int(optEnv['NbDeps'])))
+envdeps = list(map(str, range(int(optEnv['NbDeps']))))
 
 env.GenHeader('Out', None, ENVDEPS=envdeps)
 """)
diff --git a/test/AddOption/help.py b/test/AddOption/help.py
index 7b5c01dd..26b97750 100644
--- a/test/AddOption/help.py
+++ b/test/AddOption/help.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -29,8 +30,6 @@ Verify the help text when the AddOption() function is used (and when
 it's not).
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -56,27 +55,27 @@ expected_lines = [
 ]
 
 test.run(arguments = '-h')
-lines = string.split(test.stdout(), '\n')
-missing = filter(lambda e, l=lines: not e in l, expected_lines)
+lines = test.stdout().split('\n')
+missing = [e for e in expected_lines if e not in lines]
 
 if missing:
     print "====== STDOUT:"
     print test.stdout()
     print "====== Missing the following lines in the above AddOption() help output:"
-    print string.join(missing, "\n")
+    print "\n".join(missing)
     test.fail_test()
 
 test.unlink('SConstruct')
 
 test.run(arguments = '-h')
-lines = string.split(test.stdout(), '\n')
-unexpected = filter(lambda e, l=lines: e in l, expected_lines)
+lines = test.stdout().split('\n')
+unexpected = [e for e in expected_lines if e in lines]
 
 if unexpected:
     print "====== STDOUT:"
     print test.stdout()
     print "====== Unexpected lines in the above non-AddOption() help output:"
-    print string.join(unexpected, "\n")
+    print "\n".join(unexpected)
     test.fail_test()
 
 test.pass_test()
diff --git a/test/Alias/action.py b/test/Alias/action.py
index 72aab6e0..74eb6f96 100644
--- a/test/Alias/action.py
+++ b/test/Alias/action.py
@@ -35,20 +35,19 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', """
 def cat(target, source, env):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 def foo(target, source, env):
-    target = map(str, target)
-    source = map(str, source)
+    target = list(map(str, target))
+    source = list(map(str, source))
     open('foo', 'wb').write("foo(%s, %s)\\n" % (target, source))
 
 def bar(target, source, env):
-    target = map(str, target)
-    source = map(str, source)
+    target = list(map(str, target))
+    source = list(map(str, source))
     open('bar', 'wb').write("bar(%s, %s)\\n" % (target, source))
 
 env = Environment(BUILDERS = {'Cat':Builder(action=cat)})
diff --git a/test/Alias/scanner.py b/test/Alias/scanner.py
index 743191c4..fc785462 100644
--- a/test/Alias/scanner.py
+++ b/test/Alias/scanner.py
@@ -35,10 +35,9 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 XBuilder = Builder(action = cat, src_suffix = '.x', suffix = '.c')
diff --git a/test/BitKeeper/BITKEEPERCOM.py b/test/BitKeeper/BITKEEPERCOM.py
index aed066ce..d01ad961 100644
--- a/test/BitKeeper/BITKEEPERCOM.py
+++ b/test/BitKeeper/BITKEEPERCOM.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'BitKeeper'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/BitKeeper/BITKEEPERCOMSTR.py b/test/BitKeeper/BITKEEPERCOMSTR.py
index a8207c64..311ef4de 100644
--- a/test/BitKeeper/BITKEEPERCOMSTR.py
+++ b/test/BitKeeper/BITKEEPERCOMSTR.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'BitKeeper'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/BitKeeper/BitKeeper.py b/test/BitKeeper/BitKeeper.py
index 9a61e75c..24b9cccb 100644
--- a/test/BitKeeper/BitKeeper.py
+++ b/test/BitKeeper/BitKeeper.py
@@ -91,10 +91,9 @@ env.Cat('all', ['ddd.out', 'eee.out', 'fff.out'])
     test.write(['work1', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
                   BITKEEPERGETFLAGS='-e')
@@ -191,10 +190,9 @@ env.Cat('all', ['ddd.out', 'eee.out', 'fff.out'])
     test.write(['work2', 'SConstruct'], """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
                   BITKEEPERGET='$BITKEEPER co',
@@ -287,10 +285,9 @@ test.run(chdir = 'import',
 test.write(['work3', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 DefaultEnvironment(tools=['SCCS'])['SCCS'] = r'%s'
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
diff --git a/test/Builder/multi/same-overrides.py b/test/Builder/multi/same-overrides.py
index 5a3a7f8c..9a428a27 100644
--- a/test/Builder/multi/same-overrides.py
+++ b/test/Builder/multi/same-overrides.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Verify that everything works if two multi calls have the same overrides.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons(match=TestSCons.match_re)
@@ -56,7 +54,7 @@ env.B(target = 'file4.out', source = 'file4b.in', foo=3)
 test.write('file4a.in', 'file4a.in\n')
 test.write('file4b.in', 'file4b.in\n')
 
-python_expr = string.replace(TestSCons.python, '\\', '\\\\')
+python_expr = TestSCons.python.replace('\\', '\\\\')
 act = TestSCons.re_escape('"%s" build.py \$foo \$TARGET \$SOURCES' % python_expr)
 
 expect = ("""
diff --git a/test/CC/CC.py b/test/CC/CC.py
index c4120948..2c66040a 100644
--- a/test/CC/CC.py
+++ b/test/CC/CC.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 import TestSCons
 
@@ -39,7 +38,6 @@ test = TestSCons.TestSCons()
 if sys.platform == 'win32':
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -47,7 +45,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
@@ -149,11 +147,10 @@ env.Program(target = 'test2', source = 'test2.C')
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/CC/CCCOM.py b/test/CC/CCCOM.py
index 6634e15a..8d06942e 100644
--- a/test/CC/CCCOM.py
+++ b/test/CC/CCCOM.py
@@ -43,7 +43,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:6] != '/*cc*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CC/CCCOMSTR.py b/test/CC/CCCOMSTR.py
index f66a192d..6874406f 100644
--- a/test/CC/CCCOMSTR.py
+++ b/test/CC/CCCOMSTR.py
@@ -44,7 +44,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:6] != '/*cc*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CC/SHCC.py b/test/CC/SHCC.py
index f80dfe5a..b624bf26 100644
--- a/test/CC/SHCC.py
+++ b/test/CC/SHCC.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -35,11 +34,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/CC/SHCCCOM.py b/test/CC/SHCCCOM.py
index ab61035c..0e87b621 100644
--- a/test/CC/SHCCCOM.py
+++ b/test/CC/SHCCCOM.py
@@ -42,7 +42,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:6] != '/*cc*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CC/SHCCCOMSTR.py b/test/CC/SHCCCOMSTR.py
index 05c27ad4..15bfa858 100644
--- a/test/CC/SHCCCOMSTR.py
+++ b/test/CC/SHCCCOMSTR.py
@@ -44,7 +44,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:6] != '/*cc*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:6] != '/*cc*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CC/SHCCFLAGS.py b/test/CC/SHCCFLAGS.py
index d77d2474..72d36b14 100644
--- a/test/CC/SHCCFLAGS.py
+++ b/test/CC/SHCCFLAGS.py
@@ -27,7 +27,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import sys
 import TestSCons
 import os
-import string
     
 test = TestSCons.TestSCons()
 
@@ -37,7 +36,7 @@ barflags = e['SHCCFLAGS'] + ' -DBAR'
 
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') > -1:
+if sys.platform.find('irix') > -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test.write('SConstruct', """
diff --git a/test/CC/SHCFLAGS.py b/test/CC/SHCFLAGS.py
index c201c97c..3ec67783 100644
--- a/test/CC/SHCFLAGS.py
+++ b/test/CC/SHCFLAGS.py
@@ -27,7 +27,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import sys
 import TestSCons
 import os
-import string
     
 test = TestSCons.TestSCons()
 
@@ -37,7 +36,7 @@ barflags = e['SHCFLAGS'] + ' -DBAR'
 
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') > -1:
+if sys.platform.find('irix') > -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test.write('SConstruct', """
diff --git a/test/CFILESUFFIX.py b/test/CFILESUFFIX.py
index e167155b..1a812402 100644
--- a/test/CFILESUFFIX.py
+++ b/test/CFILESUFFIX.py
@@ -38,12 +38,11 @@ test = TestSCons.TestSCons()
 
 test.write('mylex.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 't', [])
 for a in args:
     contents = open(a, 'rb').read()
-    sys.stdout.write(string.replace(contents, 'LEX', 'mylex.py'))
+    sys.stdout.write(contents.replace('LEX', 'mylex.py'))
 sys.exit(0)
 """)
 
diff --git a/test/CPPPATH/absolute-path.py b/test/CPPPATH/absolute-path.py
index 1fe62300..f414e09e 100644
--- a/test/CPPPATH/absolute-path.py
+++ b/test/CPPPATH/absolute-path.py
@@ -30,7 +30,6 @@ is not strictly a test of using $CPPPATH, but it's in the ball park...)
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -45,7 +44,7 @@ does_not_exist_h = test.workpath('include', 'does_not_exist.h')
 # Verify that including an absolute path still works even if they
 # double the separators in the input file.  This can happen especially
 # on Windows if they use \\ to represent an escaped backslash.
-inc2_h = string.replace(inc2_h, os.sep, os.sep+os.sep)
+inc2_h = inc2_h.replace(os.sep, os.sep+os.sep)
 
 test.write(['work', 'SConstruct'], """\
 Program('prog.c')
diff --git a/test/CVS.py b/test/CVS.py
index b702d987..eb2553d5 100644
--- a/test/CVS.py
+++ b/test/CVS.py
@@ -91,10 +91,9 @@ test.write(['work1', 'SConstruct'], """
 import os
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(ENV = { 'PATH' : os.environ['PATH'],
                           'EDITOR' : os.environ.get('EDITOR', 'ed') },
@@ -156,10 +155,9 @@ test.write(['work2', 'SConstruct'], """
 import os
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(ENV = { 'PATH' : os.environ['PATH'],
                           'EDITOR' : os.environ.get('EDITOR', 'ed') },
@@ -228,10 +226,9 @@ test.write(['work3', 'SConstruct'], """\
 import os
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(ENV = { 'PATH' : os.environ['PATH'],
                           'EDITOR' : os.environ.get('EDITOR', 'ed') },
diff --git a/test/CVSCOM.py b/test/CVSCOM.py
index 79acb5ae..546e7778 100644
--- a/test/CVSCOM.py
+++ b/test/CVSCOM.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'CVS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/CVSCOMSTR.py b/test/CVSCOMSTR.py
index ae428418..d45bca6d 100644
--- a/test/CVSCOMSTR.py
+++ b/test/CVSCOMSTR.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'CVS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/CXX/CXX.py b/test/CXX/CXX.py
index e6bc82bf..1e338a65 100644
--- a/test/CXX/CXX.py
+++ b/test/CXX/CXX.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 import TestSCons
 
@@ -39,7 +38,6 @@ test = TestSCons.TestSCons()
 if sys.platform == 'win32':
 
     test.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -47,7 +45,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
@@ -179,11 +177,10 @@ env.Program(target = 'test6', source = 'test6.C')
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/CXX/CXXCOM.py b/test/CXX/CXXCOM.py
index f623eaf2..a3da81ae 100644
--- a/test/CXX/CXXCOM.py
+++ b/test/CXX/CXXCOM.py
@@ -41,7 +41,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:7] != '/*c++*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:7] != '/*c++*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CXX/CXXCOMSTR.py b/test/CXX/CXXCOMSTR.py
index ebacd194..9d54e91b 100644
--- a/test/CXX/CXXCOMSTR.py
+++ b/test/CXX/CXXCOMSTR.py
@@ -42,7 +42,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*c++*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*c++*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CXX/CXXFILESUFFIX.py b/test/CXX/CXXFILESUFFIX.py
index 749ca69d..8439aefa 100644
--- a/test/CXX/CXXFILESUFFIX.py
+++ b/test/CXX/CXXFILESUFFIX.py
@@ -34,12 +34,11 @@ test = TestSCons.TestSCons()
 
 test.write('mylex.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 't', [])
 for a in args:
     contents = open(a, 'rb').read()
-    sys.stdout.write(string.replace(contents, 'LEX', 'mylex.py'))
+    sys.stdout.write(contents.replace('LEX', 'mylex.py'))
 sys.exit(0)
 """)
 
diff --git a/test/CXX/CXXFLAGS.py b/test/CXX/CXXFLAGS.py
index f83fe480..8d72708e 100644
--- a/test/CXX/CXXFLAGS.py
+++ b/test/CXX/CXXFLAGS.py
@@ -30,7 +30,6 @@ and shared object files.
 """
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -39,7 +38,7 @@ _obj = TestSCons._obj
 
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') > -1:
+if sys.platform.find('irix') > -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test = TestSCons.TestSCons()
diff --git a/test/CXX/SHCXX.py b/test/CXX/SHCXX.py
index 6351cfe5..9a788818 100644
--- a/test/CXX/SHCXX.py
+++ b/test/CXX/SHCXX.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -35,11 +34,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/CXX/SHCXXCOM.py b/test/CXX/SHCXXCOM.py
index 7c5e45f2..0f0940bb 100644
--- a/test/CXX/SHCXXCOM.py
+++ b/test/CXX/SHCXXCOM.py
@@ -41,7 +41,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l[:7] != '/*c++*/', infile.readlines()):
+for l in [l for l in infile.readlines() if l[:7] != '/*c++*/']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CXX/SHCXXCOMSTR.py b/test/CXX/SHCXXCOMSTR.py
index afe647a8..716c9adf 100644
--- a/test/CXX/SHCXXCOMSTR.py
+++ b/test/CXX/SHCXXCOMSTR.py
@@ -42,7 +42,7 @@ test.write('mycc.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*c++*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*c++*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/CXX/SHCXXFLAGS.py b/test/CXX/SHCXXFLAGS.py
index a4d552e0..343be30f 100644
--- a/test/CXX/SHCXXFLAGS.py
+++ b/test/CXX/SHCXXFLAGS.py
@@ -29,7 +29,6 @@ Verify that $SHCXXFLAGS settings are used to build shared object files.
 """
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -38,7 +37,7 @@ _obj = TestSCons._obj
 
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') > -1:
+if sys.platform.find('irix') > -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test = TestSCons.TestSCons()
diff --git a/test/CacheDir/CacheDir.py b/test/CacheDir/CacheDir.py
index c72b2d06..9abe0e05 100644
--- a/test/CacheDir/CacheDir.py
+++ b/test/CacheDir/CacheDir.py
@@ -53,10 +53,9 @@ test.write(['src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/VariantDir.py b/test/CacheDir/VariantDir.py
index 8ba3e781..b665fe38 100644
--- a/test/CacheDir/VariantDir.py
+++ b/test/CacheDir/VariantDir.py
@@ -43,10 +43,9 @@ test.write(['src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/debug.py b/test/CacheDir/debug.py
index 94880be3..307687df 100644
--- a/test/CacheDir/debug.py
+++ b/test/CacheDir/debug.py
@@ -53,10 +53,9 @@ test.write(['src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/environment.py b/test/CacheDir/environment.py
index 297d46d8..4fb9b51f 100644
--- a/test/CacheDir/environment.py
+++ b/test/CacheDir/environment.py
@@ -54,10 +54,9 @@ test.write(['src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env_cache = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env_nocache = env_cache.Clone()
diff --git a/test/CacheDir/option--cd.py b/test/CacheDir/option--cd.py
index 9b9f2f7a..b77cfeb2 100644
--- a/test/CacheDir/option--cd.py
+++ b/test/CacheDir/option--cd.py
@@ -42,10 +42,9 @@ test.write(['src', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/option--cf.py b/test/CacheDir/option--cf.py
index b2237556..6d64059d 100644
--- a/test/CacheDir/option--cf.py
+++ b/test/CacheDir/option--cf.py
@@ -41,10 +41,9 @@ test.write(['src', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/CacheDir/option--cs.py b/test/CacheDir/option--cs.py
index df1a87f7..b6bb52a2 100644
--- a/test/CacheDir/option--cs.py
+++ b/test/CacheDir/option--cs.py
@@ -57,10 +57,9 @@ test.write(['src1', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
     open('cat.out', 'ab').write(target + "\\n")
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Internal':Builder(action=cat),
                             'External':Builder(action='%(_python_)s build.py $TARGET $SOURCES')})
diff --git a/test/Case.py b/test/Case.py
index 435ca4ac..fb6821da 100644
--- a/test/Case.py
+++ b/test/Case.py
@@ -24,7 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import sys
 import TestSCons
 
@@ -73,7 +72,7 @@ if sys.platform in ['cygwin', 'win32']:
     sys.stdout.flush()
 
     test.run(stderr = None, status = None)
-    test.fail_test(string.split(test.stderr(), '\n')[0] ==
+    test.fail_test(test.stderr().split('\n')[0] ==
                    "scons: *** Multiple ways to build the same target were specified for: foo.o")
 
 else:
diff --git a/test/Chmod.py b/test/Chmod.py
index cf31d006..c00aea0f 100644
--- a/test/Chmod.py
+++ b/test/Chmod.py
@@ -45,10 +45,9 @@ Execute(Chmod('d2', 0777))
 Execute(Chmod(Dir('d2-Dir'), 0777))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
diff --git a/test/Climb/explicit-parent--D.py b/test/Climb/explicit-parent--D.py
index da58b382..f894e334 100644
--- a/test/Climb/explicit-parent--D.py
+++ b/test/Climb/explicit-parent--D.py
@@ -38,10 +38,9 @@ test.subdir(['subdir'])
 test.write('SConstruct', """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('f1.out', 'f1.in')
diff --git a/test/Climb/explicit-parent--U.py b/test/Climb/explicit-parent--U.py
index 18cb5891..ab2d33e0 100644
--- a/test/Climb/explicit-parent--U.py
+++ b/test/Climb/explicit-parent--U.py
@@ -38,10 +38,9 @@ test.subdir('subdir')
 test.write('SConstruct', """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('foo.out', 'foo.in')
diff --git a/test/Climb/explicit-parent-u.py b/test/Climb/explicit-parent-u.py
index 633a4d31..e3e774e1 100644
--- a/test/Climb/explicit-parent-u.py
+++ b/test/Climb/explicit-parent-u.py
@@ -39,10 +39,9 @@ test.subdir('subdir')
 test.write('SConstruct', """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('f1.out', 'f1.in')
diff --git a/test/Climb/option-u.py b/test/Climb/option-u.py
index 6fc27207..eeb2ccc4 100644
--- a/test/Climb/option-u.py
+++ b/test/Climb/option-u.py
@@ -43,10 +43,9 @@ test.subdir('sub1',
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment()
 env.Append(BUILDERS = {'Cat' : Builder(action=cat)})
diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py
index 9276ec83..cda6c3b9 100644
--- a/test/Configure/config-h.py
+++ b/test/Configure/config-h.py
@@ -30,14 +30,13 @@ Verify creation of a config.h file from a Configure context.
 
 import os
 import re
-import string
 
 import TestSCons
 
 test = TestSCons.TestSCons(match = TestSCons.match_exact)
 
 lib = test.Configure_lib
-LIB = "LIB" + string.upper(lib)
+LIB = "LIB" + lib.upper()
 
 test.write('SConstruct', """\
 env = Environment()
@@ -85,7 +84,7 @@ scons: Configure: creating config.h
 expected_stdout = test.wrap_stdout(build_str=expected_build_str,
                                        read_str=expected_read_str)
 
-expected_config_h = string.replace("""\
+expected_config_h = ("""\
 #ifndef CONFIG_H_SEEN
 #define CONFIG_H_SEEN
 
@@ -130,7 +129,7 @@ expected_config_h = string.replace("""\
 /* #undef HAVE_LIBHOPEFULLYNOLIB2 */
 
 #endif /* CONFIG_H_SEEN */
-""" % locals(), "\n", os.linesep)
+""" % locals()).replace("\n", os.linesep)
 
 test.run(stdout=expected_stdout)
 
@@ -157,7 +156,7 @@ expected_read_str = re.sub(r'\b((yes)|(no))\b',
 expected_build_str = "scons: `.' is up to date.\n"
 expected_stdout = test.wrap_stdout(build_str=expected_build_str,
                                    read_str=expected_read_str)
-#expected_stdout = string.replace(expected_stdout, "\n", os.linesep)
+#expected_stdout = expected_stdout.replace("\n", os.linesep)
 
 test.run(stdout=expected_stdout)    
 
diff --git a/test/Copy-Action.py b/test/Copy-Action.py
index 6e9c54f9..f64defea 100644
--- a/test/Copy-Action.py
+++ b/test/Copy-Action.py
@@ -43,10 +43,9 @@ Execute(Copy(File('d2.out'), 'd2.in'))
 Execute(Copy('d3.out', File('f3.in')))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
@@ -155,9 +154,9 @@ errors = 0
 def must_be_same(f1, f2):
     global errors
     if type(f1) is type([]):
-        f1 = apply(os.path.join, f1)
+        f1 = os.path.join(*f1)
     if type(f2) is type([]):
-        f2 = apply(os.path.join, f2)
+        f2 = os.path.join(*f2)
     s1 = os.stat(f1)
     s2 = os.stat(f2)
     for value in ['ST_MODE', 'ST_MTIME']:
diff --git a/test/DVIPDF/DVIPDF.py b/test/DVIPDF/DVIPDF.py
index 7b3e2922..e7607410 100644
--- a/test/DVIPDF/DVIPDF.py
+++ b/test/DVIPDF/DVIPDF.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -110,12 +108,11 @@ tex = test.where_is('tex')
 if dvipdf and tex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/DVIPDF/DVIPDFCOM.py b/test/DVIPDF/DVIPDFCOM.py
index 1ff5a3d0..362279e9 100644
--- a/test/DVIPDF/DVIPDFCOM.py
+++ b/test/DVIPDF/DVIPDFCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*pdf*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*pdf*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/DVIPDF/DVIPDFCOMSTR.py b/test/DVIPDF/DVIPDFCOMSTR.py
index 8b048bb9..0063e84b 100644
--- a/test/DVIPDF/DVIPDFCOMSTR.py
+++ b/test/DVIPDF/DVIPDFCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*pdf*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*pdf*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/DVIPDF/DVIPDFFLAGS.py b/test/DVIPDF/DVIPDFFLAGS.py
index 93a435fd..4d03644b 100644
--- a/test/DVIPDF/DVIPDFFLAGS.py
+++ b/test/DVIPDF/DVIPDFFLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -114,12 +112,11 @@ tex = test.where_is('tex')
 if dvipdf and tex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/DVIPS/DVIPS.py b/test/DVIPS/DVIPS.py
index 540869d9..e28a1212 100644
--- a/test/DVIPS/DVIPS.py
+++ b/test/DVIPS/DVIPS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -122,12 +120,11 @@ dvips = test.where_is('dvips')
 if dvips:
 
     test.write("wrapper.py", """import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/DVIPS/DVIPSFLAGS.py b/test/DVIPS/DVIPSFLAGS.py
index a5be0a27..285c7290 100644
--- a/test/DVIPS/DVIPSFLAGS.py
+++ b/test/DVIPS/DVIPSFLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -129,12 +127,11 @@ dvips = test.where_is('dvips')
 if dvips:
 
     test.write("wrapper.py", """import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/DVIPS/PSCOM.py b/test/DVIPS/PSCOM.py
index 3e1e5e9f..fe4832bd 100644
--- a/test/DVIPS/PSCOM.py
+++ b/test/DVIPS/PSCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ps*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ps*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/DVIPS/PSCOMSTR.py b/test/DVIPS/PSCOMSTR.py
index 96814a0d..7c57ded1 100644
--- a/test/DVIPS/PSCOMSTR.py
+++ b/test/DVIPS/PSCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ps*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ps*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Delete.py b/test/Delete.py
index 20dc8894..f3dfcb6b 100644
--- a/test/Delete.py
+++ b/test/Delete.py
@@ -39,10 +39,9 @@ Execute(Delete('f1'))
 Execute(Delete('d2'))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
@@ -164,10 +163,9 @@ test.must_match('f16.out', "f16.in\n")
 test.write("SConstruct", """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
diff --git a/test/Deprecated/BuildDir.py b/test/Deprecated/BuildDir.py
index 02ef1397..e8755dac 100644
--- a/test/Deprecated/BuildDir.py
+++ b/test/Deprecated/BuildDir.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -32,8 +33,6 @@ under the covers).
 Note that using BuildDir() does not yet print a deprecation warning.
 """
 
-import string
-
 import TestSCons
 
 _exe = TestSCons._exe
@@ -191,10 +190,9 @@ test.write(['work1', 'src', 'f4h.in'], r"""
 def blank_output(err):
     if not err:
         return 1
-    stderrlines = filter(lambda l: l, string.split(err, '\n'))
+    stderrlines = [l for l in err.split('\n') if l]
     msg = "warning: tempnam() possibly used unsafely"
-    stderrlines = filter(lambda l, msg=msg: string.find(l, msg) == -1,
-                         stderrlines)
+    stderrlines = [l for l in stderrlines if l.find(msg) == -1]
     return len(stderrlines) == 0
 
 test.run(chdir='work1', arguments = '. ../build', stderr=None)
diff --git a/test/Deprecated/Options/BoolOption.py b/test/Deprecated/Options/BoolOption.py
index 57a44c80..d99544ff 100644
--- a/test/Deprecated/Options/BoolOption.py
+++ b/test/Deprecated/Options/BoolOption.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test the BoolOption canned Option type.
 """
 
-import string
-
 try:
     True, False
 except NameError:
@@ -43,7 +41,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Deprecated/Options/EnumOption.py b/test/Deprecated/Options/EnumOption.py
index 26b14d8c..6756f09c 100644
--- a/test/Deprecated/Options/EnumOption.py
+++ b/test/Deprecated/Options/EnumOption.py
@@ -29,7 +29,6 @@ Test the EnumOption canned Option type.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -38,7 +37,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Deprecated/Options/ListOption.py b/test/Deprecated/Options/ListOption.py
index 28983d25..bb3775ba 100644
--- a/test/Deprecated/Options/ListOption.py
+++ b/test/Deprecated/Options/ListOption.py
@@ -29,7 +29,6 @@ Test the ListOption canned Option type.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -39,7 +38,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     r = result[1:len(expect)+1]
     assert r == expect, (r, expect)
 
diff --git a/test/Deprecated/Options/Options.py b/test/Deprecated/Options/Options.py
index d1c7114d..8116a636 100644
--- a/test/Deprecated/Options/Options.py
+++ b/test/Deprecated/Options/Options.py
@@ -25,23 +25,19 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import TestSCons
-import string
 
 test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 
 test.write('SConstruct', """
-import string
 env = Environment()
 print env['CC']
-print string.join(env['CCFLAGS'])
+print " ".join(env['CCFLAGS'])
 Default(env.Alias('dummy', None))
 """)
 test.run()
-cc, ccflags = string.split(test.stdout(), '\n')[1:3]
+cc, ccflags = test.stdout().split('\n')[1:3]
 
 test.write('SConstruct', """
-import string
-
 # test validator.  Change a key and add a new one to the environment
 def validator(key, value, environ):
     environ[key] = "v"
@@ -106,15 +102,15 @@ Help('Variables settable in custom.py or on the command line:\\n' + opts.Generat
 print env['RELEASE_BUILD']
 print env['DEBUG_BUILD']
 print env['CC']
-print string.join(env['CCFLAGS'])
+print " ".join(env['CCFLAGS'])
 print env['VALIDATE']
 print env['valid_key']
 
 # unspecified options should not be set:
-assert not env.has_key('UNSPECIFIED')
+assert 'UNSPECIFIED' not in env
 
 # undeclared options should be ignored:
-assert not env.has_key('UNDECLARED')
+assert 'UNDECLARED' not in env
 
 # calling Update() should not effect options that
 # are not declared on the options object:
@@ -133,26 +129,26 @@ scons: warning: The Options class is deprecated; use the Variables class instead
 
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 test.run(stderr=warnings)
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='RELEASE_BUILD=1', stderr=warnings)
-check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
+check(['1', '1', cc, (ccflags + ' -O -g').strip(), 'v', 'v'])
 
 test.run(arguments='RELEASE_BUILD=1 DEBUG_BUILD=0', stderr=warnings)
-check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
+check(['1', '0', cc, (ccflags + ' -O').strip(), 'v', 'v'])
 
 test.run(arguments='CC=not_a_c_compiler', stderr=warnings)
-check(['0', '1', 'not_a_c_compiler', string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', 'not_a_c_compiler', (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='UNDECLARED=foo', stderr=warnings)
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='CCFLAGS=--taco', stderr=warnings)
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.write('custom.py', """
 DEBUG_BUILD=0
@@ -160,10 +156,10 @@ RELEASE_BUILD=1
 """)
 
 test.run(stderr=warnings)
-check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
+check(['1', '0', cc, (ccflags + ' -O').strip(), 'v', 'v'])
 
 test.run(arguments='DEBUG_BUILD=1', stderr=warnings)
-check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
+check(['1', '1', cc, (ccflags + ' -O -g').strip(), 'v', 'v'])
 
 test.run(arguments='-h',
          stdout = """\
diff --git a/test/Deprecated/Options/PackageOption.py b/test/Deprecated/Options/PackageOption.py
index bb396539..b9f0400e 100644
--- a/test/Deprecated/Options/PackageOption.py
+++ b/test/Deprecated/Options/PackageOption.py
@@ -29,7 +29,6 @@ Test the PackageOption canned Option type.
 """
 
 import os.path
-import string
 
 try:
     True, False
@@ -44,7 +43,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Deprecated/Options/PathOption.py b/test/Deprecated/Options/PathOption.py
index 3c73617c..4701420b 100644
--- a/test/Deprecated/Options/PathOption.py
+++ b/test/Deprecated/Options/PathOption.py
@@ -31,7 +31,6 @@ various canned validators.
 
 import os.path
 import re
-import string
 
 import TestSCons
 
@@ -40,7 +39,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 #### test PathOption ####
diff --git a/test/Deprecated/SConscript-build_dir.py b/test/Deprecated/SConscript-build_dir.py
index d54f3afd..41b52223 100644
--- a/test/Deprecated/SConscript-build_dir.py
+++ b/test/Deprecated/SConscript-build_dir.py
@@ -61,10 +61,9 @@ var9 = Dir('../build/var9')
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/Deprecated/debug-stree.py b/test/Deprecated/debug-stree.py
index 43a370ac..907dedfb 100644
--- a/test/Deprecated/debug-stree.py
+++ b/test/Deprecated/debug-stree.py
@@ -29,8 +29,6 @@ Test that the --debug=stree option prints a dependency tree with output
 that indicates the state of various Node status flags.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
@@ -98,7 +96,7 @@ stree = """
 
 test.run(arguments = "--debug=stree foo.xxx",
          stderr = stderr)
-test.fail_test(string.count(test.stdout(), stree) != 1)
+test.fail_test(test.stdout().count(stree) != 1)
 
 stree2 = """
  E         = exists
@@ -130,7 +128,7 @@ test.run(arguments = '-c foo.xxx')
 
 test.run(arguments = "--no-exec --debug=stree foo.xxx",
          stderr = stderr)
-test.fail_test(string.count(test.stdout(), stree2) != 1)
+test.fail_test(test.stdout().count(stree2) != 1)
 
 test.pass_test()
 
diff --git a/test/ESCAPE.py b/test/ESCAPE.py
index 68835f1a..0651b92d 100644
--- a/test/ESCAPE.py
+++ b/test/ESCAPE.py
@@ -43,13 +43,12 @@ ofp.close()
 """)
 
 test.write('SConstruct', """\
-import string
 # We still need to run this through the original ESCAPE function,
 # because that's set up to work in tandem with the existing SHELL,
 # which we're not replacing.
 orig_escape = Environment()['ESCAPE']
 def my_escape(s):
-    s = string.replace(s, 'file.in', 'file.xxx')
+    s = s.replace('file.in', 'file.xxx')
     return orig_escape(s)
 env = Environment(ESCAPE = my_escape)
 env.Command('file.out', 'file.in', '%(_python_)s cat.py $TARGET $SOURCES')
diff --git a/test/Errors/InternalError.py b/test/Errors/InternalError.py
index 032c7a72..49d9fdd8 100644
--- a/test/Errors/InternalError.py
+++ b/test/Errors/InternalError.py
@@ -35,7 +35,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 
 # Test InternalError.
 test.write('SConstruct', """
-assert not globals().has_key("InternalError")
+assert "InternalError" not in globals()
 from SCons.Errors import InternalError
 raise InternalError, 'error inside'
 """)
diff --git a/test/Errors/UserError.py b/test/Errors/UserError.py
index c534ed60..0212a528 100644
--- a/test/Errors/UserError.py
+++ b/test/Errors/UserError.py
@@ -34,7 +34,7 @@ import TestSCons
 test = TestSCons.TestSCons(match = TestSCons.match_re_dotall)
 
 test.write('SConstruct', """
-assert not globals().has_key("UserError")
+assert "UserError" not in globals()
 import SCons.Errors
 raise SCons.Errors.UserError, 'Depends() requires both sources and targets.'
 """)
diff --git a/test/Errors/execute-a-directory.py b/test/Errors/execute-a-directory.py
index e02dcb05..bf2c2462 100644
--- a/test/Errors/execute-a-directory.py
+++ b/test/Errors/execute-a-directory.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -41,7 +40,7 @@ test.write('SConstruct', r"""
 bld = Builder(action = '%s $SOURCES $TARGET')
 env = Environment(BUILDERS = { 'bld' : bld })
 env.bld(target = 'f3', source = 'f3.in')
-""" % string.replace(test.workdir, '\\', '\\\\'))
+""" % test.workdir.replace('\\', '\\\\'))
 
 test.run(arguments='.',
          stdout = test.wrap_stdout("%s f3.in f3\n" % test.workdir, error=1),
diff --git a/test/Errors/non-executable-file.py b/test/Errors/non-executable-file.py
index dc6b6063..e51dc85c 100644
--- a/test/Errors/non-executable-file.py
+++ b/test/Errors/non-executable-file.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -72,7 +71,7 @@ test.write('SConstruct', r"""
 bld = Builder(action = '%s $SOURCES $TARGET')
 env = Environment(BUILDERS = { 'bld': bld })
 env.bld(target = 'f1', source = 'f1.in')
-""" % string.replace(not_executable, '\\', '\\\\'))
+""" % not_executable.replace('\\', '\\\\'))
 
 test.run(arguments='.',
          stdout = test.wrap_stdout("%s f1.in f1\n" % not_executable, error=1),
diff --git a/test/Errors/nonexistent-executable.py b/test/Errors/nonexistent-executable.py
index ab6d1186..1272e818 100644
--- a/test/Errors/nonexistent-executable.py
+++ b/test/Errors/nonexistent-executable.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -39,7 +38,7 @@ test.write('SConstruct', r"""
 bld = Builder(action = '%s $SOURCES $TARGET')
 env = Environment(BUILDERS = { 'bld' : bld })
 env.bld(target = 'f1', source = 'f1.in')
-""" % string.replace(no_such_file, '\\', '\\\\'))
+""" % no_such_file.replace('\\', '\\\\'))
 
 test.run(arguments='.',
          stdout = test.wrap_stdout("%s f1.in f1\n" % no_such_file, error=1),
diff --git a/test/Exit.py b/test/Exit.py
index 98d6bbaf..877a0b6c 100644
--- a/test/Exit.py
+++ b/test/Exit.py
@@ -104,10 +104,9 @@ SConscript('subdir/SConscript')
 test.write(['subdir', 'SConscript'], """\
 def exit_builder(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
     Exit(27)
 env = Environment(BUILDERS = {'my_exit' : Builder(action=exit_builder)})
@@ -134,11 +133,9 @@ exitscan = Scanner(function = exit_scanner, skeys = ['.k'])
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
-
     outf = open(target, 'wb')
     for src in source:
-        outf.write(open(src, "rb").read())
+        outf.write(open(str(src), "rb").read())
     outf.close()
 
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
diff --git a/test/Flatten.py b/test/Flatten.py
index 2fae80b2..b41c4fef 100644
--- a/test/Flatten.py
+++ b/test/Flatten.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test that the Flatten() function is available and works.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -39,16 +37,15 @@ test.subdir('work')
 test.write(['work', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 f1 = env.Cat('../file1.out', 'file1.in')
 f2 = env.Cat('../file2.out', ['file2a.in', 'file2b.in'])
-print map(str, Flatten(['begin', f1, 'middle', f2, 'end']))
-print map(str, env.Flatten([f1, [['a', 'b'], 'c'], f2]))
+print list(map(str, Flatten(['begin', f1, 'middle', f2, 'end'])))
+print list(map(str, env.Flatten([f1, [['a', 'b'], 'c'], f2])))
 SConscript('SConscript', "env")
 """)
 
@@ -64,7 +61,7 @@ test.write('file2b.in', "file2b.in\n")
 
 def double_backslash(f):
     p = test.workpath(f)
-    return string.replace(p, '\\', '\\\\')
+    return p.replace('\\', '\\\\')
 
 expect = """\
 ['begin', '%s', 'middle', '%s', 'end']
diff --git a/test/Fortran/F77.py b/test/Fortran/F77.py
index 2dc1bbfe..0ebd7ee3 100644
--- a/test/Fortran/F77.py
+++ b/test/Fortran/F77.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -100,11 +98,10 @@ if f77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F77 = '%(fc)s', tools = ['default', 'f77'], F77FILESUFFIXES = ['.f'])
diff --git a/test/Fortran/F77COMSTR.py b/test/Fortran/F77COMSTR.py
index 502473a1..6c898336 100644
--- a/test/Fortran/F77COMSTR.py
+++ b/test/Fortran/F77COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/F77FLAGS.py b/test/Fortran/F77FLAGS.py
index 70ef51c9..b708f9ec 100644
--- a/test/Fortran/F77FLAGS.py
+++ b/test/Fortran/F77FLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -81,11 +79,10 @@ if g77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F77 = '%(fc)s', tools = ['default', 'f77'], F77FILESUFFIXES = [".f"])
diff --git a/test/Fortran/F90.py b/test/Fortran/F90.py
index 7c31ee6f..d7c73c60 100644
--- a/test/Fortran/F90.py
+++ b/test/Fortran/F90.py
@@ -100,11 +100,10 @@ if g90:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F90 = '%(fc)s')
diff --git a/test/Fortran/F90COMSTR.py b/test/Fortran/F90COMSTR.py
index eec5795d..117a5a98 100644
--- a/test/Fortran/F90COMSTR.py
+++ b/test/Fortran/F90COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/F90FLAGS.py b/test/Fortran/F90FLAGS.py
index 5f8df8d5..f0b30038 100644
--- a/test/Fortran/F90FLAGS.py
+++ b/test/Fortran/F90FLAGS.py
@@ -107,11 +107,10 @@ if g90:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F90 = '%(fc)s')
diff --git a/test/Fortran/F95.py b/test/Fortran/F95.py
index eeadac7e..e7745b16 100644
--- a/test/Fortran/F95.py
+++ b/test/Fortran/F95.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -102,11 +100,10 @@ if g95:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F95 = '%(fc)s')
diff --git a/test/Fortran/F95COMSTR.py b/test/Fortran/F95COMSTR.py
index 1f9734a5..5d162f96 100644
--- a/test/Fortran/F95COMSTR.py
+++ b/test/Fortran/F95COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/F95FLAGS.py b/test/Fortran/F95FLAGS.py
index 86fd9f54..de188585 100644
--- a/test/Fortran/F95FLAGS.py
+++ b/test/Fortran/F95FLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -109,11 +107,10 @@ if g95:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(F95 = '%(fc)s')
diff --git a/test/Fortran/FORTRAN.py b/test/Fortran/FORTRAN.py
index 96f2749c..df73ea68 100644
--- a/test/Fortran/FORTRAN.py
+++ b/test/Fortran/FORTRAN.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -95,11 +93,10 @@ if f77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(FORTRAN = '%(fc)s')
diff --git a/test/Fortran/FORTRANCOMSTR.py b/test/Fortran/FORTRANCOMSTR.py
index ba923d34..5efa820c 100644
--- a/test/Fortran/FORTRANCOMSTR.py
+++ b/test/Fortran/FORTRANCOMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/FORTRANFLAGS.py b/test/Fortran/FORTRANFLAGS.py
index 3424bfd8..8c5e781f 100644
--- a/test/Fortran/FORTRANFLAGS.py
+++ b/test/Fortran/FORTRANFLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 from common import write_fake_link
@@ -99,11 +97,10 @@ if g77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(FORTRAN = '%(fc)s')
diff --git a/test/Fortran/FORTRANMODDIR.py b/test/Fortran/FORTRANMODDIR.py
index 96a341a1..3c146323 100644
--- a/test/Fortran/FORTRANMODDIR.py
+++ b/test/Fortran/FORTRANMODDIR.py
@@ -36,12 +36,11 @@ test = TestSCons.TestSCons()
 test.write('myfortran.py', r"""
 import os.path
 import re
-import string
 import sys
 mod_regex = "(?im)^\\s*MODULE\\s+(?!PROCEDURE)(\\w+)"
 contents = open(sys.argv[2]).read()
 modules = re.findall(mod_regex, contents)
-modules = map(lambda m: os.path.join(sys.argv[1], string.lower(m)+'.mod'), modules)
+modules = [os.path.join(sys.argv[1], m.lower()+'.mod') for m in modules]
 for t in sys.argv[3:] + modules:
     open(t, 'wb').write('myfortran.py wrote %s\n' % os.path.split(t)[1])
 sys.exit(0)
diff --git a/test/Fortran/SHF77.py b/test/Fortran/SHF77.py
index 9cc569ad..ff2a0ca8 100644
--- a/test/Fortran/SHF77.py
+++ b/test/Fortran/SHF77.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -98,11 +96,10 @@ if f77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF77 = '%(fc)s')
diff --git a/test/Fortran/SHF77COMSTR.py b/test/Fortran/SHF77COMSTR.py
index 9ca6631d..7a43a4af 100644
--- a/test/Fortran/SHF77COMSTR.py
+++ b/test/Fortran/SHF77COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/SHF77FLAGS.py b/test/Fortran/SHF77FLAGS.py
index f3939b62..7d55a91d 100644
--- a/test/Fortran/SHF77FLAGS.py
+++ b/test/Fortran/SHF77FLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -79,11 +77,10 @@ if g77:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF77 = '%(fc)s')
diff --git a/test/Fortran/SHF90.py b/test/Fortran/SHF90.py
index dc5f1de8..486b57b6 100644
--- a/test/Fortran/SHF90.py
+++ b/test/Fortran/SHF90.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -100,11 +98,10 @@ if g90:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF90 = '%(fc)s')
diff --git a/test/Fortran/SHF90COMSTR.py b/test/Fortran/SHF90COMSTR.py
index 61045eea..a3353fa2 100644
--- a/test/Fortran/SHF90COMSTR.py
+++ b/test/Fortran/SHF90COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/SHF90FLAGS.py b/test/Fortran/SHF90FLAGS.py
index 88ae6560..7ff3a43b 100644
--- a/test/Fortran/SHF90FLAGS.py
+++ b/test/Fortran/SHF90FLAGS.py
@@ -103,11 +103,10 @@ if g90:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF90 = '%(fc)s')
diff --git a/test/Fortran/SHF95.py b/test/Fortran/SHF95.py
index a6b1f6d1..0b649234 100644
--- a/test/Fortran/SHF95.py
+++ b/test/Fortran/SHF95.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -99,11 +97,10 @@ if g95:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF95 = '%(fc)s')
diff --git a/test/Fortran/SHF95COMSTR.py b/test/Fortran/SHF95COMSTR.py
index 01247276..5aec6b00 100644
--- a/test/Fortran/SHF95COMSTR.py
+++ b/test/Fortran/SHF95COMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/SHF95FLAGS.py b/test/Fortran/SHF95FLAGS.py
index e3d36a04..b809d22e 100644
--- a/test/Fortran/SHF95FLAGS.py
+++ b/test/Fortran/SHF95FLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -107,11 +105,10 @@ if g95:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHF95 = '%(fc)s')
diff --git a/test/Fortran/SHFORTRAN.py b/test/Fortran/SHFORTRAN.py
index 2e4bd61e..d9ae55dc 100644
--- a/test/Fortran/SHFORTRAN.py
+++ b/test/Fortran/SHFORTRAN.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -93,11 +91,10 @@ if fortran:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHFORTRAN = '%(fc)s')
diff --git a/test/Fortran/SHFORTRANCOMSTR.py b/test/Fortran/SHFORTRANCOMSTR.py
index a2cf47cb..3b801dbe 100644
--- a/test/Fortran/SHFORTRANCOMSTR.py
+++ b/test/Fortran/SHFORTRANCOMSTR.py
@@ -37,7 +37,7 @@ import sys
 fline = '#'+sys.argv[1]+'\n'
 outfile = open(sys.argv[2], 'wb')
 infile = open(sys.argv[3], 'rb')
-for l in filter(lambda l, fl=fline: l != fl, infile.readlines()):
+for l in [l for l in infile.readlines() if l != fline]:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Fortran/SHFORTRANFLAGS.py b/test/Fortran/SHFORTRANFLAGS.py
index 90f0c65a..65f6a6ce 100644
--- a/test/Fortran/SHFORTRANFLAGS.py
+++ b/test/Fortran/SHFORTRANFLAGS.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -95,11 +93,10 @@ if fortran:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(SHFORTRAN = '%(fc)s')
diff --git a/test/Fortran/USE-MODULE.py b/test/Fortran/USE-MODULE.py
index 26669926..8f537dde 100644
--- a/test/Fortran/USE-MODULE.py
+++ b/test/Fortran/USE-MODULE.py
@@ -36,12 +36,11 @@ test = TestSCons.TestSCons()
 test.write('myfortran.py', r"""
 import os.path
 import re
-import string
 import sys
 mod_regex = "(?im)^\\s*MODULE\\s+(?!PROCEDURE)(\\w+)"
 contents = open(sys.argv[1]).read()
 modules = re.findall(mod_regex, contents)
-modules = map(lambda m: string.lower(m)+'.mod', modules)
+modules = [m.lower()+'.mod' for m in modules]
 for t in sys.argv[2:] + modules:
     open(t, 'wb').write('myfortran.py wrote %s\n' % os.path.split(t)[1])
 sys.exit(0)
diff --git a/test/Fortran/common.py b/test/Fortran/common.py
index fe3f46c5..b48c83b6 100644
--- a/test/Fortran/common.py
+++ b/test/Fortran/common.py
@@ -34,7 +34,6 @@ def write_fake_link(t):
     non-compiled) tests."""
     if sys.platform == 'win32':
         t.write('mylink.py', r"""
-import string
 import sys
 args = sys.argv[1:]
 while args:
@@ -42,7 +41,7 @@ while args:
     if a[0] != '/':
         break
     args = args[1:]
-    if string.lower(a[:5]) == '/out:': out = a[5:]
+    if a[:5].lower() == '/out:': out = a[5:]
 infile = open(args[0], 'rb')
 outfile = open(out, 'wb')
 for l in infile.readlines():
diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py
index d3a9f77a..a240d1ef 100644
--- a/test/GetBuildFailures/serial.py
+++ b/test/GetBuildFailures/serial.py
@@ -89,14 +89,13 @@ Command('f15', 'f15.in', returnExcAction(SCons.Errors.InternalError("My Internal
 
 def print_build_failures():
     from SCons.Script import GetBuildFailures
-    import string
     bf_list = GetBuildFailures()
     bf_list.sort(lambda a,b: cmp(str(a.node), str(b.node)))
     for bf in bf_list:
         assert( isinstance(bf, SCons.Errors.BuildError) )
         print "BF: %%s failed (%%s):  %%s" %% (bf.node, bf.status, bf.errstr)
         if bf.command:
-            print "BF:    %%s" %% string.join(Flatten(bf.command))
+            print "BF:    %%s" %% " ".join(Flatten(bf.command))
 
 try:
     import atexit
diff --git a/test/GetOption/help.py b/test/GetOption/help.py
index f20704e0..e2eeef7e 100644
--- a/test/GetOption/help.py
+++ b/test/GetOption/help.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test use of GetOption('help') to short-circuit work.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -46,10 +44,10 @@ test.run(arguments = '-q -Q', stdout = "no help for you\n")
 expect = "GetOption('help') set"
 
 test.run(arguments = '-q -Q -h')
-test.fail_test(string.split(test.stdout(), '\n')[0] != expect)
+test.fail_test(test.stdout().split('\n')[0] != expect)
 
 test.run(arguments = '-q -Q --help')
-test.fail_test(string.split(test.stdout(), '\n')[0] != expect)
+test.fail_test(test.stdout().split('\n')[0] != expect)
 
 test.pass_test()
 
diff --git a/test/Ghostscript/GS.py b/test/Ghostscript/GS.py
index c2e5dd73..2cae8b8d 100644
--- a/test/Ghostscript/GS.py
+++ b/test/Ghostscript/GS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -76,12 +75,11 @@ if gs:
 
     test.write("wrapper.py", """\
 import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """\
 import os
diff --git a/test/Ghostscript/GSCOM.py b/test/Ghostscript/GSCOM.py
index b43bc199..c86f8b61 100644
--- a/test/Ghostscript/GSCOM.py
+++ b/test/Ghostscript/GSCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*gs*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*gs*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Ghostscript/GSCOMSTR.py b/test/Ghostscript/GSCOMSTR.py
index acd1132b..b39cf4f6 100644
--- a/test/Ghostscript/GSCOMSTR.py
+++ b/test/Ghostscript/GSCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*gs*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*gs*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Ghostscript/GSFLAGS.py b/test/Ghostscript/GSFLAGS.py
index 057977e6..16ad6c1e 100644
--- a/test/Ghostscript/GSFLAGS.py
+++ b/test/Ghostscript/GSFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -84,12 +83,11 @@ gs = test.where_is(gs_executable)
 if gs:
 
     test.write("wrapper.py", """import os
-import string
 import sys
-cmd = string.join(sys.argv[1:], " ")
+cmd = " ".join(sys.argv[1:])
 open('%s', 'ab').write("%%s\\n" %% cmd)
 os.system(cmd)
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """\
 import os
diff --git a/test/Glob/Repository.py b/test/Glob/Repository.py
index 2b0a5bb1..5783443a 100644
--- a/test/Glob/Repository.py
+++ b/test/Glob/Repository.py
@@ -49,10 +49,9 @@ opts = "-Y " + test.workpath('repository')
 test.write(['repository', 'SConstruct'], """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 # Verify that we can glob a repository-only Node that exists
diff --git a/test/IDL/MIDLCOM.py b/test/IDL/MIDLCOM.py
index 9005d6b9..05255923 100644
--- a/test/IDL/MIDLCOM.py
+++ b/test/IDL/MIDLCOM.py
@@ -45,7 +45,7 @@ out_h = open(base + '.h', 'wb')
 out_c = open(base + '_i.c', 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*midl*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*midl*/\\n']:
         out_tlb.write(l)
         out_h.write(l)
         out_c.write(l)
diff --git a/test/IDL/MIDLCOMSTR.py b/test/IDL/MIDLCOMSTR.py
index 472526ad..56f8c400 100644
--- a/test/IDL/MIDLCOMSTR.py
+++ b/test/IDL/MIDLCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*midl*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*midl*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Install/Install.py b/test/Install/Install.py
index ac843984..29a8276b 100644
--- a/test/Install/Install.py
+++ b/test/Install/Install.py
@@ -29,7 +29,6 @@ Verify that the Install() Builder works
 """
 
 import os.path
-import string
 import time
 
 import TestSCons
@@ -44,17 +43,16 @@ f3_out = test.workpath('work', 'export', 'f3.out')
 f4_out = test.workpath('work', 'export', 'f4.out')
 f5_txt = test.workpath('outside', 'f5.txt')
 f6_txt = test.workpath('outside', 'f6.txt')
-f6_sep = string.replace(f6_txt, os.sep, '/')
+f6_sep = f6_txt.replace(os.sep, '/')
 
 _SUBDIR_f4_out = os.path.join('$SUBDIR', 'f4.out')
 
 test.write(['work', 'SConstruct'], """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 def my_install(dest, source, env):
diff --git a/test/Install/wrap-by-attribute.py b/test/Install/wrap-by-attribute.py
index e36d11db..912551e2 100644
--- a/test/Install/wrap-by-attribute.py
+++ b/test/Install/wrap-by-attribute.py
@@ -46,10 +46,9 @@ import os.path
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(DESTDIR='dest')
diff --git a/test/Interactive/implicit-VariantDir.py b/test/Interactive/implicit-VariantDir.py
index 8975e900..5ef4583d 100644
--- a/test/Interactive/implicit-VariantDir.py
+++ b/test/Interactive/implicit-VariantDir.py
@@ -37,7 +37,6 @@ deps must be cleared on the source files.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -94,7 +93,7 @@ test.write(['src', 'inc', 'foo.h'], """
 
 # Start scons, to build only "build/foo"
 build_foo_exe   = os.path.join('build', 'foo' + TestSCons._exe)
-_build_foo_exe_ = '"%s"' % string.replace(build_foo_exe, '\\', '\\\\')
+_build_foo_exe_ = '"%s"' % build_foo_exe.replace('\\', '\\\\')
 abs_foo_exe     = test.workpath(build_foo_exe)
 
 scons = test.start(arguments = '--interactive', combine=1)
diff --git a/test/Interactive/shell.py b/test/Interactive/shell.py
index 4e4907a0..f4e89bd9 100644
--- a/test/Interactive/shell.py
+++ b/test/Interactive/shell.py
@@ -28,7 +28,6 @@ Verify the ability of the "shell" command (and its "sh" and "!" aliases)
 to shell out of interactive mode.
 """
 
-import string
 import sys
 
 import TestSCons
@@ -38,7 +37,7 @@ test = TestSCons.TestSCons(combine=1)
 _python_ = TestSCons._python_
 
 shell_command_py    = test.workpath('shell_command.py')
-_shell_command_py_  = '"%s"' % string.replace(shell_command_py, '\\', '\\\\')
+_shell_command_py_  = '"%s"' % shell_command_py.replace('\\', '\\\\')
 
 test.write(shell_command_py, """\
 print 'hello from shell_command.py'
diff --git a/test/Java/JAR.py b/test/Java/JAR.py
index b0b193e9..81664dc7 100644
--- a/test/Java/JAR.py
+++ b/test/Java/JAR.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -89,9 +88,8 @@ line 3
 
 test.write('myjar2.py', r"""
 import sys
-import string
 f=open(sys.argv[2], 'wb')
-f.write(string.join(sys.argv[1:]))
+f.write(" ".join(sys.argv[1:]))
 f.write("\n")
 f.close()
 sys.exit(0)
@@ -128,11 +126,10 @@ where_jar = test.java_where_jar()
 
 test.write("wrapper.py", """\
 import os
-import string
 import sys
-open('%s', 'ab').write("wrapper.py %%s\\n" %% string.join(sys.argv[1:]))
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+open('%s', 'ab').write("wrapper.py %%s\\n" %% " ".join(sys.argv[1:]))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(tools = ['javac', 'jar'],
@@ -238,7 +235,7 @@ public class Example6
 test.run(arguments = '.')
 
 expected_wrapper_out = "wrapper.py %(where_jar)s cf bar.jar classes/com/sub/bar\n"
-expected_wrapper_out = string.replace(expected_wrapper_out, '/', os.sep)
+expected_wrapper_out = expected_wrapper_out.replace('/', os.sep)
 test.must_match('wrapper.out',
                 expected_wrapper_out % locals())
 
diff --git a/test/Java/JARCHDIR.py b/test/Java/JARCHDIR.py
index e3f22db8..d574fe74 100644
--- a/test/Java/JARCHDIR.py
+++ b/test/Java/JARCHDIR.py
@@ -34,7 +34,6 @@ ${TARGET} or ${SOURCE} work.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -100,7 +99,7 @@ test.write(['in', 's.class'], "s.class\n")
 # env.subst() in the code that handle jar).
 
 p = test.workpath('out')
-for d in string.split(test.workpath('in'), os.sep):
+for d in test.workpath('in').split(os.sep):
     p = p + d
     test.subdir(p)
     p = p + os.sep
diff --git a/test/Java/JARCOM.py b/test/Java/JARCOM.py
index a51ea5a6..9d93ba58 100644
--- a/test/Java/JARCOM.py
+++ b/test/Java/JARCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*jar*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*jar*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/JARCOMSTR.py b/test/Java/JARCOMSTR.py
index 4358f6b5..069587fe 100644
--- a/test/Java/JARCOMSTR.py
+++ b/test/Java/JARCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*jar*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*jar*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/JARFLAGS.py b/test/Java/JARFLAGS.py
index 73064267..c0ae6274 100644
--- a/test/Java/JARFLAGS.py
+++ b/test/Java/JARFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -69,7 +68,7 @@ expect = test.wrap_stdout("""\
 adding: src/Example1\.class.*
 """ % locals())
 
-expect = string.replace(expect, '/', os.sep)
+expect = expect.replace('/', os.sep)
 
 test.run(arguments = '.',
          match=TestSCons.match_re_dotall,
diff --git a/test/Java/JAVABOOTCLASSPATH.py b/test/Java/JAVABOOTCLASSPATH.py
index e448165a..6913c6ae 100644
--- a/test/Java/JAVABOOTCLASSPATH.py
+++ b/test/Java/JAVABOOTCLASSPATH.py
@@ -30,7 +30,6 @@ on javac compilations.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -83,7 +82,7 @@ public class Example2
 # we'll just take the easy way out and examine the -n output to see if
 # the expected option shows up on the command line.
 
-bootclasspath = string.join(['dir1', 'dir2'], os.pathsep)
+bootclasspath = os.pathsep.join(['dir1', 'dir2'])
 
 expect = """\
 %(where_javac)s -bootclasspath %(bootclasspath)s -d class -sourcepath com com/Example1.java
diff --git a/test/Java/JAVACCOM.py b/test/Java/JAVACCOM.py
index c4eaa928..064feed0 100644
--- a/test/Java/JAVACCOM.py
+++ b/test/Java/JAVACCOM.py
@@ -43,7 +43,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*javac*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*javac*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/JAVACCOMSTR.py b/test/Java/JAVACCOMSTR.py
index 23e7dfbd..64402830 100644
--- a/test/Java/JAVACCOMSTR.py
+++ b/test/Java/JAVACCOMSTR.py
@@ -46,7 +46,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*javac*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*javac*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/JAVACFLAGS.py b/test/Java/JAVACFLAGS.py
index d86c267c..6afd1b97 100644
--- a/test/Java/JAVACFLAGS.py
+++ b/test/Java/JAVACFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -57,7 +56,7 @@ public class Example1
 """)
 
 expected_wrapper_out = "%(where_javac)s -O -d classes -sourcepath src src/Example1.java\n"
-expected_wrapper_out = string.replace(expected_wrapper_out, '/', os.sep)
+expected_wrapper_out = expected_wrapper_out.replace('/', os.sep)
 test.run(arguments = '.',
          stdout = test.wrap_stdout(expected_wrapper_out % locals()))
 
diff --git a/test/Java/JAVAH.py b/test/Java/JAVAH.py
index 2518928b..f7c9dcc0 100644
--- a/test/Java/JAVAH.py
+++ b/test/Java/JAVAH.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -105,11 +104,10 @@ if java_version:
 
 test.write("wrapper.py", """\
 import os
-import string
 import sys
-open('%s', 'ab').write("wrapper.py %%s\\n" %% string.join(sys.argv[1:]))
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+open('%s', 'ab').write("wrapper.py %%s\\n" %% " ".join(sys.argv[1:]))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(tools = ['javac', 'javah', 'install'],
diff --git a/test/Java/JAVAHCOM.py b/test/Java/JAVAHCOM.py
index 10303801..9db897a8 100644
--- a/test/Java/JAVAHCOM.py
+++ b/test/Java/JAVAHCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*javah*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*javah*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/JAVAHCOMSTR.py b/test/Java/JAVAHCOMSTR.py
index f3185240..f8120d65 100644
--- a/test/Java/JAVAHCOMSTR.py
+++ b/test/Java/JAVAHCOMSTR.py
@@ -52,7 +52,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*javah*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*javah*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/Java-1.4.py b/test/Java/Java-1.4.py
index f0f5a93f..9cc1d96a 100644
--- a/test/Java/Java-1.4.py
+++ b/test/Java/Java-1.4.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -361,7 +362,7 @@ def classes_must_match(dir, expect):
 
 def classes_must_not_exist(dir, expect):
     global failed
-    present = filter(os.path.exists, expect)
+    present = list(filter(os.path.exists, expect))
     if present:
         sys.stderr.write("Found the following unexpected class files in '%s' after cleaning:\n" % dir)
         for c in present:
diff --git a/test/Java/Java-1.5.py b/test/Java/Java-1.5.py
index e769c222..ca9cbceb 100644
--- a/test/Java/Java-1.5.py
+++ b/test/Java/Java-1.5.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -357,7 +358,7 @@ def classes_must_match(dir, expect):
 
 def classes_must_not_exist(dir, expect):
     global failed
-    present = filter(os.path.exists, expect)
+    present = list(filter(os.path.exists, expect))
     if present:
         sys.stderr.write("Found the following unexpected class files in '%s' after cleaning:\n" % dir)
         for c in present:
diff --git a/test/Java/Java-1.6.py b/test/Java/Java-1.6.py
index d107e321..ec6df54d 100644
--- a/test/Java/Java-1.6.py
+++ b/test/Java/Java-1.6.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -357,7 +358,7 @@ def classes_must_match(dir, expect):
 
 def classes_must_not_exist(dir, expect):
     global failed
-    present = filter(os.path.exists, expect)
+    present = list(filter(os.path.exists, expect))
     if present:
         sys.stderr.write("Found the following unexpected class files in '%s' after cleaning:\n" % dir)
         for c in present:
diff --git a/test/Java/RMIC.py b/test/Java/RMIC.py
index f08186e1..f88dd147 100644
--- a/test/Java/RMIC.py
+++ b/test/Java/RMIC.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -97,14 +96,12 @@ where_rmic = test.java_where_rmic()
 
 test.write("wrapper.py", """\
 import os
-import string
 import sys
-open('%s', 'ab').write("wrapper.py %%s\\n" %% string.join(sys.argv[1:]))
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+open('%s', 'ab').write("wrapper.py %%s\\n" %% " ".join(sys.argv[1:]))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
-import string
 foo = Environment(tools = ['javac', 'rmic'],
                   JAVAC = r'%(where_javac)s',
                   RMIC = r'%(where_rmic)s')
@@ -120,7 +117,7 @@ bar_classes = bar.Java(target = 'class2', source = 'com/sub/bar')
 # XXX This is kind of a Python brute-force way to do what Ant
 # does with its "excludes" attribute.  We should probably find
 # a similar friendlier way to do this.
-bar_classes = filter(lambda c: string.find(str(c), 'Hello') == -1, bar_classes)
+bar_classes = [c for c in bar_classes if str(c).find('Hello') == -1]
 bar.RMIC(target = Dir('outdir2'), source = bar_classes)
 """ % locals() )
 
diff --git a/test/Java/RMICCOM.py b/test/Java/RMICCOM.py
index 6bc50da4..ba7f965d 100644
--- a/test/Java/RMICCOM.py
+++ b/test/Java/RMICCOM.py
@@ -51,7 +51,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rmic*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rmic*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Java/RMICCOMSTR.py b/test/Java/RMICCOMSTR.py
index 8981ed7e..8fe535aa 100644
--- a/test/Java/RMICCOMSTR.py
+++ b/test/Java/RMICCOMSTR.py
@@ -52,7 +52,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rmic*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rmic*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LEX/LEX.py b/test/LEX/LEX.py
index 0ead71ac..975d4e9c 100644
--- a/test/LEX/LEX.py
+++ b/test/LEX/LEX.py
@@ -37,12 +37,11 @@ test = TestSCons.TestSCons()
 
 test.write('mylex.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 't', [])
 for a in args:
     contents = open(a, 'rb').read()
-    sys.stdout.write(string.replace(contents, 'LEX', 'mylex.py'))
+    sys.stdout.write(contents.replace('LEX', 'mylex.py'))
 sys.exit(0)
 """)
 
diff --git a/test/LEX/LEXCOM.py b/test/LEX/LEXCOM.py
index f496f951..5fb82fed 100644
--- a/test/LEX/LEXCOM.py
+++ b/test/LEX/LEXCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*lex*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*lex*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LEX/LEXCOMSTR.py b/test/LEX/LEXCOMSTR.py
index fa0bbf19..83b2f9c0 100644
--- a/test/LEX/LEXCOMSTR.py
+++ b/test/LEX/LEXCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*lex*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*lex*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LEX/LEXFLAGS.py b/test/LEX/LEXFLAGS.py
index aaabdf04..82ae5865 100644
--- a/test/LEX/LEXFLAGS.py
+++ b/test/LEX/LEXFLAGS.py
@@ -39,7 +39,6 @@ test.subdir('in')
 
 test.write('mylex.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'I:tx', [])
 opt_string = ''
@@ -49,8 +48,8 @@ for opt, arg in cmd_opts:
     else: opt_string = opt_string + ' ' + opt
 for a in args:
     contents = open(a, 'rb').read()
-    contents = string.replace(contents, 'LEXFLAGS', opt_string)
-    contents = string.replace(contents, 'I_ARGS', i_arguments)
+    contents = contents.replace('LEXFLAGS', opt_string)
+    contents = contents.replace('I_ARGS', i_arguments)
     sys.stdout.write(contents)
 sys.exit(0)
 """)
diff --git a/test/LEX/live.py b/test/LEX/live.py
index da511753..f50b06f3 100644
--- a/test/LEX/live.py
+++ b/test/LEX/live.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test LEX and LEXFLAGS with a live lex.
 """
 
-import string
-
 import TestSCons
 
 _exe = TestSCons._exe
@@ -45,11 +43,10 @@ if not lex:
 
 
 test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/LINK/LINK.py b/test/LINK/LINK.py
index 21e2d66c..25d9efb8 100644
--- a/test/LINK/LINK.py
+++ b/test/LINK/LINK.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -36,11 +35,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/LINK/LINKCOM.py b/test/LINK/LINKCOM.py
index b3c56d64..f09e8f87 100644
--- a/test/LINK/LINKCOM.py
+++ b/test/LINK/LINKCOM.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*link*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*link*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LINK/LINKCOMSTR.py b/test/LINK/LINKCOMSTR.py
index 7e12c1df..113bdcdc 100644
--- a/test/LINK/LINKCOMSTR.py
+++ b/test/LINK/LINKCOMSTR.py
@@ -29,8 +29,6 @@ Test that the $LINKCOMSTR construction variable allows you to customize
 the displayed linker string.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -45,7 +43,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*link*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*link*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LINK/LINKFLAGS.py b/test/LINK/LINKFLAGS.py
index 17267090..442baf72 100644
--- a/test/LINK/LINKFLAGS.py
+++ b/test/LINK/LINKFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -36,12 +35,11 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-args = filter(lambda s: s != 'fake_link_flag', sys.argv[1:])
-os.system(string.join(args, " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+args = [s for s in sys.argv[1:] if s != 'fake_link_flag']
+os.system(" ".join(args))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/LINK/SHLINK.py b/test/LINK/SHLINK.py
index 2bd9bd61..bc1239bd 100644
--- a/test/LINK/SHLINK.py
+++ b/test/LINK/SHLINK.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -37,11 +36,10 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/LINK/SHLINKCOM.py b/test/LINK/SHLINKCOM.py
index c507d316..8bdb9b53 100644
--- a/test/LINK/SHLINKCOM.py
+++ b/test/LINK/SHLINKCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*cc*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*cc*/\n']:
         outfile.write(l)
 sys.exit(0)
 
@@ -51,7 +51,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*link*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*link*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LINK/SHLINKCOMSTR.py b/test/LINK/SHLINKCOMSTR.py
index 1d93b75f..dd6f22b4 100644
--- a/test/LINK/SHLINKCOMSTR.py
+++ b/test/LINK/SHLINKCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*cc*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*cc*/\n']:
         outfile.write(l)
 sys.exit(0)
 
@@ -52,7 +52,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*link*/\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*link*/\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/LINK/SHLINKFLAGS.py b/test/LINK/SHLINKFLAGS.py
index ddd1a6c4..57766de9 100644
--- a/test/LINK/SHLINKFLAGS.py
+++ b/test/LINK/SHLINKFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -37,12 +36,11 @@ test = TestSCons.TestSCons()
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-args = filter(lambda s: s != 'fake_shlink_flag', sys.argv[1:])
-os.system(string.join(args, " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+args = [s for s in sys.argv[1:] if s != 'fake_shlink_flag']
+os.system(" ".join(args))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment()
diff --git a/test/Libs/SharedLibrary.py b/test/Libs/SharedLibrary.py
index 1bb91ead..18d1f245 100644
--- a/test/Libs/SharedLibrary.py
+++ b/test/Libs/SharedLibrary.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -202,13 +201,13 @@ test.run(arguments = '.',
 
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') != -1:
+if sys.platform.find('irix') != -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test.run(program = test.workpath('prog'),
          stdout = "f1.c\nf2a.c\nf2b.c\nf2c.c\nf3a.c\nf3b.c\nf3c.c\nprog.c\n")
 
-if sys.platform == 'win32' or string.find(sys.platform, 'irix') != -1:
+if sys.platform == 'win32' or sys.platform.find('irix') != -1:
     test.run(arguments = '-f SConstructFoo')
 else:
     test.run(arguments = '-f SConstructFoo', status=2, stderr='''\
@@ -274,9 +273,9 @@ main(int argc, char *argv[])
 
     # Make sure there is (at most) one mention each of the
     # appropriate .def and .lib files per line.
-    for line in string.split(test.stdout(), '\n'):
-        test.fail_test(string.count(line, 'foo4.def') > 1)
-        test.fail_test(string.count(line, 'foo4.lib') > 1)
+    for line in test.stdout().split('\n'):
+        test.fail_test(line.count('foo4.def') > 1)
+        test.fail_test(line.count('foo4.lib') > 1)
 
     test.run(program = test.workpath('progbar'),
              stdout = "f4.c\nprogbar.c\n")
diff --git a/test/Libs/SharedLibraryIxes.py b/test/Libs/SharedLibraryIxes.py
index fb0bc22e..c60165ac 100644
--- a/test/Libs/SharedLibraryIxes.py
+++ b/test/Libs/SharedLibraryIxes.py
@@ -46,7 +46,7 @@ env.Append(LIBPATH=['.'])
 
 # We first bake the LIBSUFFIXES, so that it will not change as a
 # side-effect of changing SHLIBSUFFIX.
-env['LIBSUFFIXES'] = map( env.subst, env.get('LIBSUFFIXES', []))
+env['LIBSUFFIXES'] = list(map( env.subst, env.get('LIBSUFFIXES', [])))
 
 weird_prefixes = ['libXX', 'libYY']
 
@@ -76,13 +76,13 @@ def nodeInSrc(source, lib, libname):
     return (source+lib, '')
 
 def pathInSrc(source, lib, libname):
-    return (source+map(str,lib), '')
+    return (source+list(map(str,lib)), '')
 
 def nodeInLib(source, lib, libname):
     return (source, lib)
 
 def pathInLib(source, lib, libname):
-    return (source, map(str,lib))
+    return (source, list(map(str,lib)))
 
 def nameInLib(source, lib, libname):
     # NOTE: libname must contain both the proper prefix and suffix.
@@ -116,7 +116,7 @@ def buildAndlinkAgainst(builder, target, source,  method, lib, libname, **kw):
     kw['target'] = target
     kw['source'] = source
     kw['LIBS'] = LIBS
-    build = apply(builder, (), kw)
+    build = builder(**kw)
 
     # Check that the build target depends on at least one of the
     # library target.
@@ -128,7 +128,7 @@ def buildAndlinkAgainst(builder, target, source,  method, lib, libname, **kw):
             break;
     assert found_dep, \
         "One of %s not found in %s, method=%s, libname=%s, shlibsuffix=%s" % \
-        (map(str,lib), map(str, build[0].children()), method.__name__, libname, shlibsuffix)
+        (list(map(str,lib)), list(map(str, build[0].children())), method.__name__, libname, shlibsuffix)
     return build
 
 def prog(i, 
@@ -194,7 +194,7 @@ except AttributeError:
     pass
 
 for i in range(200):
-  apply(prog, tests[i])
+  prog(*tests[i])
 
 """)
 
diff --git a/test/LoadableModule.py b/test/LoadableModule.py
index 4c69dc00..61093592 100644
--- a/test/LoadableModule.py
+++ b/test/LoadableModule.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestCmd
@@ -97,13 +96,13 @@ main(int argc, char *argv[])
 foo1_name = {'darwin' : 'foo1'}.get(sys.platform[:6], dll_+'foo1'+_dll)
 
 test.write('dlopenprog.c',
-           string.replace(dlopenprog, '__foo1_name__', foo1_name))
+           dlopenprog.replace('__foo1_name__', foo1_name))
 
 test.run(arguments = '.',
          stderr=TestSCons.noisy_ar,
          match=TestSCons.match_re_dotall)
 
-if string.find(sys.platform, 'darwin') != -1:
+if sys.platform.find('darwin') != -1:
     test.run(program='/usr/bin/file',
              arguments = "foo1",
              match = TestCmd.match_re,
diff --git a/test/M4/M4.py b/test/M4/M4.py
index 44cda7c6..6c2de9cc 100644
--- a/test/M4/M4.py
+++ b/test/M4/M4.py
@@ -29,7 +29,6 @@ Test that $M4 and $M4FLAGS work as expected.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -40,10 +39,9 @@ test = TestSCons.TestSCons()
 
 
 test.write('mym4.py', """
-import string
 import sys
 contents = sys.stdin.read()
-sys.stdout.write(string.replace(contents, 'M4', 'mym4.py'))
+sys.stdout.write(contents.replace('M4', 'mym4.py'))
 sys.exit(0)
 """)
 
@@ -71,11 +69,10 @@ if m4:
 
     test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment(tools=['default', 'm4'],
diff --git a/test/M4/M4COM.py b/test/M4/M4COM.py
index 92996457..ad151729 100644
--- a/test/M4/M4COM.py
+++ b/test/M4/M4COM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*m4*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*m4*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/M4/M4COMSTR.py b/test/M4/M4COMSTR.py
index 1425f5cb..1b5bd353 100644
--- a/test/M4/M4COMSTR.py
+++ b/test/M4/M4COMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*m4*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*m4*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MSVC/PCHCOM.py b/test/MSVC/PCHCOM.py
index 56718ef1..ff27e10e 100644
--- a/test/MSVC/PCHCOM.py
+++ b/test/MSVC/PCHCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*pch*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*pch*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MSVC/PCHCOMSTR.py b/test/MSVC/PCHCOMSTR.py
index a3ee99e1..51f56fb1 100644
--- a/test/MSVC/PCHCOMSTR.py
+++ b/test/MSVC/PCHCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*pch*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*pch*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MSVC/RCCOM.py b/test/MSVC/RCCOM.py
index babc4c7d..05382b86 100644
--- a/test/MSVC/RCCOM.py
+++ b/test/MSVC/RCCOM.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MSVC/RCCOMSTR.py b/test/MSVC/RCCOMSTR.py
index b346f489..8425d73e 100644
--- a/test/MSVC/RCCOMSTR.py
+++ b/test/MSVC/RCCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MSVC/batch.py b/test/MSVC/batch.py
index 0ab116c7..f089b605 100644
--- a/test/MSVC/batch.py
+++ b/test/MSVC/batch.py
@@ -40,7 +40,6 @@ _python_ = TestSCons._python_
 
 test.write('fake_cl.py', """\
 import os
-import string
 import sys
 input_files = sys.argv[2:]
 if sys.argv[1][-1] in (os.sep, '\\\\'):
@@ -56,17 +55,16 @@ else:
 # Delay writing the .log output until here so any trailing slash or
 # backslash has been stripped, and the output comparisons later in this
 # script don't have to account for the difference.
-open('fake_cl.log', 'ab').write(string.join(sys.argv[1:]) + '\\n')
+open('fake_cl.log', 'ab').write(" ".join(sys.argv[1:]) + '\\n')
 for infile in input_files:
     if dir:
-        outfile = os.path.join(dir, string.replace(infile, '.c', '.obj'))
+        outfile = os.path.join(dir, infile.replace('.c', '.obj'))
     else:
         outfile = output
     open(outfile, 'wb').write(open(infile, 'rb').read())
 """)
 
 test.write('fake_link.py', """\
-import string
 import sys
 ofp = open(sys.argv[1], 'wb')
 for infile in sys.argv[2:]:
diff --git a/test/MSVS/vs-8.0-x64-files.py b/test/MSVS/vs-8.0-x64-files.py
index b2a310df..53f8d151 100644
--- a/test/MSVS/vs-8.0-x64-files.py
+++ b/test/MSVS/vs-8.0-x64-files.py
@@ -30,7 +30,6 @@ solution (.sln) files that look correct.
 """
 
 import os
-import string
 
 import TestSConsMSVS
 
@@ -48,9 +47,9 @@ SConscript_contents = TestSConsMSVS.SConscript_contents_8_0
 # We didn't create an API for putting parameters like this into
 # the common generated and expected files.  Until we do, just patch
 # in the values.
-expected_slnfile = string.replace(expected_slnfile, 'Win32', 'x64')
-expected_vcprojfile = string.replace(expected_vcprojfile, 'Win32', 'x64')
-SConscript_contents = string.replace(SConscript_contents, '\'Release\'', '\'Release|x64\'')
+expected_slnfile = expected_slnfile.replace('Win32', 'x64')
+expected_vcprojfile = expected_vcprojfile.replace('Win32', 'x64')
+SConscript_contents = SConscript_contents.replace('\'Release\'', '\'Release|x64\'')
 
 
 
diff --git a/test/MinGW/RCCOM.py b/test/MinGW/RCCOM.py
index 45683ddc..dadfea5a 100644
--- a/test/MinGW/RCCOM.py
+++ b/test/MinGW/RCCOM.py
@@ -44,7 +44,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/MinGW/RCCOMSTR.py b/test/MinGW/RCCOMSTR.py
index 67957959..501a57db 100644
--- a/test/MinGW/RCCOMSTR.py
+++ b/test/MinGW/RCCOMSTR.py
@@ -44,7 +44,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*rc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*rc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/Mkdir.py b/test/Mkdir.py
index f79a32af..094e6ed7 100644
--- a/test/Mkdir.py
+++ b/test/Mkdir.py
@@ -41,10 +41,9 @@ Execute(Mkdir('d1'))
 Execute(Mkdir(Dir('#d1-Dir')))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
@@ -127,13 +126,13 @@ test.write(['work2', 'SConstruct'], """\
 import os
 def catdir(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     outfp = open(target, "wb")
     for src in source:
-        l = os.listdir(src)
+        s = str(src)
+        l = os.listdir(s)
         l.sort()
         for f in l:
-            f = os.path.join(src, f)
+            f = os.path.join(s, f)
             if os.path.isfile(f):
                 outfp.write(open(f, "rb").read())
     outfp.close()
diff --git a/test/Move.py b/test/Move.py
index d83a5cdf..b58fa34b 100644
--- a/test/Move.py
+++ b/test/Move.py
@@ -37,10 +37,9 @@ Execute(Move('f1.out', 'f1.in'))
 Execute(Move('File-f1.out', File('f1.in-File')))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
diff --git a/test/NodeOps.py b/test/NodeOps.py
index 96e9f12e..e4a403f9 100644
--- a/test/NodeOps.py
+++ b/test/NodeOps.py
@@ -36,7 +36,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import sys
 import TestSCons
 import os
-import string
 
 _exe = TestSCons._exe
 lib_ = TestSCons.lib_
@@ -47,7 +46,7 @@ _dll = TestSCons._dll
     
 if os.name == 'posix':
     os.environ['LD_LIBRARY_PATH'] = '.'
-if string.find(sys.platform, 'irix') > -1:
+if sys.platform.find('irix') > -1:
     os.environ['LD_LIBRARYN32_PATH'] = '.'
 
 test = TestSCons.TestSCons()
@@ -67,10 +66,10 @@ Nodes.extend(bar.SharedObject(target = 'bar%(_obj)s', source = 'prog.cpp'))
 SConscript('bld/SConscript', ['Nodes'])
 if %(_E)s:
   import os
-  derived = map(lambda N: N.is_derived(), Nodes)
-  real1 = map(lambda N: os.path.exists(str(N)), Nodes)
-  exists = map(lambda N: N.exists(), Nodes)
-  real2 = map(lambda N: os.path.exists(str(N)), Nodes)
+  derived = [N.is_derived() for N in Nodes]
+  real1 = [os.path.exists(str(N)) for N in Nodes]
+  exists = [N.exists() for N in Nodes]
+  real2 = [os.path.exists(str(N)) for N in Nodes]
   for N,D,R,E,F in map(None, Nodes, derived, real1, exists, real2):
     print '%%s: %%s %%s %%s %%s'%%(N,D,R,E,F)
 foo.SharedLibrary(target = 'foo', source = 'foo%(_obj)s')
diff --git a/test/Parallel/ref_count.py b/test/Parallel/ref_count.py
index 1eab1736..ce59668c 100644
--- a/test/Parallel/ref_count.py
+++ b/test/Parallel/ref_count.py
@@ -59,7 +59,6 @@ _python_ = TestSCons._python_
 test = TestSCons.TestSCons()
 
 test.write('build.py', """\
-import string
 import sys
 import time
 args = sys.argv[1:]
@@ -78,7 +77,7 @@ for ifile in args:
     contents = contents + open(ifile, 'rb').read()
 for ofile in outputs:
     ofp = open(ofile, 'wb')
-    ofp.write('%s:  building from %s\\n' % (ofile, string.join(args)))
+    ofp.write('%s:  building from %s\\n' % (ofile, " ".join(args)))
     ofp.write(contents)
     ofp.close()
 """)
diff --git a/test/ParseConfig.py b/test/ParseConfig.py
index 6473458a..9bcc440f 100644
--- a/test/ParseConfig.py
+++ b/test/ParseConfig.py
@@ -58,7 +58,7 @@ env.ParseConfig([r'%(_python_)s', r"%(test_config1)s", "--libs --cflags"])
 env.ParseConfig([r'%(_python_)s', r"%(test_config2)s", "--libs --cflags"])
 print env['CPPPATH']
 print env['LIBPATH']
-print map(lambda x: str(x), env['LIBS'])
+print [str(x) for x in env['LIBS']]
 print env['CCFLAGS']
 """ % locals())
 
@@ -70,7 +70,7 @@ env.ParseConfig(r"$PYTHON %(test_config1)s --libs --cflags")
 env.ParseConfig(r"$PYTHON %(test_config2)s --libs --cflags")
 print env['CPPPATH']
 print env['LIBPATH']
-print map(lambda x: str(x), env['LIBS'])
+print [str(x) for x in env['LIBS']]
 print env['CCFLAGS']
 """ % locals())
 
@@ -81,7 +81,7 @@ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [],
 env.ParseConfig(r"$PYTHON %(test_config3)s --libs --cflags")
 print env['CPPPATH']
 print env['LIBPATH']
-print map(lambda x: str(x), env['LIBS'])
+print [str(x) for x in env['LIBS']]
 print env['CCFLAGS']
 """ % locals())
 
diff --git a/test/Perforce/P4COM.py b/test/Perforce/P4COM.py
index 5a907750..5fd5fd2b 100644
--- a/test/Perforce/P4COM.py
+++ b/test/Perforce/P4COM.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'Perforce'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/Perforce/P4COMSTR.py b/test/Perforce/P4COMSTR.py
index a8675f29..accf6d5b 100644
--- a/test/Perforce/P4COMSTR.py
+++ b/test/Perforce/P4COMSTR.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'Perforce'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/Perforce/Perforce.py b/test/Perforce/Perforce.py
index ee4b0b5e..32154dbb 100644
--- a/test/Perforce/Perforce.py
+++ b/test/Perforce/Perforce.py
@@ -32,13 +32,12 @@ on port 1666, as well as that of course a client must be present.
 """
 
 import os
-import string
 
 import TestSCons
 
 class TestPerforce(TestSCons.TestSCons):
     def __init__(self, *args, **kw):
-        apply(TestSCons.TestSCons.__init__, (self,)+args, kw)
+        TestSCons.TestSCons.__init__(self, *args, **kw)
 
         self.p4d = None
 
@@ -66,11 +65,11 @@ class TestPerforce(TestSCons.TestSCons):
                 if ' ' in a:
                     a = '"%s"' % a
                 return a
-            args = map(quote_space, [self.p4d, '-q', '-d'] + \
+            args = list(map(quote_space, [self.p4d, '-q', '-d'] + \
                                     self.p4portflags + \
                                     ['-J', 'Journal',
                                      '-L', 'Log',
-                                     '-r', self.workpath('depot')])
+                                     '-r', self.workpath('depot')]))
 
             # We don't use self.run() because the TestCmd logic will hang
             # waiting for the daemon to exit, even when we pass it
@@ -78,7 +77,7 @@ class TestPerforce(TestSCons.TestSCons):
             try:
                 spawnv = os.spawnv
             except AttributeError:
-                os.system(string.join(args))
+                os.system(' '.join(args))
             else:
                 spawnv(os.P_NOWAIT, self.p4d, args)
                 self.sleep(2)
@@ -102,7 +101,7 @@ class TestPerforce(TestSCons.TestSCons):
                 # is already clear.
                 pass
 
-        self.portflag = string.join(self.p4portflags)
+        self.portflag = ' '.join(self.p4portflags)
 
     def p4(self, *args, **kw):
         try:
@@ -110,9 +109,9 @@ class TestPerforce(TestSCons.TestSCons):
         except KeyError:
             arguments = args[0]
             args = args[1:]
-        kw['arguments'] = string.join(self.p4portflags + [arguments])
+        kw['arguments'] = ' '.join(self.p4portflags + [arguments])
         kw['program'] = self.p4path
-        return apply(self.run, args, kw)
+        return self.run(*args, **kw)
 
     def substitute(self, s, **kw):
         kw = kw.copy()
@@ -208,8 +207,8 @@ test.write(['import', 'sub', 'fff.in'], "import/sub/fff.in\n")
 os.environ["PWD"] = test.workpath('import')
 paths = [ 'aaa.in', 'bbb.in', 'ccc.in',
           'sub/ddd.in', 'sub/eee.in', 'sub/fff.in', 'sub/SConscript' ]
-paths = map(os.path.normpath, paths)
-args = '-c testclient1 add -t binary %s' % string.join(paths)
+paths = list(map(os.path.normpath, paths))
+args = '-c testclient1 add -t binary %s' % ' '.join(paths)
 test.p4(args, chdir='import')
 
 changespec = test.substitute("""
@@ -240,10 +239,9 @@ test.p4('-c testclient1 submit -i', stdin=changespec)
 SConstruct_contents = test.substitute("""
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(tools = ['default', 'Perforce'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/Progress/TARGET.py b/test/Progress/TARGET.py
index c2b42138..d7ff3c96 100644
--- a/test/Progress/TARGET.py
+++ b/test/Progress/TARGET.py
@@ -30,7 +30,6 @@ overwriting it by setting the overwrite= keyword argument.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -59,7 +58,7 @@ S1.in\r     \rS1.out\rCopy("S1.out", "S1.in")
       \rSConstruct\r          \r.\r"""
 
 if os.linesep != '\n':
-    expect = string.replace(expect, '\n', os.linesep)
+    expect = expect.replace('\n', os.linesep)
 
 test.run(arguments = '-Q .', stdout=expect)
 
diff --git a/test/Progress/file.py b/test/Progress/file.py
index 6095fb0b..3184a5b8 100644
--- a/test/Progress/file.py
+++ b/test/Progress/file.py
@@ -30,7 +30,6 @@ progress output.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -74,7 +73,7 @@ stderr: .
 """
 
 if os.linesep != '\n':
-    expect = string.replace(expect, '\n', os.linesep)
+    expect = expect.replace('\n', os.linesep)
 
 test.must_match('progress.out', expect)
 
diff --git a/test/Progress/spinner.py b/test/Progress/spinner.py
index 0919b445..85ca32f2 100644
--- a/test/Progress/spinner.py
+++ b/test/Progress/spinner.py
@@ -30,7 +30,6 @@ that represents a canonical "spinner" on the output.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -59,7 +58,7 @@ expect = """\
 \\\r|\r"""
 
 if os.linesep != '\n':
-    expect = string.replace(expect, '\n', os.linesep)
+    expect = expect.replace('\n', os.linesep)
 
 test.run(arguments = '-Q .', stdout=expect)
 
diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py
index 62155fd2..008397a8 100644
--- a/test/QT/QTFLAGS.py
+++ b/test/QT/QTFLAGS.py
@@ -147,9 +147,8 @@ test.must_exist(['work1', 'mmmmocFromH.cxx'],
                 ['work1', 'mmmanother_ui_file.cxx'])
 
 def _flagTest(test,fileToContentsStart):
-    import string
     for f,c in fileToContentsStart.items():
-        if string.find(test.read(test.workpath('work1', f)), c) != 0:
+        if test.read(test.workpath('work1', f)).find(c) != 0:
             return 1
     return 0
 
diff --git a/test/QT/Tool.py b/test/QT/Tool.py
index 86eb4ca7..63fb113e 100644
--- a/test/QT/Tool.py
+++ b/test/QT/Tool.py
@@ -90,7 +90,7 @@ def CheckForQt(context):
     "/usr/pkg/qt3" # pkgsrc (NetBSD)
     ]
 
-  if os.environ.has_key('QTDIR'):
+  if 'QTDIR' in os.environ:
     potential_qt_dirs.insert(0, os.environ[ 'QTDIR' ])
   
   if env[ 'qt_directory' ] != "/":
@@ -125,10 +125,8 @@ def CheckForQt(context):
   return 0
 
 def AttemptLinkWithVariables(context, variables, code, extension, prefix):
-  return DoWithVariables(variables,
-                         prefix,
-                         lambda c=context, code=code, e=extension:
-                                c.TryLink(code, e))
+  return DoWithVariables(variables, prefix,
+                         lambda: context.TryLink(code, extension))
 
 env = Environment(CPPPATH=['.'], LIBPATH=['.'], LIBS=[])
 
diff --git a/test/QT/copied-env.py b/test/QT/copied-env.py
index f68e1db2..63083da3 100644
--- a/test/QT/copied-env.py
+++ b/test/QT/copied-env.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -28,8 +29,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test Qt with a copied construction environment.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -68,10 +67,9 @@ void aaa(void)
 
 test.run()
 
-moc_MyForm = filter(lambda x: string.find(x, 'moc_MyForm') != -1,
-                    string.split(test.stdout(), '\n'))
+moc_MyForm = [x for x in test.stdout().split('\n') if x.find('moc_MyForm') != -1]
 
-MYLIB_IMPL = filter(lambda x: string.find(x, 'MYLIB_IMPL') != -1, moc_MyForm)
+MYLIB_IMPL = [x for x in moc_MyForm if x.find('MYLIB_IMPL') != -1]
 
 if not MYLIB_IMPL:
     print "Did not find MYLIB_IMPL on moc_MyForm compilation line:"
diff --git a/test/QT/generated-ui.py b/test/QT/generated-ui.py
index e01a6338..e4632b12 100644
--- a/test/QT/generated-ui.py
+++ b/test/QT/generated-ui.py
@@ -47,7 +47,7 @@ import os
 aa=os.getcwd()
 
 env=Environment(tools=['default','expheaders','qt'],toolpath=[aa])
-if os.environ.has_key('HOME'):
+if 'HOME' in os.environ:
     env['ENV']['HOME'] = os.environ['HOME']
 env["EXP_HEADER_ABS"]=os.path.join(os.getcwd(),'include')
 if not os.access(env["EXP_HEADER_ABS"],os.F_OK):
diff --git a/test/QT/installed.py b/test/QT/installed.py
index c79f958f..26613774 100644
--- a/test/QT/installed.py
+++ b/test/QT/installed.py
@@ -29,7 +29,6 @@ Look if qt is installed, and try out all builders.
 """
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -51,7 +50,7 @@ dummy_env = Environment()
 ENV = dummy_env['ENV']
 try:
     PATH=ARGUMENTS['PATH']
-    if ENV.has_key('PATH'):
+    if 'PATH' in ENV:
         ENV_PATH = PATH + os.pathsep + ENV['PATH']
     else:
         Exit(0) # this is certainly a weird system :-)
@@ -191,7 +190,7 @@ if test.stdout() != "Hello World\n" or test.stderr() != '' or test.status:
     # an indication that it built correctly) but don't fail the test.
     expect = 'cannot connect to X server'
     test.fail_test(test.stdout())
-    test.fail_test(string.find(test.stderr(), expect) == -1)
+    test.fail_test(test.stderr().find(expect) == -1)
     if test.status != 1 and (test.status>>8) != 1:
         sys.stdout.write('test_realqt returned status %s\n' % test.status)
         test.fail_test()
@@ -206,8 +205,8 @@ test.run(stderr=None, arguments="-c bld/test_realqt" + TestSCons._exe)
 expect1 = "scons: warning: Could not detect qt, using empty QTDIR"
 expect2 = "scons: warning: Could not detect qt, using moc executable as a hint"
 
-test.fail_test(string.find(test.stderr(), expect1) == -1 and
-               string.find(test.stderr(), expect2) == -1)
+test.fail_test(test.stderr().find(expect1) == -1 and
+               test.stderr().find(expect2) == -1)
 
 
 test.pass_test()
diff --git a/test/QT/manual.py b/test/QT/manual.py
index dcab3aae..ff38f32b 100644
--- a/test/QT/manual.py
+++ b/test/QT/manual.py
@@ -56,7 +56,7 @@ env.Moc('moc_eee.cpp', 'eee.cpp')
 sources.extend(env.Uic(['include/uic_fff.hpp', 'fff.cpp', 'fff.moc.cpp'],
                        'ui/fff.ui')[1:])
 
-print map(str,sources)
+print list(map(str,sources))
 env.Program(target='aaa',
             source=sources,
             CPPPATH=['$CPPPATH', './include'],
diff --git a/test/QT/source-from-ui.py b/test/QT/source-from-ui.py
index 6cffecc5..38cc8c86 100644
--- a/test/QT/source-from-ui.py
+++ b/test/QT/source-from-ui.py
@@ -29,7 +29,6 @@ Create .cpp, .h, moc_....cpp from a .ui file.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -126,7 +125,7 @@ test.must_not_exist(test.workpath(cpp))
 test.must_not_exist(test.workpath(h))
 
 cppContents = test.read(test.workpath('build', cpp))
-test.fail_test(string.find(cppContents, '#include "aaa.ui.h"') == -1)
+test.fail_test(cppContents.find('#include "aaa.ui.h"') == -1)
 
 test.run(arguments = "variant_dir=1 chdir=1 " +
                      test.workpath('build', aaa_dll) )
diff --git a/test/QT/up-to-date.py b/test/QT/up-to-date.py
index fbbcac0d..21c758e0 100644
--- a/test/QT/up-to-date.py
+++ b/test/QT/up-to-date.py
@@ -34,7 +34,6 @@ ca. September 2005.)
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -133,7 +132,7 @@ my_obj = 'layer/aclock/qt_bug/my'+_obj
 
 test.run(arguments = my_obj, stderr=None)
 
-expect = string.replace( my_obj, '/', os.sep )
+expect = my_obj.replace( '/', os.sep )
 test.up_to_date(options = '--debug=explain',
                 arguments = (expect),
                 stderr=None)
diff --git a/test/QT/warnings.py b/test/QT/warnings.py
index 975091bf..a861b24b 100644
--- a/test/QT/warnings.py
+++ b/test/QT/warnings.py
@@ -30,7 +30,6 @@ Test the Qt tool warnings.
 
 import os
 import re
-import string
 
 import TestSCons
 
@@ -82,7 +81,7 @@ moc = test.where_is('moc')
 if moc:
     import os.path
     qtdir = os.path.dirname(os.path.dirname(moc))
-    qtdir = string.replace(qtdir, '\\', '\\\\' )
+    qtdir = qtdir.replace('\\', '\\\\' )
 
     expect = """
 scons: warning: Could not detect qt, using moc executable as a hint \(QTDIR=%s\)
diff --git a/test/RANLIB/RANLIB.py b/test/RANLIB/RANLIB.py
index ecc6482d..c9fc10fc 100644
--- a/test/RANLIB/RANLIB.py
+++ b/test/RANLIB/RANLIB.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -42,11 +41,10 @@ if not ranlib:
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
diff --git a/test/RANLIB/RANLIBCOM.py b/test/RANLIB/RANLIBCOM.py
index 94f19979..486a91f2 100644
--- a/test/RANLIB/RANLIBCOM.py
+++ b/test/RANLIB/RANLIBCOM.py
@@ -46,7 +46,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ar*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ar*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
@@ -55,7 +55,7 @@ test.write('myranlib.py', """
 import sys
 lines = open(sys.argv[1], 'rb').readlines()
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != '/*ranlib*/\\n', lines):
+for l in [l for l in lines if l != '/*ranlib*/\\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/RANLIB/RANLIBCOMSTR.py b/test/RANLIB/RANLIBCOMSTR.py
index b59d133d..6e76cbfd 100644
--- a/test/RANLIB/RANLIBCOMSTR.py
+++ b/test/RANLIB/RANLIBCOMSTR.py
@@ -47,7 +47,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*ar*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*ar*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
@@ -56,7 +56,7 @@ test.write('myranlib.py', """
 import sys
 lines = open(sys.argv[1], 'rb').readlines()
 outfile = open(sys.argv[1], 'wb')
-for l in filter(lambda l: l != '/*ranlib*/\\n', lines):
+for l in [l for l in lines if l != '/*ranlib*/\\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/RANLIB/RANLIBFLAGS.py b/test/RANLIB/RANLIBFLAGS.py
index 123d403a..636059b4 100644
--- a/test/RANLIB/RANLIBFLAGS.py
+++ b/test/RANLIB/RANLIBFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -41,11 +40,10 @@ if not ranlib:
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(LIBS = ['foo'], LIBPATH = ['.'])
diff --git a/test/RCS/RCS_COCOM.py b/test/RCS/RCS_COCOM.py
index 8bbeb59c..a1c18e55 100644
--- a/test/RCS/RCS_COCOM.py
+++ b/test/RCS/RCS_COCOM.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'RCS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/RCS/RCS_COCOMSTR.py b/test/RCS/RCS_COCOMSTR.py
index 576afc1d..ee3ba150 100644
--- a/test/RCS/RCS_COCOMSTR.py
+++ b/test/RCS/RCS_COCOMSTR.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'RCS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/RCS/diskcheck.py b/test/RCS/diskcheck.py
index 264822a6..4e7dd24d 100644
--- a/test/RCS/diskcheck.py
+++ b/test/RCS/diskcheck.py
@@ -95,10 +95,9 @@ ENV = {'PATH' : os.environ['PATH'],
        'LOGNAME' : logname}
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 SetOption('diskcheck', None)
 DefaultEnvironment()['ENV'] = ENV
@@ -116,7 +115,7 @@ test.write('bbb.in', "checked-out bbb.in\n")
 test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n")
 
 sub_SConscript = os.path.join('sub', 'SConscript')
-SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 23)[:-1]
+SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 22)[:-1]
 
 expect = """\
 
diff --git a/test/RCS/explicit.py b/test/RCS/explicit.py
index 3e19a679..75eb1895 100644
--- a/test/RCS/explicit.py
+++ b/test/RCS/explicit.py
@@ -95,10 +95,9 @@ ENV = {'PATH' : os.environ['PATH'],
        'LOGNAME' : logname}
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(ENV=ENV,
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/RCS/transparent.py b/test/RCS/transparent.py
index 397017cb..2ebde9ac 100644
--- a/test/RCS/transparent.py
+++ b/test/RCS/transparent.py
@@ -95,10 +95,9 @@ ENV = {'PATH' : os.environ['PATH'],
        'LOGNAME' : logname}
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 DefaultEnvironment()['ENV'] = ENV
 DefaultEnvironment()['RCS_COFLAGS'] = '-l'
diff --git a/test/Repository/LIBPATH.py b/test/Repository/LIBPATH.py
index 0eb2da26..c95d29a1 100644
--- a/test/Repository/LIBPATH.py
+++ b/test/Repository/LIBPATH.py
@@ -24,7 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -40,7 +39,6 @@ workpath_bar_zzz = test.workpath('bar', 'zzz')
 workpath_work = test.workpath('work')
 
 test.write(['work', 'SConstruct'], r"""
-import string
 env_zzz = Environment(LIBPATH = ['.', 'zzz'])
 env_yyy = Environment(LIBPATH = ['yyy', '.'])
 aaa_exe = env_zzz.Program('aaa', 'aaa.c')
@@ -49,7 +47,7 @@ def write_LIBDIRFLAGS(env, target, source):
     pre = env.subst('$LIBDIRPREFIX')
     suf = env.subst('$LIBDIRSUFFIX')
     f = open(str(target[0]), 'wb')
-    for arg in string.split(env.subst('$_LIBDIRFLAGS', target=target)):
+    for arg in env.subst('$_LIBDIRFLAGS', target=target).split():
         if arg[:len(pre)] == pre:
             arg = arg[len(pre):]
         if arg[-len(suf):] == suf:
@@ -100,13 +98,13 @@ test.run(chdir = 'work', options = opts, arguments = ".")
 dirs = ['.', workpath_foo, workpath_bar,
         'zzz', workpath_foo_zzz, workpath_bar_zzz]
 test.fail_test(test.read(['work', 'zzz.out']) !=
-               string.join(dirs, '\n') + '\n')
+               '\n'.join(dirs) + '\n')
 
 #dirs = [workpath_bar_yyy, '.', workpath_foo, workpath_bar]
 dirs = ['yyy', workpath_foo_yyy, workpath_bar_yyy,
         '.', workpath_foo, workpath_bar]
 test.fail_test(test.read(['work', 'yyy.out']) !=
-               string.join(dirs, '\n') + '\n')
+               '\n'.join(dirs) + '\n')
 
 #
 test.run(chdir = 'work', options = '-c', arguments = ".")
@@ -120,13 +118,13 @@ test.run(chdir = 'work', options = opts, arguments = ".")
 dirs = ['.', workpath_foo, workpath_bar,
         'zzz', workpath_foo_zzz, workpath_bar_zzz]
 test.fail_test(test.read(['work', 'zzz.out']) !=
-               string.join(dirs, '\n') + '\n')
+               '\n'.join(dirs) + '\n')
 
 #dirs = ['yyy', workpath_bar_yyy, '.', workpath_foo, workpath_bar]
 dirs = ['yyy', workpath_foo_yyy, workpath_bar_yyy,
         '.', workpath_foo, workpath_bar]
 test.fail_test(test.read(['work', 'yyy.out']) !=
-               string.join(dirs, '\n') + '\n')
+               '\n'.join(dirs) + '\n')
 
 #
 test.pass_test()
diff --git a/test/Repository/M4.py b/test/Repository/M4.py
index b3ed7556..fe1eb7b5 100644
--- a/test/Repository/M4.py
+++ b/test/Repository/M4.py
@@ -39,10 +39,9 @@ test = TestSCons.TestSCons()
 test.subdir('work', 'repository', ['repository', 'src'])
 
 test.write('mym4.py', """
-import string
 import sys
 contents = sys.stdin.read()
-sys.stdout.write(string.replace(contents, 'M4', 'mym4.py'))
+sys.stdout.write(contents.replace('M4', 'mym4.py'))
 sys.exit(0)
 """)
 
diff --git a/test/Repository/RMIC.py b/test/Repository/RMIC.py
index e00bb43f..b214b4bd 100644
--- a/test/Repository/RMIC.py
+++ b/test/Repository/RMIC.py
@@ -60,13 +60,12 @@ opts = '-Y ' + test.workpath('rep1')
 
 #
 test.write(['rep1', 'SConstruct'], """
-import string
 env = Environment(tools = ['javac', 'rmic'],
                   JAVAC = r'%s',
                   RMIC = r'%s')
 classes = env.Java(target = 'classes', source = 'src')
 # Brute-force removal of the "Hello" class.
-classes = filter(lambda c: string.find(str(c), 'Hello') == -1, classes)
+classes = [c for c in classes if str(c).find('Hello') == -1]
 env.RMIC(target = 'outdir', source = classes)
 """ % (javac, rmic))
 
@@ -329,13 +328,12 @@ test.up_to_date(chdir = 'work2', options = opts, arguments = ".")
 
 #
 test.write(['work3', 'SConstruct'], """
-import string
 env = Environment(tools = ['javac', 'rmic'],
                   JAVAC = r'%s',
                   RMIC = r'%s')
 classes = env.Java(target = 'classes', source = 'src')
 # Brute-force removal of the "Hello" class.
-classes = filter(lambda c: string.find(str(c), 'Hello') == -1, classes)
+classes = [c for c in classes if str(c).find('Hello') == -1]
 rmi_classes = env.RMIC(target = 'outdir', source = classes)
 Local(rmi_classes)
 """ % (javac, rmic))
diff --git a/test/Repository/SConscript.py b/test/Repository/SConscript.py
index fb4ef082..22956acd 100644
--- a/test/Repository/SConscript.py
+++ b/test/Repository/SConscript.py
@@ -61,10 +61,9 @@ SConscript('src/SConscript')
 test.write(['rep1', 'src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat(target = 'foo', source = ['aaa.in', 'bbb.in', 'ccc.in'])
@@ -98,10 +97,9 @@ SConscript('src/SConscript')
 test.write(['rep2', 'src', 'SConscript'], """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat(target = 'foo', source = ['aaa.in', 'bbb.in', 'ccc.in'])
diff --git a/test/Repository/SharedLibrary.py b/test/Repository/SharedLibrary.py
index fbd135e8..51142aa9 100644
--- a/test/Repository/SharedLibrary.py
+++ b/test/Repository/SharedLibrary.py
@@ -30,7 +30,6 @@ object files built in a repository.
 """
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -115,7 +114,7 @@ if os.name == 'posix':
         os.environ['DYLD_LIBRARY_PATH'] = test.workpath('work')
     else:
         os.environ['LD_LIBRARY_PATH'] = test.workpath('work')
-if string.find(sys.platform, 'irix') != -1:
+if sys.platform.find('irix') != -1:
     os.environ['LD_LIBRARYN32_PATH'] = test.workpath('work')
 
 test.run(program = test.workpath('work', 'prog'),
diff --git a/test/Repository/VariantDir.py b/test/Repository/VariantDir.py
index 0abda0bd..ec723c82 100644
--- a/test/Repository/VariantDir.py
+++ b/test/Repository/VariantDir.py
@@ -47,7 +47,7 @@ SConscript('build1/SConscript')
 test.write(['repository', 'src', 'SConscript'], r"""
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
+    source = list(map(str, source))
     print 'cat(%s) > %s' % (source, target)
     f = open(target, "wb")
     for src in source:
diff --git a/test/Repository/option-f.py b/test/Repository/option-f.py
index aec94183..8511f6ac 100644
--- a/test/Repository/option-f.py
+++ b/test/Repository/option-f.py
@@ -43,10 +43,9 @@ test.write(['repository', 'SConstruct'], """\
 Repository(r'%s')
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(BUILDERS={'Build':Builder(action=cat)})
diff --git a/test/Repository/targets.py b/test/Repository/targets.py
index d3950478..62f4785a 100644
--- a/test/Repository/targets.py
+++ b/test/Repository/targets.py
@@ -42,7 +42,7 @@ opts = "-Y " + test.workpath('repository')
 test.write(['repository', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
+    source = list(map(str, source))
     print 'cat(%s) > %s' % (source, target)
     f = open(target, "wb")
     for src in source:
diff --git a/test/Requires/basic.py b/test/Requires/basic.py
index 548e6b2a..edce13b2 100644
--- a/test/Requires/basic.py
+++ b/test/Requires/basic.py
@@ -36,8 +36,8 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', """
 def append_prereq_func(target, source, env):
     fp = open(str(target[0]), 'wb')
-    for s in map(str, source):
-        fp.write(open(s, 'rb').read())
+    for s in source:
+        fp.write(open(str(s), 'rb').read())
     fp.write(open('prereq.out', 'rb').read())
     fp.close()
     return None
diff --git a/test/Requires/eval-order.py b/test/Requires/eval-order.py
index 9c1f25b4..51539a28 100644
--- a/test/Requires/eval-order.py
+++ b/test/Requires/eval-order.py
@@ -35,8 +35,8 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', """
 def copy_and_create_func(target, source, env):
     fp = open(str(target[0]), 'wb')
-    for s in map(str, source):
-        fp.write(open(s, 'rb').read())
+    for s in source:
+        fp.write(open(str(s), 'rb').read())
     fp.close()
     open('file.in', 'wb').write("file.in 1\\n")
     return None
diff --git a/test/Rpcgen/RPCGEN.py b/test/Rpcgen/RPCGEN.py
index 5fde5dff..dd3669b3 100644
--- a/test/Rpcgen/RPCGEN.py
+++ b/test/Rpcgen/RPCGEN.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/Rpcgen/RPCGENCLIENTFLAGS.py b/test/Rpcgen/RPCGENCLIENTFLAGS.py
index 4b0d24f5..7cf0144b 100644
--- a/test/Rpcgen/RPCGENCLIENTFLAGS.py
+++ b/test/Rpcgen/RPCGENCLIENTFLAGS.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:x', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/Rpcgen/RPCGENFLAGS.py b/test/Rpcgen/RPCGENFLAGS.py
index ddbc745d..4af5da8f 100644
--- a/test/Rpcgen/RPCGENFLAGS.py
+++ b/test/Rpcgen/RPCGENFLAGS.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:x', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/Rpcgen/RPCGENHEADERFLAGS.py b/test/Rpcgen/RPCGENHEADERFLAGS.py
index 3eac78f6..0c93fe7a 100644
--- a/test/Rpcgen/RPCGENHEADERFLAGS.py
+++ b/test/Rpcgen/RPCGENHEADERFLAGS.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:x', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/Rpcgen/RPCGENSERVICEFLAGS.py b/test/Rpcgen/RPCGENSERVICEFLAGS.py
index eee45053..9b8962f9 100644
--- a/test/Rpcgen/RPCGENSERVICEFLAGS.py
+++ b/test/Rpcgen/RPCGENSERVICEFLAGS.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:x', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/Rpcgen/RPCGENXDRFLAGS.py b/test/Rpcgen/RPCGENXDRFLAGS.py
index c9a911ad..8f90d5a4 100644
--- a/test/Rpcgen/RPCGENXDRFLAGS.py
+++ b/test/Rpcgen/RPCGENXDRFLAGS.py
@@ -35,15 +35,14 @@ test = TestSCons.TestSCons()
 
 test.write('myrpcgen.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'chlmo:x', [])
 for opt, arg in cmd_opts:
     if opt == '-o': output = open(arg, 'wb')
-output.write(string.join(sys.argv) + "\\n")
+output.write(" ".join(sys.argv) + "\\n")
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'RPCGEN', 'myrpcgen.py'))
+    output.write(contents.replace('RPCGEN', 'myrpcgen.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/SCCS/SCCSCOM.py b/test/SCCS/SCCSCOM.py
index 771b7736..9d1b649f 100644
--- a/test/SCCS/SCCSCOM.py
+++ b/test/SCCS/SCCSCOM.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'SCCS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/SCCS/SCCSCOMSTR.py b/test/SCCS/SCCSCOMSTR.py
index 162fe3cb..d0da2e43 100644
--- a/test/SCCS/SCCSCOMSTR.py
+++ b/test/SCCS/SCCSCOMSTR.py
@@ -58,10 +58,9 @@ for f in sys.argv[1:]:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(TOOLS = ['default', 'SCCS'],
                   BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/SCCS/diskcheck.py b/test/SCCS/diskcheck.py
index 8d30d332..a8660bc0 100644
--- a/test/SCCS/diskcheck.py
+++ b/test/SCCS/diskcheck.py
@@ -29,7 +29,6 @@ Test transparent checkouts from SCCS files in an SCCS subdirectory.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -74,10 +73,9 @@ test.write(['SConstruct'], """
 DefaultEnvironment()['SCCSCOM'] = 'cd ${TARGET.dir} && $SCCS get ${TARGET.file}'
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 SetOption('diskcheck', ['match', 'rcs'])
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
@@ -94,7 +92,7 @@ test.write(['bbb.in'], "checked-out bbb.in\n")
 test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n")
 
 sub_SConscript = os.path.join('sub', 'SConscript')
-SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 17)[:-1]
+SConstruct_file_line = test.python_file_line(test.workpath('SConstruct'), 16)[:-1]
 
 expect = """\
 
@@ -107,7 +105,7 @@ test.run(status=2, stderr=expect)
 
 test.run(arguments = '--diskcheck=sccs', stderr = None)
 
-lines = string.split("""
+lines = """
 sccs get SConscript
 sccs get aaa.in
 cat(["aaa.out"], ["aaa.in"])
@@ -121,7 +119,7 @@ cat(["sub/eee.out"], ["sub/eee.in"])
 sccs get fff.in
 cat(["sub/fff.out"], ["sub/fff.in"])
 cat(["sub/all"], ["sub/ddd.out", "sub/eee.out", "sub/fff.out"])
-""", '\n')
+""".split('\n')
 
 test.must_contain_all_lines(test.stdout(), lines)
 
diff --git a/test/SCCS/explicit.py b/test/SCCS/explicit.py
index f716dd09..252e9013 100644
--- a/test/SCCS/explicit.py
+++ b/test/SCCS/explicit.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test explicit checkouts from local SCCS files.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -71,10 +69,9 @@ for f in ['ddd.in', 'eee.in', 'fff.in']:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
                   SCCSCOM = 'cd ${TARGET.dir} && $SCCS get $SCCSGETFLAGS ${TARGET.file}',
@@ -93,7 +90,7 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n")
 
 test.run(arguments = '.', stderr = None)
 
-lines = string.split("""
+lines = """
 sccs get -e SConscript
 sccs get -e aaa.in
 cat(["aaa.out"], ["aaa.in"])
@@ -107,7 +104,7 @@ cat(["sub/eee.out"], ["sub/eee.in"])
 sccs get -e fff.in
 cat(["sub/fff.out"], ["sub/fff.in"])
 cat(["sub/all"], ["sub/ddd.out", "sub/eee.out", "sub/fff.out"])
-""", '\n')
+""".split('\n')
 
 test.must_contain_all_lines(test.stdout(), lines)
 
diff --git a/test/SCCS/implicit.py b/test/SCCS/implicit.py
index 79eaf06b..3f868412 100644
--- a/test/SCCS/implicit.py
+++ b/test/SCCS/implicit.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test transparent SCCS checkouts of implicit dependencies.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -70,10 +68,10 @@ env.Program('foo.c')
 
 test.run(stderr = None)
 
-lines = string.split("""
+lines = """
 sccs get foo.c
 sccs get foo.h
-""", '\n')
+""".split('\n')
 
 test.must_contain_all_lines(test.stdout(), lines)
 
diff --git a/test/SCCS/transparent.py b/test/SCCS/transparent.py
index adc0fe10..a8105a29 100644
--- a/test/SCCS/transparent.py
+++ b/test/SCCS/transparent.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test transparent checkouts from SCCS files in an SCCS subdirectory.
 """
 
-import string
-
 import TestSCons
 
 test = TestSCons.TestSCons()
@@ -73,10 +71,9 @@ test.write(['SConstruct'], """
 DefaultEnvironment()['SCCSCOM'] = 'cd ${TARGET.dir} && $SCCS get ${TARGET.file}'
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
                   SCCSFLAGS='-k')
@@ -93,7 +90,7 @@ test.write(['sub', 'eee.in'], "checked-out sub/eee.in\n")
 
 test.run(arguments = '.', stderr = None)
 
-lines = string.split("""
+lines = """
 sccs get SConscript
 sccs get aaa.in
 cat(["aaa.out"], ["aaa.in"])
@@ -107,7 +104,7 @@ cat(["sub/eee.out"], ["sub/eee.in"])
 sccs get fff.in
 cat(["sub/fff.out"], ["sub/fff.in"])
 cat(["sub/all"], ["sub/ddd.out", "sub/eee.out", "sub/fff.out"])
-""", '\n')
+""".split('\n')
 
 test.must_contain_all_lines(test.stdout(), lines)
 
diff --git a/test/SConscript/SConscript.py b/test/SConscript/SConscript.py
index fa7e9144..5bd49f3e 100644
--- a/test/SConscript/SConscript.py
+++ b/test/SConscript/SConscript.py
@@ -83,7 +83,7 @@ SConscript('SConscript7')
 
 test.write('SConscript', """\
 # os should not be automajically imported:
-assert not globals().has_key("os")
+assert "os" not in globals()
 
 import os
 print "SConscript " + os.getcwd()
diff --git a/test/SConscript/src_dir.py b/test/SConscript/src_dir.py
index 1a3a3df9..967e391c 100644
--- a/test/SConscript/src_dir.py
+++ b/test/SConscript/src_dir.py
@@ -57,7 +57,7 @@ from os.path import join
 from os.path import basename
 Import('env')
 
-sources = map(basename, glob(join(str(env.Dir('.').srcnode()),'*.c')))
+sources = list(map(basename, glob(join(str(env.Dir('.').srcnode()),'*.c'))))
 
 # Trivial example; really I read the configuration file
 # their build system uses to generate the vcproj files
diff --git a/test/SHELL.py b/test/SHELL.py
index fa1ae78e..93ed0b13 100644
--- a/test/SHELL.py
+++ b/test/SHELL.py
@@ -48,7 +48,6 @@ my_shell = test.workpath('my_shell.py')
 test.write(my_shell, """\
 #!%(python)s
 import os
-import string
 import sys
 cmd = sys.argv[2]
 def stripquote(s):
@@ -56,8 +55,8 @@ def stripquote(s):
        s[0] == "'" and s[-1] == "'":
         s = s[1:-1]
     return s
-args = string.split(stripquote(sys.argv[2]))
-args = map(stripquote, args)
+args = stripquote(sys.argv[2]).split()
+args = list(map(stripquote, args))
 ofp = open(args[2], 'wb')
 for f in args[3:] + ['extra.txt']:
     ofp.write(open(f, 'rb').read())
diff --git a/test/SPAWN.py b/test/SPAWN.py
index c7cd4e41..68025244 100644
--- a/test/SPAWN.py
+++ b/test/SPAWN.py
@@ -44,15 +44,14 @@ ofp.close()
 
 test.write('SConstruct', """
 import os
-import string
 import sys
 def my_spawn1(sh, escape, cmd, args, env):
-    s = string.join(args + ['extra1.txt'])
+    s = " ".join(args + ['extra1.txt'])
     if sys.platform in ['win32']:
         s = '"' + s + '"'
     os.system(s)
 def my_spawn2(sh, escape, cmd, args, env):
-    s = string.join(args + ['extra2.txt'])
+    s = " ".join(args + ['extra2.txt'])
     if sys.platform in ['win32']:
         s = '"' + s + '"'
     os.system(s)
diff --git a/test/SWIG/SWIGCOM.py b/test/SWIG/SWIGCOM.py
index d1d77763..44602fda 100644
--- a/test/SWIG/SWIGCOM.py
+++ b/test/SWIG/SWIGCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*swig*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*swig*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/SWIG/SWIGCOMSTR.py b/test/SWIG/SWIGCOMSTR.py
index 739c7811..1df3499e 100644
--- a/test/SWIG/SWIGCOMSTR.py
+++ b/test/SWIG/SWIGCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*swig*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*swig*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/SWIG/live.py b/test/SWIG/live.py
index 0a4c9059..8f580c97 100644
--- a/test/SWIG/live.py
+++ b/test/SWIG/live.py
@@ -29,7 +29,6 @@ Test SWIG behavior with a live, installed SWIG.
 """
 
 import os.path
-import string
 import sys
 
 import TestSCons
@@ -58,11 +57,10 @@ ldmodule_prefix = '_'
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """\
 foo = Environment(SWIGFLAGS='-python',
diff --git a/test/Scanner/FindPathDirs.py b/test/Scanner/FindPathDirs.py
index 9f0e5357..ef3ea46d 100644
--- a/test/Scanner/FindPathDirs.py
+++ b/test/Scanner/FindPathDirs.py
@@ -39,9 +39,8 @@ test.subdir('inc1', 'inc2')
 
 test.write('build.py', r"""
 import os.path
-import string
 import sys
-path = string.split(sys.argv[1])
+path = sys.argv[1].split()
 input = open(sys.argv[2], 'rb')
 output = open(sys.argv[3], 'wb')
 
diff --git a/test/Scanner/Scanner.py b/test/Scanner/Scanner.py
index 4c84069f..8d48b730 100644
--- a/test/Scanner/Scanner.py
+++ b/test/Scanner/Scanner.py
@@ -113,11 +113,9 @@ bar = env.BarBld(target='bar', source='bar.in')
 # Test specifying a source scanner for a Builder that gets
 # automatically applied to targets generated from that Builder
 
-import string
-
 def blork(env, target, source):
     open(str(target[0]), 'wb').write(
-        string.replace(source[0].get_text_contents(), 'getfile', 'MISSEDME'))
+        source[0].get_text_contents().replace('getfile', 'MISSEDME'))
 
 kbld = Builder(action=r'%(_python_)s build.py $SOURCES $TARGET',
                src_suffix='.lork',
diff --git a/test/Scanner/exception.py b/test/Scanner/exception.py
index 4e62f8f3..1e229315 100644
--- a/test/Scanner/exception.py
+++ b/test/Scanner/exception.py
@@ -67,11 +67,9 @@ def process(outf, inf):
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
-
     outf = open(target, 'wb')
     for src in source:
-        process(outf, open(src, 'rb'))
+        process(outf, open(str(src), 'rb'))
     outf.close()
 
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py
index 5a695106..8c90df45 100644
--- a/test/Scanner/generated.py
+++ b/test/Scanner/generated.py
@@ -84,7 +84,6 @@ Mylib.Subdirs(env, "src")
 
 test.write('Mylib.py', """\
 import os
-import string
 import re
 
 def Subdirs(env, dirlist):
@@ -92,10 +91,10 @@ def Subdirs(env, dirlist):
         env.SConscript(file, "env")
 
 def _subconf_list(dirlist):
-    return map(lambda x: os.path.join(x, "SConscript"), string.split(dirlist))
+    return [os.path.join(x, "SConscript") for x in dirlist.split()]
 
 def StaticLibMergeMembers(local_env, libname, hackpath, files):
-    for file in string.split(files):
+    for file in files.split():
         # QQQ Fix limits in grok'ed regexp
         tmp = re.sub(".c$", ".o", file)
         objname = re.sub(".cpp", ".o", tmp)
@@ -121,22 +120,22 @@ def Gen_StaticLibMerge(source, target, env, for_signature):
     return [["ar", "cq"] + target + srclist, ["ranlib"] + target]
 
 def StaticLibrary(env, target, source):
-    env.StaticLibrary(target, string.split(source))
+    env.StaticLibrary(target, source.split())
 
 def SharedLibrary(env, target, source):
-    env.SharedLibrary(target, string.split(source))
+    env.SharedLibrary(target, source.split())
 
 def ExportHeader(env, headers):
-    env.Install(dir = env["EXPORT_INCLUDE"], source = string.split(headers))
+    env.Install(dir = env["EXPORT_INCLUDE"], source = headers.split())
 
 def ExportLib(env, libs):
-    env.Install(dir = env["EXPORT_LIB"], source = string.split(libs))
+    env.Install(dir = env["EXPORT_LIB"], source = libs.split())
 
 def InstallBin(env, bins):
-    env.Install(dir = env["INSTALL_BIN"], source = string.split(bins))
+    env.Install(dir = env["INSTALL_BIN"], source = bins.split())
 
 def Program(env, target, source):
-    env.Program(target, string.split(source))
+    env.Program(target, source.split())
 
 def AddCFlags(env, str):
     env.Append(CPPFLAGS = " " + str)
@@ -146,13 +145,13 @@ def AddCFlags(env, str):
 #    AddCFlags(env, str)
 
 def AddIncludeDirs(env, str):
-    env.Append(CPPPATH = string.split(str))
+    env.Append(CPPPATH = str.split())
 
 def AddLibs(env, str):
-    env.Append(LIBS = string.split(str))
+    env.Append(LIBS = str.split())
 
 def AddLibDirs(env, str):
-    env.Append(LIBPATH = string.split(str))
+    env.Append(LIBPATH = str.split())
 
 """)
 
@@ -189,7 +188,6 @@ env = env.Clone()    # Yes, clobber intentionally
 
 test.write(['src', 'lib_geng', 'SConscript'], """\
 # --- Begin SConscript boilerplate ---
-import string
 import sys
 import Mylib
 Import("env")
@@ -233,8 +231,8 @@ for k in fromdict.keys():
         except SCons.Errors.UserError:
              pass
 todict["CFLAGS"] = fromdict["CPPFLAGS"] + " " + \
-    string.join(map(lambda x: "-I" + x, env["CPPPATH"])) + " " + \
-    string.join(map(lambda x: "-L" + x, env["LIBPATH"])) 
+    ' '.join(["-I" + x for x in env["CPPPATH"]]) + " " + \
+    ' '.join(["-L" + x for x in env["LIBPATH"]])
 todict["CXXFLAGS"] = todict["CFLAGS"]
 
 generated_hdrs = "libg_gx.h libg_gy.h libg_gz.h"
@@ -243,9 +241,9 @@ static_hdrs = "libg_w.h"
 exported_hdrs = static_hdrs
 lib_name = "g"
 lib_fullname = env.subst("${LIBPREFIX}g${LIBSUFFIX}")
-lib_srcs = string.split("libg_1.c libg_2.c libg_3.c")
+lib_srcs = "libg_1.c libg_2.c libg_3.c".split()
 import re
-lib_objs = map(lambda x: re.sub("\.c$", ".o", x), lib_srcs)
+lib_objs = [re.sub("\.c$", ".o", x) for x in lib_srcs]
 
 Mylib.ExportHeader(env, exported_hdrs)
 Mylib.ExportLib(env, lib_fullname)
@@ -275,11 +273,11 @@ cmd_justlib = "%s %s -C ${SOURCES[0].dir}" % (escape(sys.executable),
 #
 # SCons bug??
 
-env.Command(string.split(generated_hdrs),
+env.Command(generated_hdrs.split(),
             ["MAKE-HEADER.py"],
             cmd_generated)
 recurse_env.Command([lib_fullname] + lib_objs,
-                    lib_srcs + string.split(generated_hdrs + " " + static_hdrs),
+                    lib_srcs + (generated_hdrs + " " + static_hdrs).split(),
                     cmd_justlib) 
 """)
 
diff --git a/test/Scanner/no-Dir-node.py b/test/Scanner/no-Dir-node.py
index a780de1f..9a47c018 100644
--- a/test/Scanner/no-Dir-node.py
+++ b/test/Scanner/no-Dir-node.py
@@ -52,9 +52,8 @@ inc2_include_h = test.workpath('inc2', 'include.h')
 
 test.write('build.py', r"""
 import os.path
-import string
 import sys
-path = string.split(sys.argv[1])
+path = sys.argv[1].split()
 input = open(sys.argv[2], 'rb')
 output = open(sys.argv[3], 'wb')
 
diff --git a/test/SourceCode.py b/test/SourceCode.py
index 0f8a5c1f..91af7da3 100644
--- a/test/SourceCode.py
+++ b/test/SourceCode.py
@@ -41,10 +41,9 @@ import os
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 def sc_cat(env, source, target):
diff --git a/test/Subversion.py b/test/Subversion.py
index b164d8e9..01a12f68 100644
--- a/test/Subversion.py
+++ b/test/Subversion.py
@@ -75,10 +75,9 @@ test.run(chdir = 'import',
 test.write(['work1', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'foo/aaa.in')
@@ -123,10 +122,9 @@ test.fail_test(test.read(['work1', 'foo', 'sub', 'all']) != "import/sub/ddd.in\n
 test.write(['work2', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/TAR/TAR.py b/test/TAR/TAR.py
index 80dea7a1..ac8d7913 100644
--- a/test/TAR/TAR.py
+++ b/test/TAR/TAR.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -88,11 +87,10 @@ tar = test.detect('TAR', 'tar')
 if tar:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment()
diff --git a/test/TAR/TARCOM.py b/test/TAR/TARCOM.py
index 2a98d064..d1b3662a 100644
--- a/test/TAR/TARCOM.py
+++ b/test/TAR/TARCOM.py
@@ -40,7 +40,7 @@ test.write('mytar.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*tar*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*tar*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TAR/TARCOMSTR.py b/test/TAR/TARCOMSTR.py
index 70b6c699..339f0ca9 100644
--- a/test/TAR/TARCOMSTR.py
+++ b/test/TAR/TARCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*tar*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*tar*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TAR/TARFLAGS.py b/test/TAR/TARFLAGS.py
index e9940a85..f349b3a6 100644
--- a/test/TAR/TARFLAGS.py
+++ b/test/TAR/TARFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -39,7 +38,6 @@ test.write('mytar.py', """
 import getopt
 import os
 import os.path
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'cf:x', [])
 opt_string = ''
@@ -95,11 +93,10 @@ tar = test.detect('TAR', 'tar')
 if tar:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 foo = Environment()
diff --git a/test/TARGET-dir.py b/test/TARGET-dir.py
index d56127d8..9e990878 100644
--- a/test/TARGET-dir.py
+++ b/test/TARGET-dir.py
@@ -43,10 +43,9 @@ test.subdir('src', 'build1', 'build2')
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(CPPPATH='${TARGET.dir}')
 env.Append(BUILDERS = {'Cat' : Builder(action=cat)})
diff --git a/test/TARGETS.py b/test/TARGETS.py
index bf278aaf..5b36c49e 100644
--- a/test/TARGETS.py
+++ b/test/TARGETS.py
@@ -36,10 +36,10 @@ test = TestSCons.TestSCons()
 
 test.write('SConstruct', """
 print COMMAND_LINE_TARGETS
-print map(str, BUILD_TARGETS)
+print list(map(str, BUILD_TARGETS))
 Default('.')
 print COMMAND_LINE_TARGETS
-print map(str, BUILD_TARGETS)
+print list(map(str, BUILD_TARGETS))
 """)
 
 test.write('aaa', 'aaa\n')
@@ -68,17 +68,17 @@ test.run(arguments = 'bbb ccc=xyz -n aaa', stdout = expect)
 
 test.write('SConstruct', """
 env = Environment()
-print map(str, DEFAULT_TARGETS)
-print map(str, BUILD_TARGETS)
+print list(map(str, DEFAULT_TARGETS))
+print list(map(str, BUILD_TARGETS))
 Default('aaa')
-print map(str, DEFAULT_TARGETS)
-print map(str, BUILD_TARGETS)
+print list(map(str, DEFAULT_TARGETS))
+print list(map(str, BUILD_TARGETS))
 env.Default('bbb')
-print map(str, DEFAULT_TARGETS)
-print map(str, BUILD_TARGETS)
+print list(map(str, DEFAULT_TARGETS))
+print list(map(str, BUILD_TARGETS))
 env.Default(None)
-print map(str, DEFAULT_TARGETS)
-print map(str, BUILD_TARGETS)
+print list(map(str, DEFAULT_TARGETS))
+print list(map(str, BUILD_TARGETS))
 env.Default('ccc')
 """)
 
@@ -113,9 +113,9 @@ test.run(arguments = '.', stdout = expect)
 
 
 test.write('SConstruct', """\
-print map(str, BUILD_TARGETS)
+print list(map(str, BUILD_TARGETS))
 SConscript('SConscript')
-print map(str, BUILD_TARGETS)
+print list(map(str, BUILD_TARGETS))
 """)
 
 test.write('SConscript', """\
diff --git a/test/TEX/LATEX.py b/test/TEX/LATEX.py
index 2316770b..03d3a007 100644
--- a/test/TEX/LATEX.py
+++ b/test/TEX/LATEX.py
@@ -30,8 +30,6 @@ the produced .dvi, .aux and .log files get removed by the -c option,
 and that we can use this to wrap calls to the real latex utility.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -99,11 +97,10 @@ latex = test.where_is('latex')
 if latex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/LATEXCOM.py b/test/TEX/LATEXCOM.py
index 9d65134f..2c638645 100644
--- a/test/TEX/LATEXCOM.py
+++ b/test/TEX/LATEXCOM.py
@@ -41,7 +41,7 @@ test.write('mylatex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*latex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*latex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/LATEXCOMSTR.py b/test/TEX/LATEXCOMSTR.py
index 9383e878..4e1b93c2 100644
--- a/test/TEX/LATEXCOMSTR.py
+++ b/test/TEX/LATEXCOMSTR.py
@@ -42,7 +42,7 @@ test.write('mylatex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*latex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*latex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/LATEXFLAGS.py b/test/TEX/LATEXFLAGS.py
index 8c4e7074..f693970b 100644
--- a/test/TEX/LATEXFLAGS.py
+++ b/test/TEX/LATEXFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -82,11 +81,10 @@ latex = test.where_is('latex')
 if latex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/PDFLATEX.py b/test/TEX/PDFLATEX.py
index a7320a19..dbae623c 100644
--- a/test/TEX/PDFLATEX.py
+++ b/test/TEX/PDFLATEX.py
@@ -30,8 +30,6 @@ the produced .dvi, .aux and .log files get removed by the -c option,
 and that we can use this to wrap calls to the real latex utility.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -99,11 +97,10 @@ pdflatex = test.where_is('pdflatex')
 if pdflatex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/PDFLATEXCOM.py b/test/TEX/PDFLATEXCOM.py
index 36372a80..09283f30 100644
--- a/test/TEX/PDFLATEXCOM.py
+++ b/test/TEX/PDFLATEXCOM.py
@@ -41,7 +41,7 @@ test.write('mypdflatex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*latex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*latex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/PDFLATEXCOMSTR.py b/test/TEX/PDFLATEXCOMSTR.py
index e91ba873..c751e8e4 100644
--- a/test/TEX/PDFLATEXCOMSTR.py
+++ b/test/TEX/PDFLATEXCOMSTR.py
@@ -43,7 +43,7 @@ test.write('mypdflatex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*latex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*latex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/PDFLATEXFLAGS.py b/test/TEX/PDFLATEXFLAGS.py
index 19c7e5a9..deee9ede 100644
--- a/test/TEX/PDFLATEXFLAGS.py
+++ b/test/TEX/PDFLATEXFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -82,11 +81,10 @@ pdflatex = test.where_is('pdflatex')
 if pdflatex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/PDFTEX.py b/test/TEX/PDFTEX.py
index e9b547dd..321a58ae 100644
--- a/test/TEX/PDFTEX.py
+++ b/test/TEX/PDFTEX.py
@@ -30,8 +30,6 @@ the produced .dvi, .aux and .log files get removed by the -c option,
 and that we can use this to wrap calls to the real latex utility.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -86,11 +84,10 @@ pdftex = test.where_is('pdftex')
 if pdftex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/PDFTEXCOM.py b/test/TEX/PDFTEXCOM.py
index 6d57f2c2..8c31da3b 100644
--- a/test/TEX/PDFTEXCOM.py
+++ b/test/TEX/PDFTEXCOM.py
@@ -41,7 +41,7 @@ test.write('mypdftex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*tex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*tex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/PDFTEXCOMSTR.py b/test/TEX/PDFTEXCOMSTR.py
index 8caa4e37..13abe7a3 100644
--- a/test/TEX/PDFTEXCOMSTR.py
+++ b/test/TEX/PDFTEXCOMSTR.py
@@ -43,7 +43,7 @@ test.write('mypdftex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*tex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*tex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/PDFTEXFLAGS.py b/test/TEX/PDFTEXFLAGS.py
index d1b82fe0..ce27e82d 100644
--- a/test/TEX/PDFTEXFLAGS.py
+++ b/test/TEX/PDFTEXFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -75,11 +74,10 @@ pdftex = test.where_is('pdftex')
 if pdftex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py
index 58ec40d5..0de34589 100644
--- a/test/TEX/TEX.py
+++ b/test/TEX/TEX.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -30,8 +31,6 @@ the produced .dvi, .aux and .log files get removed by the -c option,
 and that we can use this to wrap calls to the real latex utility.
 """
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -86,11 +85,10 @@ tex = test.where_is('tex')
 if tex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
@@ -173,18 +171,18 @@ Run \texttt{latex}, then \texttt{bibtex}, then \texttt{latex} twice again \cite{
     test.must_exist('bar-latex.dvi')
 
     test.run(stderr = None)
-    output_lines = string.split(test.stdout(), '\n')
+    output_lines = test.stdout().split('\n')
 
-    reruns = filter(lambda x: string.find(x, 'latex -interaction=nonstopmode -recorder rerun.tex') != -1, output_lines)
+    reruns = [x for x in output_lines if x.find('latex -interaction=nonstopmode -recorder rerun.tex') != -1]
     if len(reruns) != 2:
         print "Expected 2 latex calls, got %s:" % len(reruns)
-        print string.join(reruns, '\n')
+        print '\n'.join(reruns)
         test.fail_test()
 
-    bibtex = filter(lambda x: string.find(x, 'bibtex bibtex-test') != -1, output_lines)
+    bibtex = [x for x in output_lines if x.find('bibtex bibtex-test') != -1]
     if len(bibtex) != 1:
         print "Expected 1 bibtex call, got %s:" % len(bibtex)
-        print string.join(bibtex, '\n')
+        print '\n'.join(bibtex)
         test.fail_test()
 
 test.pass_test()
diff --git a/test/TEX/TEXCOM.py b/test/TEX/TEXCOM.py
index 6336730e..1cadd634 100644
--- a/test/TEX/TEXCOM.py
+++ b/test/TEX/TEXCOM.py
@@ -41,7 +41,7 @@ test.write('mytex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*tex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*tex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/TEXCOMSTR.py b/test/TEX/TEXCOMSTR.py
index d4ebe573..f1ead7fb 100644
--- a/test/TEX/TEXCOMSTR.py
+++ b/test/TEX/TEXCOMSTR.py
@@ -42,7 +42,7 @@ test.write('mytex.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*tex*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*tex*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/TEX/TEXFLAGS.py b/test/TEX/TEXFLAGS.py
index efb66061..7ae86ffc 100644
--- a/test/TEX/TEXFLAGS.py
+++ b/test/TEX/TEXFLAGS.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 
 import TestSCons
 
@@ -75,11 +74,10 @@ tex = test.where_is('tex')
 if tex:
 
     test.write("wrapper.py", """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
     test.write('SConstruct', """
 import os
diff --git a/test/ToolSurrogate.py b/test/ToolSurrogate.py
index 82e0371f..a343d62d 100644
--- a/test/ToolSurrogate.py
+++ b/test/ToolSurrogate.py
@@ -34,7 +34,6 @@ import TestSCons
 test = TestSCons.TestSCons()
 
 test.write('SConstruct', """\
-import string
 class Curry:
     def __init__(self, fun, *args, **kwargs):
         self.fun = fun
@@ -48,13 +47,13 @@ class Curry:
         else:
             kw = kwargs or self.kwargs
 
-        return apply(self.fun, self.pending + args, kw)
+        return self.fun(*self.pending + args, **kw)
 
 def Str(target, source, env, cmd=""):
     result = []
     for cmd in env.subst_list(cmd, target=target, source=source):
-        result.append(string.join(map(str, cmd)))
-    return string.join(result, '\\n')
+        result.append(" ".join(map(str, cmd)))
+    return '\\n'.join(result)
 
 class ToolSurrogate:
     def __init__(self, tool, variable, func):
@@ -82,7 +81,7 @@ ToolList = {
 }
 
 platform = ARGUMENTS['platform']
-tools = map(lambda t: apply(ToolSurrogate, t), ToolList[platform])
+tools = [ToolSurrogate(*t) for t in ToolList[platform]]
 
 env = Environment(tools=tools, PROGSUFFIX='.exe', OBJSUFFIX='.obj')
 env.Program('foo.c')
diff --git a/test/Touch.py b/test/Touch.py
index bf85dcb7..7c1817ae 100644
--- a/test/Touch.py
+++ b/test/Touch.py
@@ -39,10 +39,9 @@ Execute(Touch('f1'))
 Execute(Touch(File('f1-File')))
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Action(cat)
 env = Environment()
diff --git a/test/Value.py b/test/Value.py
index 9f0645ec..72a43fa9 100644
--- a/test/Value.py
+++ b/test/Value.py
@@ -73,9 +73,8 @@ env.B3('f5.out', V)
 
 test.write('put.py', """\
 import os
-import string
 import sys
-open(sys.argv[-1],'wb').write(string.join(sys.argv[1:-2]))
+open(sys.argv[-1],'wb').write(" ".join(sys.argv[1:-2]))
 """)
 
 # Run all of the tests with both types of source signature
diff --git a/test/Variables/BoolVariable.py b/test/Variables/BoolVariable.py
index 3630fc89..37130c0e 100644
--- a/test/Variables/BoolVariable.py
+++ b/test/Variables/BoolVariable.py
@@ -29,7 +29,6 @@ Test the BoolVariable canned Variable type.
 """
 
 import os.path
-import string
 
 try:
     True, False
@@ -44,7 +43,7 @@ test = TestSCons.TestSCons()
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Variables/EnumVariable.py b/test/Variables/EnumVariable.py
index 241a9b93..bb85f4c9 100644
--- a/test/Variables/EnumVariable.py
+++ b/test/Variables/EnumVariable.py
@@ -29,7 +29,6 @@ Test the EnumVariable canned Variable type.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -38,7 +37,7 @@ test = TestSCons.TestSCons()
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Variables/ListVariable.py b/test/Variables/ListVariable.py
index 2dc7d4bf..e5be6251 100644
--- a/test/Variables/ListVariable.py
+++ b/test/Variables/ListVariable.py
@@ -29,7 +29,6 @@ Test the ListVariable canned Variable type.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -38,7 +37,7 @@ test = TestSCons.TestSCons()
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     r = result[1:len(expect)+1]
     assert r == expect, (r, expect)
 
diff --git a/test/Variables/PackageVariable.py b/test/Variables/PackageVariable.py
index d6260556..6ad7fc12 100644
--- a/test/Variables/PackageVariable.py
+++ b/test/Variables/PackageVariable.py
@@ -29,7 +29,6 @@ Test the PackageVariable canned Variable type.
 """
 
 import os.path
-import string
 
 try:
     True, False
@@ -44,7 +43,7 @@ test = TestSCons.TestSCons()
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 
diff --git a/test/Variables/PathVariable.py b/test/Variables/PathVariable.py
index 447d3699..bfe82bad 100644
--- a/test/Variables/PathVariable.py
+++ b/test/Variables/PathVariable.py
@@ -30,7 +30,6 @@ various canned validators.
 """
 
 import os.path
-import string
 
 import TestSCons
 
@@ -39,7 +38,7 @@ test = TestSCons.TestSCons()
 SConstruct_path = test.workpath('SConstruct')
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 #### test PathVariable ####
diff --git a/test/Variables/Variables.py b/test/Variables/Variables.py
index a6ed74f1..454e32e4 100644
--- a/test/Variables/Variables.py
+++ b/test/Variables/Variables.py
@@ -25,23 +25,19 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import TestSCons
-import string
 
 test = TestSCons.TestSCons()
 
 test.write('SConstruct', """
-import string
 env = Environment()
 print env['CC']
-print string.join(env['CCFLAGS'])
+print " ".join(env['CCFLAGS'])
 Default(env.Alias('dummy', None))
 """)
 test.run()
-cc, ccflags = string.split(test.stdout(), '\n')[1:3]
+cc, ccflags = test.stdout().split('\n')[1:3]
 
 test.write('SConstruct', """
-import string
-
 # test validator.  Change a key and add a new one to the environment
 def validator(key, value, environ):
     environ[key] = "v"
@@ -106,15 +102,15 @@ Help('Variables settable in custom.py or on the command line:\\n' + opts.Generat
 print env['RELEASE_BUILD']
 print env['DEBUG_BUILD']
 print env['CC']
-print string.join(env['CCFLAGS'])
+print " ".join(env['CCFLAGS'])
 print env['VALIDATE']
 print env['valid_key']
 
 # unspecified variables should not be set:
-assert not env.has_key('UNSPECIFIED')
+assert 'UNSPECIFIED' not in env
 
 # undeclared variables should be ignored:
-assert not env.has_key('UNDECLARED')
+assert 'UNDECLARED' not in env
 
 # calling Update() should not effect variables that
 # are not declared on the variables object:
@@ -128,26 +124,26 @@ Default(env.Alias('dummy', None))
 """)
 
 def check(expect):
-    result = string.split(test.stdout(), '\n')
+    result = test.stdout().split('\n')
     assert result[1:len(expect)+1] == expect, (result[1:len(expect)+1], expect)
 
 test.run()
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='RELEASE_BUILD=1')
-check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
+check(['1', '1', cc, (ccflags + ' -O -g').strip(), 'v', 'v'])
 
 test.run(arguments='RELEASE_BUILD=1 DEBUG_BUILD=0')
-check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
+check(['1', '0', cc, (ccflags + ' -O').strip(), 'v', 'v'])
 
 test.run(arguments='CC=not_a_c_compiler')
-check(['0', '1', 'not_a_c_compiler', string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', 'not_a_c_compiler', (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='UNDECLARED=foo')
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.run(arguments='CCFLAGS=--taco')
-check(['0', '1', cc, string.strip(ccflags + ' -g'), 'v', 'v'])
+check(['0', '1', cc, (ccflags + ' -g').strip(), 'v', 'v'])
 
 test.write('custom.py', """
 DEBUG_BUILD=0
@@ -155,10 +151,10 @@ RELEASE_BUILD=1
 """)
 
 test.run()
-check(['1', '0', cc, string.strip(ccflags + ' -O'), 'v', 'v'])
+check(['1', '0', cc, (ccflags + ' -O').strip(), 'v', 'v'])
 
 test.run(arguments='DEBUG_BUILD=1')
-check(['1', '1', cc, string.strip(ccflags + ' -O -g'), 'v', 'v'])
+check(['1', '1', cc, (ccflags + ' -O -g').strip(), 'v', 'v'])
 
 test.run(arguments='-h',
          stdout = """\
diff --git a/test/VariantDir/SConscript-variant_dir.py b/test/VariantDir/SConscript-variant_dir.py
index 088ead21..068c3123 100644
--- a/test/VariantDir/SConscript-variant_dir.py
+++ b/test/VariantDir/SConscript-variant_dir.py
@@ -59,10 +59,9 @@ var9 = Dir('../build/var9')
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(BUILDERS={'Cat':Builder(action=cat)},
diff --git a/test/VariantDir/VariantDir.py b/test/VariantDir/VariantDir.py
index 396f6a9f..7b89db4d 100644
--- a/test/VariantDir/VariantDir.py
+++ b/test/VariantDir/VariantDir.py
@@ -21,11 +21,10 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _exe = TestSCons._exe
@@ -229,10 +228,9 @@ test.write(['work1', 'src', 'b2.for'], r"""
 def blank_output(err):
     if not err:
         return 1
-    stderrlines = filter(lambda l: l, string.split(err, '\n'))
+    stderrlines = [l for l in err.split('\n') if l]
     msg = "warning: tempnam() possibly used unsafely"
-    stderrlines = filter(lambda l, msg=msg: string.find(l, msg) == -1,
-                         stderrlines)
+    stderrlines = [l for l in stderrlines if l.find(msg) == -1]
     return len(stderrlines) == 0
 
 test.run(chdir='work1', arguments = '. ../build', stderr=None)
diff --git a/test/VariantDir/errors.py b/test/VariantDir/errors.py
index f31cd71c..d1490d42 100644
--- a/test/VariantDir/errors.py
+++ b/test/VariantDir/errors.py
@@ -57,10 +57,9 @@ def fake_scan(node, env, target):
 
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(BUILDERS={'Build':Builder(action=cat)},
diff --git a/test/WhereIs.py b/test/WhereIs.py
index 7a93af4f..dc127b62 100644
--- a/test/WhereIs.py
+++ b/test/WhereIs.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -57,13 +56,13 @@ pathdirs_1234 = [ test.workpath('sub1'),
                   test.workpath('sub2'),
                   test.workpath('sub3'),
                   test.workpath('sub4'),
-                ] + string.split(env_path, os.pathsep)
+                ] + env_path.split(os.pathsep)
 
 pathdirs_1243 = [ test.workpath('sub1'),
                   test.workpath('sub2'),
                   test.workpath('sub4'),
                   test.workpath('sub3'),
-                ] + string.split(env_path, os.pathsep)
+                ] + env_path.split(os.pathsep)
 
 test.write('SConstruct', """
 SConscript('%s')
@@ -77,13 +76,13 @@ print WhereIs('xxx.exe', %s, reject=%s)
 env.Replace( XXXNAME='xxx.exe' )
 print env.WhereIs( '$XXXNAME', %s )
 """ % (subdir_SConscript,
-       repr(string.join(pathdirs_1234, os.pathsep)),
-       repr(string.join(pathdirs_1243, os.pathsep)),
+       repr(os.pathsep.join(pathdirs_1234)),
+       repr(os.pathsep.join(pathdirs_1243)),
        repr(pathdirs_1234),
        repr(pathdirs_1243),
        repr(pathdirs_1243),
        repr(sub4_xxx_exe),
-       repr(string.join(pathdirs_1243, os.pathsep)),
+       repr(os.pathsep.join(pathdirs_1243)),
       ))
 
 test.write(subdir_SConscript, """
@@ -93,13 +92,13 @@ print WhereIs('xxx.exe', %s)
 print env.WhereIs('xxx.exe', %s)
 print WhereIs('xxx.exe', %s)
 print WhereIs('xxx.exe', %s)
-""" % (repr(string.join(pathdirs_1234, os.pathsep)),
-       repr(string.join(pathdirs_1243, os.pathsep)),
+""" % (repr(os.pathsep.join(pathdirs_1234)),
+       repr(os.pathsep.join(pathdirs_1243)),
        repr(pathdirs_1234),
        repr(pathdirs_1243),
       ))
 
-os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
+os.environ['PATH'] = os.pathsep.join(pathdirs_1234)
 
 expect = [ test.workpath(sub3_xxx_exe),
            test.workpath(sub3_xxx_exe),
@@ -116,10 +115,10 @@ expect = [ test.workpath(sub3_xxx_exe),
          ]
 
 test.run(arguments = ".",
-         stdout = test.wrap_stdout(read_str = string.join(expect, "\n") + "\n",
+         stdout = test.wrap_stdout(read_str = "\n".join(expect) + "\n",
                                    build_str = "scons: `.' is up to date.\n"))
 
-os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
+os.environ['PATH'] = os.pathsep.join(pathdirs_1243)
 
 expect = [ test.workpath(sub4_xxx_exe),
            test.workpath(sub3_xxx_exe),
@@ -136,7 +135,7 @@ expect = [ test.workpath(sub4_xxx_exe),
          ]
 
 test.run(arguments = ".",
-         stdout = test.wrap_stdout(read_str = string.join(expect, "\n") + "\n",
+         stdout = test.wrap_stdout(read_str = "\n".join(expect) + "\n",
                                    build_str = "scons: `.' is up to date.\n"))
 
 
diff --git a/test/Win32/bad-drive.py b/test/Win32/bad-drive.py
index ffa5aad9..f2a55b8c 100644
--- a/test/Win32/bad-drive.py
+++ b/test/Win32/bad-drive.py
@@ -31,8 +31,8 @@ with an invalid drive letter.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
+from string import uppercase
 
 import TestSCons
 
@@ -43,8 +43,8 @@ if sys.platform != 'win32':
     test.skip_test(msg)
 
 bad_drive = None
-for i in range(len(string.uppercase)-1, -1, -1):
-    d = string.uppercase[i]
+for i in range(len(uppercase)-1, -1, -1):
+    d = uppercase[i]
     if not os.path.isdir(d + ':' + os.sep):
         bad_drive = d + ':'
         break
@@ -57,7 +57,7 @@ if bad_drive is None:
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
+    source = list(map(str, source))
     print 'cat(%%s) > %%s' %% (source, target)
     f = open(target, "wb")
     for src in source:
diff --git a/test/Win32/default-drive.py b/test/Win32/default-drive.py
index 84e6389f..f427a203 100644
--- a/test/Win32/default-drive.py
+++ b/test/Win32/default-drive.py
@@ -46,10 +46,9 @@ test.subdir('src')
 test.write(['src', 'SConstruct'], """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 env = Environment(BUILDERS={'Build':Builder(action=cat)})
diff --git a/test/Win32/mingw.py b/test/Win32/mingw.py
index 969ccfbf..33854224 100644
--- a/test/Win32/mingw.py
+++ b/test/Win32/mingw.py
@@ -29,7 +29,6 @@ This tests the MinGW C/C++ compiler support.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import sys
 
 import TestSCons
@@ -53,7 +52,7 @@ sys.exit(0)
 """)
 
 test.run()
-if string.find(test.stdout(), 'mingw exists') == -1:
+if test.stdout().find('mingw exists') == -1:
     test.skip_test("No MinGW on this system, skipping test.\n")
 
 test.subdir('header')
@@ -149,8 +148,8 @@ test.write('header/resource2.h', '''
 # that comes out of stderr:
 test.run(arguments='test.exe', stderr='.*')
 # ensure the source def for cshared.def got used, and there wasn't a target def for chshared.dll:
-test.fail_test(string.find(test.stdout(), 'cshared.def') == -1)
-test.fail_test(string.find(test.stdout(), '-Wl,--output-def,cshared.def') != -1)
+test.fail_test(test.stdout().find('cshared.def') == -1)
+test.fail_test(test.stdout().find('-Wl,--output-def,cshared.def') != -1)
 # ensure the target def got generated for the shared.dll:
 test.fail_test(not os.path.exists(test.workpath('shared.def')))
 test.run(program=test.workpath('test.exe'), stdout='test.cpp\nshared.cpp\nstatic.cpp\ncshared.c\n2001 resource.rc\n')
diff --git a/test/Win32/win32pathmadness.py b/test/Win32/win32pathmadness.py
index 875d9598..dd04ec4d 100644
--- a/test/Win32/win32pathmadness.py
+++ b/test/Win32/win32pathmadness.py
@@ -33,7 +33,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import TestSCons
 import sys
 import TestCmd
-import string
 import os.path
 
 test = TestSCons.TestSCons(match=TestCmd.match_re)
@@ -89,10 +88,10 @@ int bar(void);
 
 drive, rest = os.path.splitdrive(test.workpath('src'))
 
-drive_upper = string.upper(drive)
-drive_lower = string.lower(drive)
-rest_upper = rest[0] + string.upper(rest[1]) + rest[2:]
-rest_lower = rest[0] + string.lower(rest[1]) + rest[2:]
+drive_upper = drive.upper()
+drive_lower = drive.lower()
+rest_upper = rest[0] + rest[1].upper() + rest[2:]
+rest_lower = rest[0] + rest[1].lower() + rest[2:]
 
 combinations = [
     os.path.join(drive_upper, rest_upper),
diff --git a/test/YACC/YACC.py b/test/YACC/YACC.py
index a9ef57cb..59067f31 100644
--- a/test/YACC/YACC.py
+++ b/test/YACC/YACC.py
@@ -45,7 +45,6 @@ test = TestSCons.TestSCons()
 
 test.write('myyacc.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'o:', [])
 output = None
@@ -55,7 +54,7 @@ for opt, arg in cmd_opts:
     else: opt_string = opt_string + ' ' + opt
 for a in args:
     contents = open(a, 'rb').read()
-    output.write(string.replace(contents, 'YACC', 'myyacc.py'))
+    output.write(contents.replace('YACC', 'myyacc.py'))
 output.close()
 sys.exit(0)
 """)
diff --git a/test/YACC/YACCCOM.py b/test/YACC/YACCCOM.py
index 14c4f010..4e43676d 100644
--- a/test/YACC/YACCCOM.py
+++ b/test/YACC/YACCCOM.py
@@ -41,7 +41,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*yacc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*yacc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/YACC/YACCCOMSTR.py b/test/YACC/YACCCOMSTR.py
index f9204401..eaf3fded 100644
--- a/test/YACC/YACCCOMSTR.py
+++ b/test/YACC/YACCCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*yacc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*yacc*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/YACC/YACCFLAGS.py b/test/YACC/YACCFLAGS.py
index f36cb944..f0b698bf 100644
--- a/test/YACC/YACCFLAGS.py
+++ b/test/YACC/YACCFLAGS.py
@@ -47,7 +47,6 @@ test.subdir('in')
 
 test.write('myyacc.py', """
 import getopt
-import string
 import sys
 cmd_opts, args = getopt.getopt(sys.argv[1:], 'o:I:x', [])
 output = None
@@ -59,8 +58,8 @@ for opt, arg in cmd_opts:
     else: opt_string = opt_string + ' ' + opt
 for a in args:
     contents = open(a, 'rb').read()
-    contents = string.replace(contents, 'YACCFLAGS', opt_string)
-    contents = string.replace(contents, 'I_ARGS', i_arguments)
+    contents = contents.replace('YACCFLAGS', opt_string)
+    contents = contents.replace('I_ARGS', i_arguments)
     output.write(contents)
 output.close()
 sys.exit(0)
diff --git a/test/YACC/YACCHFILESUFFIX.py b/test/YACC/YACCHFILESUFFIX.py
index ee554b6b..8801aea7 100644
--- a/test/YACC/YACCHFILESUFFIX.py
+++ b/test/YACC/YACCHFILESUFFIX.py
@@ -40,7 +40,6 @@ test = TestSCons.TestSCons()
 test.write('myyacc.py', """\
 import getopt
 import os.path
-import string
 import sys
 opts, args = getopt.getopt(sys.argv[1:], 'do:')
 for o, a in opts:
@@ -48,11 +47,11 @@ for o, a in opts:
         outfile = open(a, 'wb')
 for f in args:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*yacc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*yacc*/\\n']:
         outfile.write(l)
 outfile.close()
 base, ext = os.path.splitext(args[0])
-open(base+'.hsuffix', 'wb').write(string.join(sys.argv)+'\\n')
+open(base+'.hsuffix', 'wb').write(" ".join(sys.argv)+'\\n')
 sys.exit(0)
 """)
 
diff --git a/test/YACC/YACCHXXFILESUFFIX.py b/test/YACC/YACCHXXFILESUFFIX.py
index 933fbc50..6664356e 100644
--- a/test/YACC/YACCHXXFILESUFFIX.py
+++ b/test/YACC/YACCHXXFILESUFFIX.py
@@ -40,7 +40,6 @@ test = TestSCons.TestSCons()
 test.write('myyacc.py', """\
 import getopt
 import os.path
-import string
 import sys
 opts, args = getopt.getopt(sys.argv[1:], 'do:')
 for o, a in opts:
@@ -48,11 +47,11 @@ for o, a in opts:
         outfile = open(a, 'wb')
 for f in args:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*yacc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*yacc*/\\n']:
         outfile.write(l)
 outfile.close()
 base, ext = os.path.splitext(args[0])
-open(base+'.hxxsuffix', 'wb').write(string.join(sys.argv)+'\\n')
+open(base+'.hxxsuffix', 'wb').write(" ".join(sys.argv)+'\\n')
 sys.exit(0)
 """)
 
diff --git a/test/YACC/YACCVCGFILESUFFIX.py b/test/YACC/YACCVCGFILESUFFIX.py
index 655cc443..0327d8a2 100644
--- a/test/YACC/YACCVCGFILESUFFIX.py
+++ b/test/YACC/YACCVCGFILESUFFIX.py
@@ -39,7 +39,6 @@ test = TestSCons.TestSCons()
 test.write('myyacc.py', """\
 import getopt
 import os.path
-import string
 import sys
 vcg = None
 opts, args = getopt.getopt(sys.argv[1:], 'go:')
@@ -50,12 +49,12 @@ for o, a in opts:
         outfile = open(a, 'wb')
 for f in args:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*yacc*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*yacc*/\\n']:
         outfile.write(l)
 outfile.close()
 if vcg:
     base, ext = os.path.splitext(args[0])
-    open(base+'.vcgsuffix', 'wb').write(string.join(sys.argv)+'\\n')
+    open(base+'.vcgsuffix', 'wb').write(" ".join(sys.argv)+'\\n')
 sys.exit(0)
 """)
 
diff --git a/test/YACC/live.py b/test/YACC/live.py
index 4922c6a7..28e2186d 100644
--- a/test/YACC/live.py
+++ b/test/YACC/live.py
@@ -28,8 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test YACC and YACCFLAGS with a live yacc compiler.
 """
 
-import string
-
 import TestSCons
 
 _exe = TestSCons._exe
@@ -44,11 +42,10 @@ if not yacc:
 
 test.write("wrapper.py",
 """import os
-import string
 import sys
 open('%s', 'wb').write("wrapper.py\\n")
-os.system(string.join(sys.argv[1:], " "))
-""" % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
+os.system(" ".join(sys.argv[1:]))
+""" % test.workpath('wrapper.out').replace('\\', '\\\\'))
 
 test.write('SConstruct', """
 foo = Environment(YACCFLAGS='-d')
diff --git a/test/ZIP/ZIP.py b/test/ZIP/ZIP.py
index 60f3dad1..73e78105 100644
--- a/test/ZIP/ZIP.py
+++ b/test/ZIP/ZIP.py
@@ -26,7 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
 import stat
-import string
 
 import TestSCons
 
@@ -95,7 +94,7 @@ try:
 
     def files(fname):
         zf = zipfile.ZipFile(fname, 'r')
-        return map(lambda x: x.filename, zf.infolist())
+        return [x.filename for x in zf.infolist()]
 
 except ImportError:
     internal_zip = 0
@@ -104,14 +103,14 @@ except ImportError:
 
     def files(fname, test=test, unzip=unzip):
         test.run(program = unzip, arguments = "-l -qq %s" % fname)
-        lines = string.split(test.stdout(), "\n")[:-1]
+        lines = test.stdout().split("\n")[:-1]
         def lastword(line):
-            return string.split(line)[-1]
-        return map(lastword, lines)
+            return line.split()[-1]
+        return list(map(lastword, lines))
 
 if zip:
 
-    marker_out = string.replace(test.workpath('marker.out'), '\\', '\\\\')
+    marker_out = test.workpath('marker.out').replace('\\', '\\\\')
 
     test.write('SConstruct', """\
 def marker(target, source, env):
diff --git a/test/ZIP/ZIPCOM.py b/test/ZIP/ZIPCOM.py
index 6c78824e..e982c58c 100644
--- a/test/ZIP/ZIPCOM.py
+++ b/test/ZIP/ZIPCOM.py
@@ -40,7 +40,7 @@ test.write('myzip.py', r"""
 import sys
 outfile = open(sys.argv[1], 'wb')
 infile = open(sys.argv[2], 'rb')
-for l in filter(lambda l: l != '/*zip*/\n', infile.readlines()):
+for l in [l for l in infile.readlines() if l != '/*zip*/\n']:
     outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/ZIP/ZIPCOMSTR.py b/test/ZIP/ZIPCOMSTR.py
index acc77c71..d91a48d4 100644
--- a/test/ZIP/ZIPCOMSTR.py
+++ b/test/ZIP/ZIPCOMSTR.py
@@ -42,7 +42,7 @@ import sys
 outfile = open(sys.argv[1], 'wb')
 for f in sys.argv[2:]:
     infile = open(f, 'rb')
-    for l in filter(lambda l: l != '/*zip*/\\n', infile.readlines()):
+    for l in [l for l in infile.readlines() if l != '/*zip*/\\n']:
         outfile.write(l)
 sys.exit(0)
 """)
diff --git a/test/custom-concat.py b/test/custom-concat.py
index 9d0e64bc..56c7f642 100644
--- a/test/custom-concat.py
+++ b/test/custom-concat.py
@@ -37,7 +37,7 @@ test.write('SConstruct', """
 def my_concat1(pref, list, suff, env, f=None):
     if f:
         list = f(list)
-    list = map(lambda x, p=pref, s=suff: 'my'+p+x+s+'1', list)
+    list = ['my'+pref+x+suff+'1' for x in list]
     return list
 myflags = '${_stripixes(MYPREFIX, LIST, MYSUFFIX, STRIPPREFIX, STRIPSUFFIX, __env__)}'
 env1 = Environment(MYFLAGS=myflags, _concat = my_concat1,
diff --git a/test/explain/basic.py b/test/explain/basic.py
index fec7b936..7b3e5122 100644
--- a/test/explain/basic.py
+++ b/test/explain/basic.py
@@ -29,7 +29,6 @@ Verify a lot of the basic operation of the --debug=explain option.
 """
 
 import os
-import string
 
 import TestSCons
 
@@ -317,7 +316,7 @@ Import("env")
 env.Cat('file3', ['zzz', 'yyy', 'xxx'])
 """)
 
-python_sep = string.replace(python, '\\', '\\\\')
+python_sep = python.replace('\\', '\\\\')
 
 expect = test.wrap_stdout("""\
 scons: rebuilding `file3' because the dependency order changed:
diff --git a/test/gnutools.py b/test/gnutools.py
index ee082e3d..e1b7e42b 100644
--- a/test/gnutools.py
+++ b/test/gnutools.py
@@ -29,7 +29,6 @@ Testing the gnu tool chain, i.e. the tools 'gcc', 'g++' and 'gnulink'.
 """
 
 import TestSCons
-import string
 import sys
 
 _python_ = TestSCons._python_
@@ -116,8 +115,8 @@ test.run(chdir='work1')
 
 def testObject(test, obj, expect):
     contents = test.read(test.workpath('work1', obj))
-    line1 = string.split(contents,'\n')[0]
-    actual = string.join(string.split(line1))
+    line1 = contents.split('\n')[0]
+    actual = ' '.join(line1.split())
     if not expect == actual:
         print "%s:  %s != %s\n" % (obj, repr(expect), repr(actual))
         test.fail_test()
diff --git a/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py b/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
index 8e391c1a..33656882 100644
--- a/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
+++ b/test/implicit/IMPLICIT_COMMAND_DEPENDENCIES.py
@@ -45,11 +45,10 @@ import sys
 open(sys.argv[1], 'w').write('''\
 #!/usr/bin/env %(python)s
 import os
-import string
 import sys
 fp = open(sys.argv[1], 'wb')
 args = [os.path.split(sys.argv[0])[1]] + sys.argv[1:]
-fp.write(string.join(args) + '\\\\n' + '%(extra)s')
+fp.write(" ".join(args) + '\\\\n' + '%(extra)s')
 for infile in sys.argv[2:]:
     fp.write(open(infile, 'rb').read())
 fp.close()
diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py
index a8bd0589..bc5d11a9 100644
--- a/test/long-lines/signature.py
+++ b/test/long-lines/signature.py
@@ -39,11 +39,10 @@ build_py = test.workpath('build.py')
 
 test.write(build_py, """\
 #!/usr/bin/env python
-import string
 import sys
 if sys.argv[1][0] == '@':
     args = open(sys.argv[1][1:], 'rb').read()
-    args = string.split(args)
+    args = args.split()
 else:
     args = sys.argv[1:]
 fp = open(args[0], 'wb')
diff --git a/test/no-arguments.py b/test/no-arguments.py
index 0fa0d8a6..e447ff69 100644
--- a/test/no-arguments.py
+++ b/test/no-arguments.py
@@ -39,7 +39,7 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', r"""
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
+    source = list(map(str, source))
     print 'cat(%s) > %s' % (source, target)
     f = open(target, "wb")
     for src in source:
diff --git a/test/no-target.py b/test/no-target.py
index 6c910134..be2cd51e 100644
--- a/test/no-target.py
+++ b/test/no-target.py
@@ -42,10 +42,9 @@ SConscript(r'%s')
 test.write(subdir_SConscript, r"""
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 
 b = Builder(action=cat, suffix='.out', src_suffix='.in')
diff --git a/test/option--C.py b/test/option--C.py
index 3d93d2f7..1a9a72b7 100644
--- a/test/option--C.py
+++ b/test/option--C.py
@@ -25,16 +25,15 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os
-import string
 import types
 
 import TestSCons
 
 def match_normcase(lines, matches):
     if not type(lines) is types.ListType:
-        lines = string.split(lines, "\n")
+        lines = lines.split("\n")
     if not type(matches) is types.ListType:
-        matches = string.split(matches, "\n")
+        matches = matches.split("\n")
     if len(lines) != len(matches):
         return
     for i in range(len(lines)):
diff --git a/test/option--random.py b/test/option--random.py
index 0e5cc668..a9b9b9d8 100644
--- a/test/option--random.py
+++ b/test/option--random.py
@@ -37,10 +37,9 @@ test = TestSCons.TestSCons()
 test.write('SConscript', """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 env = Environment(BUILDERS={'Cat':Builder(action=cat)})
 env.Cat('aaa.out', 'aaa.in')
diff --git a/test/option-j.py b/test/option-j.py
index 83597caf..3eb7bd32 100644
--- a/test/option-j.py
+++ b/test/option-j.py
@@ -30,7 +30,6 @@ SConscript settable option.
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import os.path
-import string
 
 import TestSCons
 
@@ -91,10 +90,10 @@ def RunTest(args, extra):
     test.run(arguments = args)
 
     str = test.read("f1")
-    start1,finish1 = map(float, string.split(str, "\n"))
+    start1,finish1 = list(map(float, str.split("\n")))
 
     str = test.read("f2")
-    start2,finish2 = map(float, string.split(str, "\n"))
+    start2,finish2 = list(map(float, str.split("\n")))
 
     return start2, finish1
 
@@ -149,10 +148,10 @@ warn = \
 test.must_contain_all_lines(test.stderr(), [warn])
 
 str = test.read("f1")
-start1,finish1 = map(float, string.split(str, "\n"))
+start1,finish1 = list(map(float, str.split("\n")))
 
 str = test.read("f2")
-start2,finish2 = map(float, string.split(str, "\n"))
+start2,finish2 = list(map(float, str.split("\n")))
 
 test.fail_test(start2 < finish1)
 
diff --git a/test/option/debug-count.py b/test/option/debug-count.py
index a52e2014..c233bf5d 100644
--- a/test/option/debug-count.py
+++ b/test/option/debug-count.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -28,7 +29,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 Test that the --debug=count option works.
 """
 
-import string
 import re
 
 import TestSCons
@@ -73,11 +73,11 @@ for args in ['-h --debug=count', '--debug=count']:
     test.run(arguments = args)
     stdout = test.stdout()
 
-    missing = filter(lambda o: find_object_count(o, stdout) is None, objects)
+    missing = [o for o in objects if find_object_count(o, stdout) is None]
 
     if missing:
         print "Missing the following object lines from '%s' output:" % args
-        print "\t", string.join(missing)
+        print "\t", ' '.join(missing)
         print "STDOUT =========="
         print stdout
         test.fail_test(1)
diff --git a/test/option/debug-memory.py b/test/option/debug-memory.py
index 08385015..c9165ede 100644
--- a/test/option/debug-memory.py
+++ b/test/option/debug-memory.py
@@ -29,7 +29,6 @@ Test that the --debug=memory option works.
 """
 
 import re
-import string
 
 import TestSCons
 
@@ -60,7 +59,7 @@ test.write('file.in', "file.in\n")
 
 test.run(arguments = '--debug=memory')
 
-lines = string.split(test.stdout(), '\n')
+lines = test.stdout().split('\n')
 
 test.fail_test(re.match(r'Memory before reading SConscript files: +\d+', lines[-5]) is None)
 test.fail_test(re.match(r'Memory after reading SConscript files: +\d+', lines[-4]) is None)
@@ -71,7 +70,7 @@ test.fail_test(re.match(r'Memory after building targets: +\d+', lines[-2]) is No
 
 test.run(arguments = '-h --debug=memory')
 
-lines = string.split(test.stdout(), '\n')
+lines = test.stdout().split('\n')
 
 test.fail_test(re.match(r'Memory before reading SConscript files: +\d+', lines[-3]) is None)
 test.fail_test(re.match(r'Memory after reading SConscript files: +\d+', lines[-2]) is None)
diff --git a/test/option/debug-presub.py b/test/option/debug-presub.py
index b5038215..28eeb834 100644
--- a/test/option/debug-presub.py
+++ b/test/option/debug-presub.py
@@ -39,10 +39,9 @@ sys.exit(0)
 test.write('SConstruct', """\
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 FILE = Builder(action="$FILECOM")
 TEMP = Builder(action="$TEMPCOM")
diff --git a/test/option/debug-time.py b/test/option/debug-time.py
index d9ca2372..a1e0254f 100644
--- a/test/option/debug-time.py
+++ b/test/option/debug-time.py
@@ -25,7 +25,6 @@
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
 import TestSCons
-import string
 import re
 import time
 
@@ -110,7 +109,7 @@ complete_time = time.time() - start_time
 expected_total_time = complete_time - overhead
 
 pattern = r'Command execution time: (\d+\.\d+) seconds'
-times = map(float, re.findall(pattern, test.stdout()))
+times = list(map(float, re.findall(pattern, test.stdout())))
 expected_command_time = reduce(lambda x, y: x + y, times, 0.0)
 
 
@@ -153,7 +152,7 @@ outside of the 15%% tolerance.
 """ % locals())
 
 if failures or warnings:
-    print string.join([test.stdout()] + failures + warnings, '\n')
+    print '\n'.join([test.stdout()] + failures + warnings)
 if failures:
     test.fail_test(1)
 
@@ -190,7 +189,7 @@ outside of the 1%% tolerance.
 """ % locals())
 
 if failures:
-    print string.join([test.stdout()] + failures, '\n')
+    print '\n'.join([test.stdout()] + failures)
     test.fail_test(1)
 
 test.run(arguments = "-j4 --debug=time . SLEEP=1")
diff --git a/test/option/help-options.py b/test/option/help-options.py
index 9a873068..0f4dd4d6 100644
--- a/test/option/help-options.py
+++ b/test/option/help-options.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -29,7 +30,6 @@ Verify behavior of the -H and --help-options options.
 """
 
 import re
-import string
 
 import TestSCons
 
@@ -53,13 +53,13 @@ test.must_contain_all_lines(test.stdout(), expect)
 ignored_re = re.compile('.*Ignored for compatibility\\.\n', re.S)
 stdout = ignored_re.sub('', test.stdout())
 
-lines = string.split(stdout, '\n')
-lines = filter(lambda x: x[:3] == '  -', lines)
-lines = map(lambda x: x[3:], lines)
-lines = map(lambda x: x[0] == '-' and x[1:] or x, lines)
-options = map(lambda x: string.split(x)[0], lines)
-options = map(lambda x: x[-1] == ',' and x[:-1] or x, options)
-lowered = map(lambda x: string.lower(x), options)
+lines = stdout.split('\n')
+lines = [x for x in lines if x[:3] == '  -']
+lines = [x[3:] for x in lines]
+lines = [x[0] == '-' and x[1:] or x for x in lines]
+options = [x.split()[0] for x in lines]
+options = [x[-1] == ',' and x[:-1] or x for x in options]
+lowered = [x.lower() for x in options]
 sorted = lowered[:]
 sorted.sort()
 if lowered != sorted:
diff --git a/test/option/md5-chunksize.py b/test/option/md5-chunksize.py
index 9d15e841..acd34922 100644
--- a/test/option/md5-chunksize.py
+++ b/test/option/md5-chunksize.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -90,7 +88,7 @@ test.pass_test()
 #
 test2 = TestSCons.TestSCons()
 
-if string.find(sys.platform, 'linux') == -1:
+if sys.platform.find('linux') == -1:
     test2.skip_test("skipping test on non-Linux platform '%s'\n" % sys.platform)
 
 dd = test2.where_is('dd')
diff --git a/test/option/profile.py b/test/option/profile.py
index ed5bc0aa..ab99dab4 100644
--- a/test/option/profile.py
+++ b/test/option/profile.py
@@ -21,10 +21,10 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
 import StringIO
 import sys
 
@@ -96,8 +96,8 @@ expect = [
 test.must_contain_all_lines(test.stdout(), expect)
 
 expect = 'Memory before reading SConscript files'
-lines = string.split(test.stdout(), '\n')
-memory_lines = filter(lambda l, e=expect: string.find(l, e) != -1, lines)
+lines = test.stdout().split('\n')
+memory_lines = [l for l in lines if l.find(expect) != -1]
 
 test.fail_test(len(memory_lines) != 1)
 
diff --git a/test/option/stack-size.py b/test/option/stack-size.py
index 9458356c..3d7a7151 100644
--- a/test/option/stack-size.py
+++ b/test/option/stack-size.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -81,7 +79,7 @@ expected_stdout = test.wrap_stdout("""\
 %(_python_)s ../build.py f2.out f2.in
 """ % locals())
 
-re_expected_stdout = string.replace(expected_stdout, '\\', '\\\\')
+re_expected_stdout = expected_stdout.replace('\\', '\\\\')
 
 expect_unsupported = """
 scons: warning: Setting stack size is unsupported by this version of Python:
diff --git a/test/option/tree-all.py b/test/option/tree-all.py
index 0bd17175..fc0f6893 100644
--- a/test/option/tree-all.py
+++ b/test/option/tree-all.py
@@ -31,7 +31,6 @@ complete dependencies of a target.
 
 import TestSCons
 import sys
-import string
 
 test = TestSCons.TestSCons()
 
@@ -95,7 +94,7 @@ tree1 = """
 """ % locals()
 
 test.run(arguments = "--tree=all Foo.xxx")
-if string.count(test.stdout(), tree1) != 1:
+if test.stdout().count(tree1) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
@@ -158,13 +157,13 @@ tree3 = """
 """ % locals()
 
 test.run(arguments = "--tree=all,prune .")
-if string.count(test.stdout(), tree3) != 1:
+if test.stdout().count(tree3) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
 
 test.run(arguments = "--tree=prune .")
-if string.count(test.stdout(), tree3) != 1:
+if test.stdout().count(tree3) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
@@ -198,13 +197,13 @@ tree4 = """
 test.run(arguments = '-c Foo.xxx')
 
 test.run(arguments = "--no-exec --tree=all,status Foo.xxx")
-if string.count(test.stdout(), tree4) != 1:
+if test.stdout().count(tree4) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
 
 test.run(arguments = "--no-exec --tree=status Foo.xxx")
-if string.count(test.stdout(), tree4) != 1:
+if test.stdout().count(tree4) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
@@ -221,7 +220,7 @@ THIS SHOULD CAUSE A BUILD FAILURE
 test.run(arguments = "--tree=all Foo.xxx",
          status = 2,
          stderr = None)
-if string.count(test.stdout(), tree1) != 1:
+if test.stdout().count(tree1) != 1:
     sys.stdout.write('Did not find expected tree (or found duplicate) in the following output:\n')
     sys.stdout.write(test.stdout())
     test.fail_test()
diff --git a/test/packaging/convenience-functions.py b/test/packaging/convenience-functions.py
index 95543839..66374e3a 100644
--- a/test/packaging/convenience-functions.py
+++ b/test/packaging/convenience-functions.py
@@ -29,7 +29,6 @@ Test the FindInstalledFiles() and the FindSourceFiles() functions.
 """
 
 import os.path
-import string
 import TestSCons
 
 python = TestSCons.python
@@ -44,8 +43,8 @@ env  = Environment(tools=['default', 'packaging'])
 prog = env.Install( 'bin/', ["f1", "f2"] )
 env.File( "f3" )
 
-src_files = map(str, env.FindSourceFiles())
-oth_files = map(str, env.FindInstalledFiles())
+src_files = list(map(str, env.FindSourceFiles()))
+oth_files = list(map(str, env.FindInstalledFiles()))
 src_files.sort()
 oth_files.sort()
 
@@ -56,8 +55,8 @@ print oth_files
 bin_f1 = os.path.join('bin', 'f1')
 bin_f2 = os.path.join('bin', 'f2')
 
-bin__f1 = string.replace(bin_f1, '\\', '\\\\')
-bin__f2 = string.replace(bin_f2, '\\', '\\\\')
+bin__f1 = bin_f1.replace('\\', '\\\\')
+bin__f2 = bin_f2.replace('\\', '\\\\')
 
 expect_read = """\
 ['SConstruct', 'f1', 'f2', 'f3']
diff --git a/test/preserve-source.py b/test/preserve-source.py
index cd0b3a37..6e090734 100644
--- a/test/preserve-source.py
+++ b/test/preserve-source.py
@@ -34,7 +34,7 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', r"""
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
+    source = list(map(str, source))
     print 'cat(%s) > %s' % (source, target)
     f = open(target, "wb")
     for src in source:
diff --git a/test/python-version.py b/test/python-version.py
index 8230fd3b..3cc33951 100644
--- a/test/python-version.py
+++ b/test/python-version.py
@@ -31,7 +31,6 @@ of Python.
 
 import os
 import re
-import string
 
 import TestCmd
 import TestSCons
diff --git a/test/runtest/fallback.py b/test/runtest/fallback.py
index 6a971f8e..027d79df 100644
--- a/test/runtest/fallback.py
+++ b/test/runtest/fallback.py
@@ -30,7 +30,6 @@ if it can't find qmtest on the $PATH.
 """
 
 import os
-import string
 
 import TestRuntest
 
@@ -42,9 +41,9 @@ test = TestRuntest.TestRuntest(noqmtest=1)
 while test.where_is('qmtest'):
     qmtest=test.where_is('qmtest')
     dir = os.path.split(qmtest)[0]
-    path = string.split(os.environ['PATH'], os.pathsep)
+    path = os.environ['PATH'].split(os.pathsep)
     path.remove(dir)
-    os.environ['PATH'] = string.join(path, os.pathsep)
+    os.environ['PATH'] = os.pathsep.join(path)
 
 test.subdir('test')
 
@@ -83,7 +82,7 @@ testlist = [
     test_pass_py,
 ]
 
-test.run(arguments = string.join(testlist),
+test.run(arguments = ' '.join(testlist),
          status = 1,
          stdout = expect_stdout,
          stderr = expect_stderr)
diff --git a/test/runtest/noqmtest.py b/test/runtest/noqmtest.py
index 78b021d9..99352a10 100644
--- a/test/runtest/noqmtest.py
+++ b/test/runtest/noqmtest.py
@@ -30,7 +30,6 @@ using qmtest.
 """
 
 import os
-import string
 
 import TestRuntest
 
@@ -75,7 +74,7 @@ testlist = [
     test_pass_py,
 ]
 
-test.run(arguments = '--noqmtest %s' % string.join(testlist),
+test.run(arguments = '--noqmtest %s' % ' '.join(testlist),
          status = 1,
          stdout = expect_stdout,
          stderr = expect_stderr)
diff --git a/test/runtest/python.py b/test/runtest/python.py
index 9579746c..5c2f7377 100644
--- a/test/runtest/python.py
+++ b/test/runtest/python.py
@@ -30,7 +30,6 @@ Test that the -P option lets us specify a Python version to use.
 
 import os
 import re
-import string
 
 if not hasattr(os.path, 'pardir'):
     os.path.pardir = '..'
@@ -47,7 +46,7 @@ head, dir = os.path.split(head)
 mypython = os.path.join(head, dir, os.path.pardir, dir, python)
 
 def escape(s):
-    return string.replace(s, '\\', '\\\\')
+    return s.replace('\\', '\\\\')
 
 if re.search('\s', mypython):
     mypythonstring = '"%s"' % escape(mypython)
diff --git a/test/runtest/qmtest.py b/test/runtest/qmtest.py
index 9f9274e3..de04c3fc 100644
--- a/test/runtest/qmtest.py
+++ b/test/runtest/qmtest.py
@@ -30,7 +30,6 @@ not directly via Python.
 """
 
 import os.path
-import string
 
 import TestRuntest
 
@@ -92,7 +91,7 @@ testlist = [
     test_pass_py,
 ]
 
-test.run(arguments='--qmtest %s' % string.join(testlist),
+test.run(arguments='--qmtest %s' % ' '.join(testlist),
          status=1,
          stdout=expect_stdout)
 
diff --git a/test/runtest/xml/output.py b/test/runtest/xml/output.py
index c024f37b..7bf6b2d6 100644
--- a/test/runtest/xml/output.py
+++ b/test/runtest/xml/output.py
@@ -30,7 +30,6 @@ Test writing XML output to a file.
 
 import os
 import re
-import string
 
 import TestCmd
 import TestRuntest
diff --git a/test/scons-time/help/all-subcommands.py b/test/scons-time/help/all-subcommands.py
index 7de7fc66..8641d71f 100644
--- a/test/scons-time/help/all-subcommands.py
+++ b/test/scons-time/help/all-subcommands.py
@@ -21,6 +21,7 @@
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
@@ -45,11 +46,11 @@ except: pass
 
 # Extract all subcommands from the the do_*() functions.
 functions = globals['SConsTimer'].__dict__.keys()
-do_funcs = filter(lambda x: x[:3] == 'do_', functions)
+do_funcs = [x for x in functions if x[:3] == 'do_']
 
-subcommands = map(lambda x: x[3:], do_funcs)
+subcommands = [x[3:] for x in do_funcs]
 
-expect = map(lambda x: '    %s ' % x, subcommands)
+expect = ['    %s ' % x for x in subcommands]
 
 test.run(arguments = 'help')
 
diff --git a/test/sconsign/ghost-entries.py b/test/sconsign/ghost-entries.py
index 2f8ee73e..46916ca3 100644
--- a/test/sconsign/ghost-entries.py
+++ b/test/sconsign/ghost-entries.py
@@ -89,7 +89,7 @@ test.run(arguments="-Q go case=2")
 
 test.write('SConstruct', """\
 Command("d/current.txt", [], [Touch("$TARGET")])
-if ARGUMENTS.has_key('pass') and ARGUMENTS['pass'] == '1':
+if 'pass' in ARGUMENTS and ARGUMENTS['pass'] == '1':
   Command("d/obsolete.txt", [], [Touch("$TARGET")])
 Command("installer.exe", ['d'], [Touch("$TARGET")])
 """)
diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py
index e974c67c..fc658298 100644
--- a/test/sconsign/script/SConsignFile.py
+++ b/test/sconsign/script/SConsignFile.py
@@ -44,10 +44,9 @@ fake_link_py = test.workpath('fake_link.py')
 test.write(fake_cc_py, r"""#!/usr/bin/env python
 import os
 import re
-import string
 import sys
 
-path = string.split(sys.argv[1])
+path = sys.argv[1].split()
 output = open(sys.argv[2], 'wb')
 input = open(sys.argv[3], 'rb')
 
diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py
index 5a7b5cfd..cfd2a7f9 100644
--- a/test/sconsign/script/Signatures.py
+++ b/test/sconsign/script/Signatures.py
@@ -63,10 +63,9 @@ fake_link_py = test.workpath('fake_link.py')
 test.write(fake_cc_py, r"""#!/usr/bin/env python
 import os
 import re
-import string
 import sys
 
-path = string.split(sys.argv[1])
+path = sys.argv[1].split()
 output = open(sys.argv[2], 'wb')
 input = open(sys.argv[3], 'rb')
 
diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py
index 89243295..fe68f913 100644
--- a/test/sconsign/script/no-SConsignFile.py
+++ b/test/sconsign/script/no-SConsignFile.py
@@ -52,10 +52,9 @@ fake_link_py = test.workpath('fake_link.py')
 test.write(fake_cc_py, r"""#!/usr/bin/env python
 import os
 import re
-import string
 import sys
 
-path = string.split(sys.argv[1])
+path = sys.argv[1].split()
 output = open(sys.argv[2], 'wb')
 input = open(sys.argv[3], 'rb')
 
diff --git a/test/special-filenames.py b/test/special-filenames.py
index 86a6e59c..00e4a3df 100644
--- a/test/special-filenames.py
+++ b/test/special-filenames.py
@@ -24,8 +24,6 @@
 
 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 
-import string
-
 import TestSCons
 
 _python_ = TestSCons._python_
@@ -57,7 +55,7 @@ open(sys.argv[1], 'wb').write(open(sys.argv[2], 'rb').read())
 file_names = []
 for fn in attempt_file_names:
     try:
-        in_name = string.replace(fn, '$$', '$') + '.in'
+        in_name = fn.replace('$$', '$') + '.in'
         test.write(in_name, fn + '\n')
         file_names.append(fn)
     except IOError:
@@ -68,7 +66,7 @@ for fn in attempt_file_names:
 def buildFileStr(fn):
     return "env.Build(source=r\"\"\"%s.in\"\"\", target=r\"\"\"%s.out\"\"\")" % ( fn, fn )
 
-xxx =  string.join(map(buildFileStr, file_names), '\n')
+xxx = '\n'.join(map(buildFileStr, file_names))
 
 test.write("SConstruct", """
 env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TARGET $SOURCE')})
@@ -79,7 +77,7 @@ env=Environment(BUILDERS = {'Build' : Builder(action = '%(_python_)s cat.py $TAR
 test.run(arguments='.')
 
 for fn in file_names:
-    out_name = string.replace(fn, '$$', '$') + '.out'
+    out_name = fn.replace('$$', '$') + '.out'
     test.fail_test(test.read(out_name) != fn + '\n')
 
 test.pass_test()
diff --git a/test/srcchange.py b/test/srcchange.py
index 27921a91..d1812973 100644
--- a/test/srcchange.py
+++ b/test/srcchange.py
@@ -44,18 +44,16 @@ test = TestSCons.TestSCons()
 
 test.write('getrevision', """
 #!/usr/bin/env python
-import string
-print string.strip(open('revnum.in','rb').read())
+print open('revnum.in','rb').read().strip()
 """)
 
 test.write('SConstruct', """
 import re
-import string
 
 def subrevision(target, source ,env):
     orig = target[0].get_text_contents()
     new = re.sub('\$REV.*?\$',
-                 '$REV: %%s$'%%string.strip(source[0].get_text_contents()),
+                 '$REV: %%s$'%%source[0].get_text_contents().strip(),
                  target[0].get_text_contents())
     outf = open(str(target[0]),'wb')
     outf.write(new)
diff --git a/test/subdivide.py b/test/subdivide.py
index a80bc46c..2978e08b 100644
--- a/test/subdivide.py
+++ b/test/subdivide.py
@@ -132,8 +132,7 @@ src/sub/bar.c
 """ % locals()
 
 if os.sep == '\\':
-    import string
-    expect = string.replace(expect, '\\', '\\\\')
+    expect = expect.replace('\\', '\\\\')
 
 test.must_match(['src', 'prog.exe'], expect)
 
diff --git a/test/suffixes.py b/test/suffixes.py
index c6ca1d02..74655ec5 100644
--- a/test/suffixes.py
+++ b/test/suffixes.py
@@ -35,10 +35,9 @@ test = TestSCons.TestSCons()
 test.write('SConstruct', """
 def cat(env, source, target):
     target = str(target[0])
-    source = map(str, source)
     f = open(target, "wb")
     for src in source:
-        f.write(open(src, "rb").read())
+        f.write(open(str(src), "rb").read())
     f.close()
 Cat = Builder(action=cat, suffix='.out')
 env = Environment(BUILDERS = {'Cat':Cat})
diff --git a/test/textfile.py b/test/textfile.py
index 27b6b40b..64f8605f 100644
--- a/test/textfile.py
+++ b/test/textfile.py
@@ -27,7 +27,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import TestSCons
 
 import os
-import string
 
 test = TestSCons.TestSCons()
 
@@ -47,8 +46,8 @@ env.Textfile('foo1a.txt', data + [''])
 env.Textfile('foo2a.txt', data + [''], LINESEPARATOR='|*')
 
 # recreate the list with the data wrapped in Value()
-data0 = map(Value, data0)
-data = map(Value, data)
+data0 = list(map(Value, data0))
+data = list(map(Value, data))
 data[2] = data0
 
 env.Substfile('bar1', data)
@@ -63,25 +62,25 @@ test.run(arguments = '.')
 textparts = ['lalala', '42',
              'Goethe', 'Schiller',
              'tanteratei']
-foo1Text  = string.join(textparts, os.linesep)
-foo2Text  = string.join(textparts, '|*')
+foo1Text  = os.linesep.join(textparts)
+foo2Text  = '|*'.join(textparts)
 foo1aText = foo1Text + os.linesep
 foo2aText = foo2Text + '|*'
 
 test.up_to_date(arguments = '.')
 
-files = map(test.workpath, (
+files = list(map(test.workpath, (
             'foo1.txt', 'foo2.txt', 'foo1a.txt', 'foo2a.txt',
             'bar1',     'bar2',     'bar1a.txt', 'bar2a.txt',
-        ))
+        )))
 def check_times():
     # make sure the files didn't get rewritten, because nothing changed:
-    before = map(os.path.getmtime, files)
+    before = list(map(os.path.getmtime, files))
     # introduce a small delay, to make the test valid
     test.sleep()
     # should still be up-to-date
     test.up_to_date(arguments = '.')
-    after = map(os.path.getmtime, files)
+    after = list(map(os.path.getmtime, files))
     test.fail_test(before != after)
 
 # make sure that the file content is as expected
@@ -142,7 +141,7 @@ line3a = 'This line has %subst% substitutions'
 line3b = 'This line has many substitutions'
 
 def matchem(file, lines):
-    lines = string.join(lines, os.linesep)
+    lines = os.linesep.join(lines)
     test.must_match(file, lines)
 
 matchem('text.txt', [line1, line2a, line3a])
diff --git a/timings/hundred/SConstruct b/timings/hundred/SConstruct
index 648c26ac..c824b887 100644
--- a/timings/hundred/SConstruct
+++ b/timings/hundred/SConstruct
@@ -27,8 +27,8 @@ def copy_files( env, target, source ):
     for t, s in zip(target, source):
         open(str(t),  'wb').write(open(str(s), 'rb').read())
 
-source_list = map(lambda t: 'source_%04d' % t, xrange(target_count))
-target_list = map(lambda t: 'target_%04d' % t, xrange(target_count))
+source_list = ['source_%04d' % t for t in xrange(target_count)]
+target_list = ['target_%04d' % t for t in xrange(target_count)]
 
 env = Environment()