From 953dc41b8b720fdcec7955de67d23206214e5125 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 22 Sep 2013 13:08:12 -0400 Subject: Result of raw 2to3 run (2to3-2.7); checkpoint for python3 conversion. --- QMTest/TestCmd.py | 32 +- QMTest/TestCmdTests.py | 136 +- QMTest/TestCommon.py | 66 +- QMTest/TestSCons.py | 52 +- QMTest/TestSConsMSVS.py | 2 +- QMTest/TestSCons_time.py | 4 +- QMTest/TestSConsign.py | 2 +- QMTest/scons_tdb.py | 18 +- bench/bench.py | 8 +- bench/env.__setitem__.py | 16 +- bench/is_types.py | 12 +- bench/timeit.py | 24 +- bin/Command.py | 6 +- bin/SConsDoc.py | 28 +- bin/SConsExamples.py | 20 +- bin/calibrate.py | 8 +- bin/caller-tree.py | 10 +- bin/docs-create-example-outputs.py | 6 +- bin/docs-update-generated.py | 2 +- bin/docs-validate.py | 8 +- bin/install_python.py | 6 +- bin/install_scons.py | 10 +- bin/linecount.py | 30 +- bin/memlogs.py | 8 +- bin/memoicmp.py | 24 +- bin/objcounts.py | 13 +- bin/scons-diff.py | 14 +- bin/scons-proc.py | 14 +- bin/scons-test.py | 60 +- bin/scons-unzip.py | 2 +- bin/scons_dev_master.py | 6 +- bin/svn-bisect.py | 14 +- bin/update-release-info.py | 30 +- bin/xmlagenda.py | 2 +- review.py | 3611 ++++++++++---------- runtest.py | 24 +- src/engine/SCons/Action.py | 47 +- src/engine/SCons/ActionTests.py | 12 +- src/engine/SCons/Builder.py | 20 +- src/engine/SCons/BuilderTests.py | 28 +- src/engine/SCons/CacheDirTests.py | 2 +- src/engine/SCons/Debug.py | 4 +- src/engine/SCons/Defaults.py | 11 +- src/engine/SCons/DefaultsTests.py | 2 +- src/engine/SCons/Environment.py | 59 +- src/engine/SCons/EnvironmentTests.py | 44 +- src/engine/SCons/ErrorsTests.py | 12 +- src/engine/SCons/ExecutorTests.py | 2 +- src/engine/SCons/Job.py | 4 +- src/engine/SCons/Memoize.py | 4 +- src/engine/SCons/MemoizeTests.py | 4 +- src/engine/SCons/Node/FS.py | 23 +- src/engine/SCons/Node/FSTests.py | 34 +- src/engine/SCons/Node/__init__.py | 12 +- src/engine/SCons/Options/__init__.py | 10 +- src/engine/SCons/Platform/__init__.py | 4 +- src/engine/SCons/Platform/aix.py | 2 +- src/engine/SCons/Platform/cygwin.py | 2 +- src/engine/SCons/Platform/darwin.py | 2 +- src/engine/SCons/Platform/hpux.py | 2 +- src/engine/SCons/Platform/irix.py | 2 +- src/engine/SCons/Platform/os2.py | 2 +- src/engine/SCons/Platform/posix.py | 9 +- src/engine/SCons/Platform/sunos.py | 2 +- src/engine/SCons/Platform/win32.py | 4 +- src/engine/SCons/SConf.py | 10 +- src/engine/SCons/SConfTests.py | 2 +- src/engine/SCons/SConsign.py | 16 +- src/engine/SCons/Scanner/C.py | 2 +- src/engine/SCons/Scanner/Fortran.py | 3 +- src/engine/SCons/Scanner/LaTeX.py | 4 +- src/engine/SCons/Scanner/Prog.py | 3 +- src/engine/SCons/Scanner/ProgTests.py | 4 +- src/engine/SCons/Scanner/ScannerTests.py | 2 +- src/engine/SCons/Scanner/__init__.py | 5 +- src/engine/SCons/Script/Interactive.py | 12 +- src/engine/SCons/Script/Main.py | 61 +- src/engine/SCons/Script/SConsOptions.py | 8 +- src/engine/SCons/Script/SConscript.py | 22 +- src/engine/SCons/Script/__init__.py | 8 +- src/engine/SCons/Subst.py | 8 +- src/engine/SCons/SubstTests.py | 48 +- src/engine/SCons/Taskmaster.py | 44 +- src/engine/SCons/TaskmasterTests.py | 10 +- src/engine/SCons/Tool/FortranCommon.py | 2 +- src/engine/SCons/Tool/GettextCommon.py | 12 +- src/engine/SCons/Tool/MSCommon/common.py | 6 +- src/engine/SCons/Tool/MSCommon/netframework.py | 4 +- src/engine/SCons/Tool/MSCommon/sdk.py | 8 +- src/engine/SCons/Tool/MSCommon/vc.py | 24 +- src/engine/SCons/Tool/MSCommon/vs.py | 6 +- src/engine/SCons/Tool/__init__.py | 36 +- src/engine/SCons/Tool/aixcc.py | 2 +- src/engine/SCons/Tool/aixf77.py | 2 +- src/engine/SCons/Tool/aixlink.py | 4 +- src/engine/SCons/Tool/applelink.py | 2 +- src/engine/SCons/Tool/cvf.py | 2 +- src/engine/SCons/Tool/cyglink.py | 2 +- .../docbook-xsl-1.76.1/extensions/docbook.py | 10 +- .../docbook/docbook-xsl-1.76.1/extensions/xslt.py | 12 +- src/engine/SCons/Tool/dvipdf.py | 2 +- src/engine/SCons/Tool/f03.py | 2 +- src/engine/SCons/Tool/f95.py | 2 +- src/engine/SCons/Tool/filesystem.py | 2 +- src/engine/SCons/Tool/gcc.py | 2 +- src/engine/SCons/Tool/gfortran.py | 2 +- src/engine/SCons/Tool/gnulink.py | 2 +- src/engine/SCons/Tool/gs.py | 2 +- src/engine/SCons/Tool/hpcc.py | 2 +- src/engine/SCons/Tool/hplink.py | 2 +- src/engine/SCons/Tool/icc.py | 2 +- src/engine/SCons/Tool/ifl.py | 2 +- src/engine/SCons/Tool/ifort.py | 2 +- src/engine/SCons/Tool/install.py | 26 +- src/engine/SCons/Tool/intelc.py | 19 +- src/engine/SCons/Tool/latex.py | 4 +- src/engine/SCons/Tool/link.py | 18 +- src/engine/SCons/Tool/midl.py | 2 +- src/engine/SCons/Tool/msgfmt.py | 2 +- src/engine/SCons/Tool/msginit.py | 4 +- src/engine/SCons/Tool/msgmerge.py | 2 +- src/engine/SCons/Tool/mslib.py | 2 +- src/engine/SCons/Tool/mslink.py | 12 +- src/engine/SCons/Tool/mssdk.py | 2 +- src/engine/SCons/Tool/msvc.py | 2 +- src/engine/SCons/Tool/msvs.py | 44 +- src/engine/SCons/Tool/msvsTests.py | 2 +- src/engine/SCons/Tool/packaging/__init__.py | 10 +- src/engine/SCons/Tool/packaging/ipk.py | 2 +- src/engine/SCons/Tool/packaging/msi.py | 8 +- src/engine/SCons/Tool/packaging/rpm.py | 12 +- src/engine/SCons/Tool/pdflatex.py | 2 +- src/engine/SCons/Tool/pdftex.py | 2 +- src/engine/SCons/Tool/qt.py | 12 +- src/engine/SCons/Tool/rpmutils.py | 6 +- src/engine/SCons/Tool/sgicc.py | 2 +- src/engine/SCons/Tool/sgilink.py | 2 +- src/engine/SCons/Tool/suncc.py | 2 +- src/engine/SCons/Tool/sunf77.py | 2 +- src/engine/SCons/Tool/sunf90.py | 2 +- src/engine/SCons/Tool/sunf95.py | 2 +- src/engine/SCons/Tool/sunlink.py | 2 +- src/engine/SCons/Tool/tex.py | 94 +- src/engine/SCons/Tool/textfile.py | 5 +- src/engine/SCons/Tool/xgettext.py | 8 +- src/engine/SCons/Util.py | 39 +- src/engine/SCons/UtilTests.py | 28 +- src/engine/SCons/Variables/EnumVariableTests.py | 4 +- src/engine/SCons/Variables/PathVariableTests.py | 16 +- src/engine/SCons/Variables/VariablesTests.py | 2 +- src/engine/SCons/Variables/__init__.py | 18 +- src/engine/SCons/compat/__init__.py | 2 +- src/engine/SCons/compat/_scons_subprocess.py | 48 +- src/engine/SCons/cpp.py | 11 +- src/engine/SCons/cppTests.py | 2 +- src/engine/SCons/dblite.py | 42 +- src/script/scons-time.py | 47 +- src/script/sconsign.py | 40 +- src/test_files.py | 10 +- src/test_interrupts.py | 6 +- src/test_pychecker.py | 2 +- src/test_setup.py | 6 +- src/test_strings.py | 8 +- test/AS/nasm.py | 2 +- test/Actions/unicode-signature.py | 2 +- test/AddOption/help.py | 16 +- test/Batch/action-changed.py | 4 +- test/Chmod.py | 78 +- test/Configure/ConfigureDryRunError.py | 2 +- test/Configure/config-h.py | 52 +- test/Configure/implicit-cache.py | 10 +- test/Copy-Action.py | 4 +- test/Deprecated/Options/Options.py | 2 +- test/Deprecated/SourceCode/BitKeeper/BitKeeper.py | 6 +- test/Deprecated/SourceCode/Subversion.py | 2 +- test/GetBuildFailures/parallel.py | 8 +- test/Glob/glob-libpath.py | 4 +- test/Install/Install.py | 2 +- test/Interactive/version.py | 2 +- test/Java/multi-step.py | 2 +- test/MSVC/batch-longlines.py | 122 +- test/MSVC/msvc.py | 6 +- test/QT/QTFLAGS.py | 2 +- test/QT/copied-env.py | 4 +- test/QT/warnings.py | 4 +- test/SConsignFile/use-dbhash.py | 2 +- test/SConsignFile/use-dbm.py | 2 +- test/SConsignFile/use-dumbdbm.py | 2 +- test/SConsignFile/use-gdbm.py | 2 +- test/SHELL.py | 2 +- test/Scanner/unicode.py | 10 +- test/TEMPFILEPREFIX.py | 2 +- test/TEX/TEX.py | 8 +- test/Value.py | 2 +- test/Variables/Variables.py | 2 +- test/WhereIs.py | 4 +- test/Win32/bad-drive.py | 4 +- test/Win32/default-drive.py | 2 +- test/ZIP/ZIP.py | 2 +- test/ZIP/ZIPROOT.py | 196 +- test/gnutools.py | 2 +- test/import.py | 4 +- test/long-lines/signature.py | 2 +- test/option--random.py | 4 +- test/option-v.py | 4 +- test/option/debug-count.py | 8 +- test/option/debug-time.py | 10 +- test/option/help-options.py | 4 +- test/option/profile.py | 2 +- test/scons-time/run/config/python.py | 2 +- test/scons-time/run/option/python.py | 2 +- test/sconsign/nonwritable.py | 4 +- test/sconsign/script/SConsignFile.py | 4 +- test/sconsign/script/Signatures.py | 4 +- test/sconsign/script/no-SConsignFile.py | 4 +- test/site_scons/sysdirs.py | 142 +- test/spaces.py | 2 +- test/subdivide.py | 4 +- test/update-release-info/update-release-info.py | 2 +- timings/ElectricCloud/TimeSCons-run.py | 2 +- www/gen_sched_table.py | 12 +- 221 files changed, 3292 insertions(+), 3282 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 38e9cd3..4f08d1f 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -285,7 +285,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 division + __author__ = "Steven Knight " __revision__ = "TestCmd.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -355,7 +355,7 @@ except NameError: return isinstance(e, (str, UserString)) else: def is_String(e): - return isinstance(e, (str, unicode, UserString)) + return isinstance(e, (str, UserString)) tempfile.template = 'testcmd.' if os.name in ('posix', 'nt'): @@ -490,17 +490,17 @@ def match_re(lines = None, res = None): if not is_List(res): res = res.split("\n") if len(lines) != len(res): - print "match_re: expected %d lines, found %d"%(len(res), len(lines)) + print("match_re: expected %d lines, found %d"%(len(res), len(lines))) return for i in range(len(lines)): s = "^" + res[i] + "$" try: expr = re.compile(s) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" raise re.error(msg % (repr(s), e.args[0])) if not expr.search(lines[i]): - print "match_re: mismatch at line %d:\n search re='%s'\n line='%s'"%(i,s,lines[i]) + print("match_re: mismatch at line %d:\n search re='%s'\n line='%s'"%(i,s,lines[i])) return return 1 @@ -514,7 +514,7 @@ def match_re_dotall(lines = None, res = None): s = "^" + res + "$" try: expr = re.compile(s, re.DOTALL) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" raise re.error(msg % (repr(s), e.args[0])) return expr.match(lines) @@ -564,7 +564,7 @@ def diff_re(a, b, fromfile='', tofile='', s = "^" + aline + "$" try: expr = re.compile(s) - except re.error, e: + except re.error as e: msg = "Regular expression error in %s: %s" raise re.error(msg % (repr(s), e.args[0])) if not expr.search(bline): @@ -640,7 +640,7 @@ else: st = os.stat(f) except OSError: continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: return f return None @@ -716,7 +716,7 @@ class Popen(subprocess.Popen): (errCode, written) = WriteFile(x, input) except ValueError: return self._close('stdin') - except (subprocess.pywintypes.error, Exception), why: + except (subprocess.pywintypes.error, Exception) as why: if why.args[0] in (109, errno.ESHUTDOWN): return self._close('stdin') raise @@ -737,7 +737,7 @@ class Popen(subprocess.Popen): (errCode, read) = ReadFile(x, nAvail, None) except ValueError: return self._close(which) - except (subprocess.pywintypes.error, Exception), why: + except (subprocess.pywintypes.error, Exception) as why: if why.args[0] in (109, errno.ESHUTDOWN): return self._close(which) raise @@ -756,7 +756,7 @@ class Popen(subprocess.Popen): try: written = os.write(self.stdin.fileno(), input) - except OSError, why: + except OSError as why: if why.args[0] == errno.EPIPE: #broken pipe return self._close('stdin') raise @@ -950,7 +950,7 @@ class TestCmd(object): condition = self.condition if self._preserve[condition]: for dir in self._dirlist: - print unicode("Preserved directory " + dir + "\n"), + print(str("Preserved directory " + dir + "\n"), end=' ') else: list = self._dirlist[:] list.reverse() @@ -1016,10 +1016,10 @@ class TestCmd(object): if diff_function is None: diff_function = self.simple_diff if name is not None: - print self.banner(name) + print(self.banner(name)) args = (a.splitlines(), b.splitlines()) + args for line in diff_function(*args, **kw): - print line + print(line) def diff_stderr(self, a, b, *args, **kw): """Compare actual and expected file contents. @@ -1645,12 +1645,12 @@ class TestCmd(object): def do_chmod(fname): try: st = os.stat(fname) except OSError: pass - else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0200)) + else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0o200)) else: def do_chmod(fname): try: st = os.stat(fname) except OSError: pass - else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0200)) + else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0o200)) if os.path.isfile(top): do_chmod(top) diff --git a/QMTest/TestCmdTests.py b/QMTest/TestCmdTests.py index 1044ed1..96e0cbf 100644 --- a/QMTest/TestCmdTests.py +++ b/QMTest/TestCmdTests.py @@ -26,13 +26,13 @@ import os import shutil import signal import stat -import StringIO +import io import sys import tempfile import time import types import unittest -import UserList +import collections # Strip the current directory so we get the right TestCmd.py module. sys.path = sys.path[1:] @@ -131,11 +131,11 @@ class TestCmdTestCase(unittest.TestCase): run_env.write(t.scriptout_path, textout) run_env.write(t.scripterr_path, texterr) - os.chmod(t.script_path, 0644) # XXX UNIX-specific - os.chmod(t.scriptx_path, 0755) # XXX UNIX-specific - os.chmod(t.script1_path, 0644) # XXX UNIX-specific - os.chmod(t.scriptout_path, 0644) # XXX UNIX-specific - os.chmod(t.scripterr_path, 0644) # XXX UNIX-specific + os.chmod(t.script_path, 0o644) # XXX UNIX-specific + os.chmod(t.scriptx_path, 0o755) # XXX UNIX-specific + os.chmod(t.script1_path, 0o644) # XXX UNIX-specific + os.chmod(t.scriptout_path, 0o644) # XXX UNIX-specific + os.chmod(t.scripterr_path, 0o644) # XXX UNIX-specific t.orig_cwd = os.getcwd() @@ -220,8 +220,8 @@ class cleanup_TestCase(TestCmdTestCase): test = TestCmd.TestCmd(workdir = '') wdir = test.workdir test.write('file2', "Test file #2\n") - os.chmod(test.workpath('file2'), 0400) - os.chmod(wdir, 0500) + os.chmod(test.workpath('file2'), 0o400) + os.chmod(wdir, 0o500) test.cleanup() assert not os.path.exists(wdir) @@ -286,35 +286,35 @@ class chmod_TestCase(TestCmdTestCase): test.chmod(['sub', 'file2'], stat.S_IWRITE) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) - assert file1_mode == 0444, '0%o' % file1_mode + assert file1_mode == 0o444, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) - assert file2_mode == 0666, '0%o' % file2_mode + assert file2_mode == 0o666, '0%o' % file2_mode test.chmod('file1', stat.S_IWRITE) test.chmod(wdir_sub_file2, stat.S_IREAD) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) - assert file1_mode == 0666, '0%o' % file1_mode + assert file1_mode == 0o666, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) - assert file2_mode == 0444, '0%o' % file2_mode + assert file2_mode == 0o444, '0%o' % file2_mode else: - test.chmod(wdir_file1, 0700) - test.chmod(['sub', 'file2'], 0760) + test.chmod(wdir_file1, 0o700) + test.chmod(['sub', 'file2'], 0o760) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) - assert file1_mode == 0700, '0%o' % file1_mode + assert file1_mode == 0o700, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) - assert file2_mode == 0760, '0%o' % file2_mode + assert file2_mode == 0o760, '0%o' % file2_mode - test.chmod('file1', 0765) - test.chmod(wdir_sub_file2, 0567) + test.chmod('file1', 0o765) + test.chmod(wdir_sub_file2, 0o567) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) - assert file1_mode == 0765, '0%o' % file1_mode + assert file1_mode == 0o765, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) - assert file2_mode == 0567, '0%o' % file2_mode + assert file2_mode == 0o567, '0%o' % file2_mode @@ -1032,14 +1032,14 @@ class match_exact_TestCase(TestCmdTestCase): assert test.match_exact("abcde\n", "abcde\n") assert not test.match_exact(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_exact(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) - assert not test.match_exact(UserList.UserList(["12345\n", "abcde\n"]), + assert not test.match_exact(collections.UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) - assert test.match_exact(UserList.UserList(["12345\n", "abcde\n"]), + assert test.match_exact(collections.UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert not test.match_exact(["12345\n", "abcde\n"], - UserList.UserList(["1[0-9]*5\n", "a.*e\n"])) + collections.UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_exact(["12345\n", "abcde\n"], - UserList.UserList(["12345\n", "abcde\n"])) + collections.UserList(["12345\n", "abcde\n"])) assert not test.match_exact("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_exact("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] @@ -1098,26 +1098,26 @@ sys.exit(0) ["1.*j\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], ["12345\n", "abcde\n", "fghij\n"]) - assert test.match_re_dotall(UserList.UserList(["12345\n", + assert test.match_re_dotall(collections.UserList(["12345\n", "abcde\n", "fghij\n"]), ["1[0-9]*5\n", "a.*e\n", "f.*j\n"]) - assert test.match_re_dotall(UserList.UserList(["12345\n", + assert test.match_re_dotall(collections.UserList(["12345\n", "abcde\n", "fghij\n"]), ["1.*j\n"]) - assert test.match_re_dotall(UserList.UserList(["12345\n", + assert test.match_re_dotall(collections.UserList(["12345\n", "abcde\n", "fghij\n"]), ["12345\n", "abcde\n", "fghij\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - UserList.UserList(["1[0-9]*5\n", + collections.UserList(["1[0-9]*5\n", "a.*e\n", "f.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - UserList.UserList(["1.*j\n"])) + collections.UserList(["1.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - UserList.UserList(["12345\n", + collections.UserList(["12345\n", "abcde\n", "fghij\n"])) assert test.match_re_dotall("12345\nabcde\nfghij\n", @@ -1176,14 +1176,14 @@ sys.exit(0) assert test.match_re("abcde\n", "abcde\n") assert test.match_re(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_re(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) - assert test.match_re(UserList.UserList(["12345\n", "abcde\n"]), + assert test.match_re(collections.UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) - assert test.match_re(UserList.UserList(["12345\n", "abcde\n"]), + assert test.match_re(collections.UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert test.match_re(["12345\n", "abcde\n"], - UserList.UserList(["1[0-9]*5\n", "a.*e\n"])) + collections.UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_re(["12345\n", "abcde\n"], - UserList.UserList(["12345\n", "abcde\n"])) + collections.UserList(["12345\n", "abcde\n"])) assert test.match_re("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_re("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] @@ -1463,7 +1463,7 @@ class preserve_TestCase(TestCmdTestCase): def test_preserve(self): """Test preserve()""" def cleanup_test(test, cond=None, stdout=""): - io = StringIO.StringIO() + io = io.StringIO() save = sys.stdout sys.stdout = io try: @@ -1603,7 +1603,7 @@ class read_TestCase(TestCmdTestCase): _file_matches(wdir_foo_file3, test.read(['foo', 'file3']), "Test\nfile\n#3.\n") _file_matches(wdir_foo_file3, - test.read(UserList.UserList(['foo', 'file3'])), + test.read(collections.UserList(['foo', 'file3'])), "Test\nfile\n#3.\n") _file_matches(wdir_file4, test.read('file4', mode = 'r'), "Test\nfile\n#4.\n") @@ -1862,8 +1862,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() @@ -1876,8 +1876,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path @@ -1913,8 +1913,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) @@ -1934,8 +1934,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() testx.run(arguments = ['arg1 arg2']) @@ -1958,8 +1958,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) @@ -1978,8 +1978,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 3) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) @@ -2002,8 +2002,8 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '') - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) @@ -2022,8 +2022,8 @@ class run_verbose_TestCase(TestCmdTestCase): testx = TestCmd.TestCmd(program = t.scriptx, workdir = '') - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() testx.run(arguments = ['arg1 arg2']) @@ -2048,8 +2048,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() @@ -2062,8 +2062,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() + sys.stdout = io.StringIO() + sys.stderr = io.StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path @@ -2347,7 +2347,7 @@ while 1: logfp.close() """ % t.recv_out_path t.run_env.write(t.recv_script_path, text) - os.chmod(t.recv_script_path, 0644) # XXX UNIX-specific + os.chmod(t.recv_script_path, 0o644) # XXX UNIX-specific return t def test_start(self): @@ -2765,11 +2765,11 @@ class subdir_TestCase(TestCmdTestCase): assert test.subdir('bar') == 1 assert test.subdir(['foo', 'succeed']) == 1 if os.name != "nt": - os.chmod(test.workpath('foo'), 0500) + os.chmod(test.workpath('foo'), 0o500) assert test.subdir(['foo', 'fail']) == 0 assert test.subdir(['sub', 'dir', 'ectory'], 'sub') == 1 assert test.subdir('one', - UserList.UserList(['one', 'two']), + collections.UserList(['one', 'two']), ['one', 'two', 'three']) == 3 assert os.path.isdir(test.workpath('foo')) assert os.path.isdir(test.workpath('bar')) @@ -2962,7 +2962,7 @@ class unlink_TestCase(TestCmdTestCase): test.unlink(['foo', 'file3a']) assert not os.path.exists(wdir_foo_file3a) - test.unlink(UserList.UserList(['foo', 'file3b'])) + test.unlink(collections.UserList(['foo', 'file3b'])) assert not os.path.exists(wdir_foo_file3b) test.unlink([test.workdir, 'foo', 'file4']) @@ -2971,8 +2971,8 @@ class unlink_TestCase(TestCmdTestCase): # Make it so we can't unlink file5. # For UNIX, remove write permission from the dir and the file. # For Windows, open the file. - os.chmod(test.workdir, 0500) - os.chmod(wdir_file5, 0400) + os.chmod(test.workdir, 0o500) + os.chmod(wdir_file5, 0o400) f = open(wdir_file5, 'r') try: @@ -2983,8 +2983,8 @@ class unlink_TestCase(TestCmdTestCase): except: raise finally: - os.chmod(test.workdir, 0700) - os.chmod(wdir_file5, 0600) + os.chmod(test.workdir, 0o700) + os.chmod(wdir_file5, 0o600) f.close() @@ -3208,11 +3208,11 @@ class executable_TestCase(TestCmdTestCase): def make_executable(fname): st = os.stat(fname) - os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0100)) + os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0o100)) def make_non_executable(fname): st = os.stat(fname) - os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0100)) + os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0o100)) test.executable(test.workdir, 0) # XXX skip these tests if euid == 0? @@ -3282,7 +3282,7 @@ class write_TestCase(TestCmdTestCase): test.write('file9', "Test file #9.\r\n", mode = 'wb') if os.name != "nt": - os.chmod(test.workdir, 0500) + os.chmod(test.workdir, 0o500) try: test.write('file10', "Test file #10 (should not get created).\n") except IOError: # expect "Permission denied" diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index 4e90e16..5a397ff 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -281,9 +281,9 @@ class TestCommon(TestCmd): existing, missing = separate_files(files) unwritable = [x for x in existing if not is_writable(x)] if missing: - print "Missing files: `%s'" % "', `".join(missing) + print("Missing files: `%s'" % "', `".join(missing)) if unwritable: - print "Unwritable files: `%s'" % "', `".join(unwritable) + print("Unwritable files: `%s'" % "', `".join(unwritable)) self.fail_test(missing + unwritable) def must_contain(self, file, required, mode = 'rb', find = None): @@ -298,11 +298,11 @@ class TestCommon(TestCmd): return None contains = find(file_contents, required) if not contains: - print "File `%s' does not contain required string." % file - print self.banner('Required string ') - print required - print self.banner('%s contents ' % file) - print file_contents + print("File `%s' does not contain required string." % file) + print(self.banner('Required string ')) + print(required) + print(self.banner('%s contents ' % file)) + print(file_contents) self.fail_test(not contains) def must_contain_all_lines(self, output, lines, title=None, find=None): @@ -437,7 +437,7 @@ class TestCommon(TestCmd): 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) and not os.path.islink(x) ] if missing: - print "Missing files: `%s'" % "', `".join(missing) + print("Missing files: `%s'" % "', `".join(missing)) self.fail_test(missing) def must_exist_one_of(self, files): @@ -457,7 +457,7 @@ class TestCommon(TestCmd): if glob.glob(xpath): return missing.append(xpath) - print "Missing one of: `%s'" % "', `".join(missing) + print("Missing one of: `%s'" % "', `".join(missing)) self.fail_test(missing) def must_match(self, file, expect, mode = 'rb', match=None): @@ -474,7 +474,7 @@ class TestCommon(TestCmd): except KeyboardInterrupt: raise except: - print "Unexpected contents of `%s'" % file + print("Unexpected contents of `%s'" % file) self.diff(expect, file_contents, 'contents ') raise @@ -490,11 +490,11 @@ class TestCommon(TestCmd): return None contains = find(file_contents, banned) if contains: - print "File `%s' contains banned string." % file - print self.banner('Banned string ') - print banned - print self.banner('%s contents ' % file) - print file_contents + print("File `%s' contains banned string." % file) + print(self.banner('Banned string ')) + print(banned) + print(self.banner('%s contents ' % file)) + print(file_contents) self.fail_test(contains) def must_not_contain_any_line(self, output, lines, title=None, find=None): @@ -541,7 +541,7 @@ class TestCommon(TestCmd): files = [is_List(x) and os.path.join(*x) or x for x in files] existing = [x for x in files if os.path.exists(x) or os.path.islink(x)] if existing: - print "Unexpected files exist: `%s'" % "', `".join(existing) + print("Unexpected files exist: `%s'" % "', `".join(existing)) self.fail_test(existing) def must_not_exist_any_of(self, files): @@ -561,7 +561,7 @@ class TestCommon(TestCmd): if glob.glob(xpath): existing.append(xpath) if existing: - print "Unexpected files exist: `%s'" % "', `".join(existing) + print("Unexpected files exist: `%s'" % "', `".join(existing)) self.fail_test(existing) def must_not_be_writable(self, *files): @@ -575,9 +575,9 @@ class TestCommon(TestCmd): existing, missing = separate_files(files) writable = list(filter(is_writable, existing)) if missing: - print "Missing files: `%s'" % "', `".join(missing) + print("Missing files: `%s'" % "', `".join(missing)) if writable: - print "Writable files: `%s'" % "', `".join(writable) + print("Writable files: `%s'" % "', `".join(writable)) self.fail_test(missing + writable) def _complete(self, actual_stdout, expected_stdout, @@ -590,23 +590,23 @@ class TestCommon(TestCmd): expect = '' if status != 0: expect = " (expected %s)" % str(status) - print "%s returned %s%s" % (self.program, _status(self), expect) - print self.banner('STDOUT ') - print actual_stdout - print self.banner('STDERR ') - print actual_stderr + print("%s returned %s%s" % (self.program, _status(self), expect)) + print(self.banner('STDOUT ')) + print(actual_stdout) + print(self.banner('STDERR ')) + print(actual_stderr) self.fail_test() if (expected_stdout is not None and not match(actual_stdout, expected_stdout)): self.diff(expected_stdout, actual_stdout, 'STDOUT ') if actual_stderr: - print self.banner('STDERR ') - print actual_stderr + print(self.banner('STDERR ')) + print(actual_stderr) self.fail_test() if (expected_stderr is not None and not match(actual_stderr, expected_stderr)): - print self.banner('STDOUT ') - print actual_stdout + print(self.banner('STDOUT ')) + print(actual_stdout) self.diff(expected_stderr, actual_stderr, 'STDERR ') self.fail_test() @@ -626,15 +626,15 @@ class TestCommon(TestCmd): universal_newlines, **kw) except KeyboardInterrupt: raise - except Exception, e: - print self.banner('STDOUT ') + except Exception as e: + print(self.banner('STDOUT ')) try: - print self.stdout() + print(self.stdout()) except IndexError: pass - print self.banner('STDERR ') + print(self.banner('STDERR ')) try: - print self.stderr() + print(self.stderr()) except IndexError: pass cmd_args = self.command_args(program, interpreter, arguments) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 84cc60f..72624e6 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -13,7 +13,7 @@ attributes defined in this subclass. """ # __COPYRIGHT__ -from __future__ import division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -356,7 +356,7 @@ class TestSCons(TestCommon): # raised so as to not mask possibly serious disk or # network issues. continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: return os.path.normpath(f) else: import SCons.Environment @@ -503,9 +503,9 @@ class TestSCons(TestCommon): self.pass_test() else: # test failed; have to do this by hand... - print self.banner('STDOUT ') - print self.stdout() - print self.diff(warning, stderr, 'STDERR ') + print(self.banner('STDOUT ')) + print(self.stdout()) + print(self.diff(warning, stderr, 'STDERR ')) self.fail_test() return warning @@ -574,7 +574,7 @@ class TestSCons(TestCommon): We stick the requested file name and line number in the right places, abstracting out the version difference. """ - exec 'import traceback; x = traceback.format_stack()[-1]' + exec('import traceback; x = traceback.format_stack()[-1]') x = x.lstrip() x = x.replace('', file) x = x.replace('line 1,', 'line %s,' % line) @@ -721,7 +721,7 @@ class TestSCons(TestCommon): home = os.path.normpath('%s/..'%jar) if os.path.isdir(home): return home - print("Could not determine JAVA_HOME: %s is not a directory" % home) + print(("Could not determine JAVA_HOME: %s is not a directory" % home)) self.fail_test() def java_where_jar(self, version=None): @@ -1087,27 +1087,27 @@ SConscript( sconscript ) if doCheckLog and lastEnd != len(logfile): raise NoMatch(lastEnd) - except NoMatch, m: - print "Cannot match log file against log regexp." - print "log file: " - print "------------------------------------------------------" - print logfile[m.pos:] - print "------------------------------------------------------" - print "log regexp: " - print "------------------------------------------------------" - print log - print "------------------------------------------------------" + except NoMatch as m: + print("Cannot match log file against log regexp.") + print("log file: ") + print("------------------------------------------------------") + print(logfile[m.pos:]) + print("------------------------------------------------------") + print("log regexp: ") + print("------------------------------------------------------") + print(log) + print("------------------------------------------------------") self.fail_test() if doCheckStdout: exp_stdout = self.wrap_stdout(".*", rdstr) if not self.match_re_dotall(self.stdout(), exp_stdout): - print "Unexpected stdout: " - print "-----------------------------------------------------" - print repr(self.stdout()) - print "-----------------------------------------------------" - print repr(exp_stdout) - print "-----------------------------------------------------" + print("Unexpected stdout: ") + print("-----------------------------------------------------") + print(repr(self.stdout())) + print("-----------------------------------------------------") + print(repr(exp_stdout)) + print("-----------------------------------------------------") self.fail_test() def get_python_version(self): @@ -1241,7 +1241,7 @@ class TimeSCons(TestSCons): self.variables = kw.get('variables') default_calibrate_variables = [] if self.variables is not None: - for variable, value in self.variables.items(): + for variable, value in list(self.variables.items()): value = os.environ.get(variable, value) try: value = int(value) @@ -1297,7 +1297,7 @@ class TimeSCons(TestSCons): """ if 'options' not in kw and self.variables: options = [] - for variable, value in self.variables.items(): + for variable, value in list(self.variables.items()): options.append('%s=%s' % (variable, value)) kw['options'] = ' '.join(options) if self.calibrate: @@ -1323,7 +1323,7 @@ class TimeSCons(TestSCons): self.elapsed_time(), "seconds", sort=0) - for name, args in stats.items(): + for name, args in list(stats.items()): self.trace(name, trace, **args) def uptime(self): diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index c78b452..478438a 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -1039,7 +1039,7 @@ print "self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions()) try: host = _ARCH_TO_CANONICAL[host_platform] - except KeyError, e: + except KeyError as e: # Default to x86 for all other platforms host = 'x86' diff --git a/QMTest/TestSCons_time.py b/QMTest/TestSCons_time.py index abe8ccf..ba7fbd8 100644 --- a/QMTest/TestSCons_time.py +++ b/QMTest/TestSCons_time.py @@ -225,7 +225,7 @@ class TestSCons_time(TestCommon): def write_fake_aegis_py(self, name): name = self.workpath(name) self.write(name, aegis_py) - os.chmod(name, 0755) + os.chmod(name, 0o755) return name def write_fake_scons_py(self): @@ -235,7 +235,7 @@ class TestSCons_time(TestCommon): def write_fake_svn_py(self, name): name = self.workpath(name) self.write(name, svn_py) - os.chmod(name, 0755) + os.chmod(name, 0o755) return name def write_sample_directory(self, archive, dir, files): diff --git a/QMTest/TestSConsign.py b/QMTest/TestSConsign.py index 700c242..665059c 100644 --- a/QMTest/TestSConsign.py +++ b/QMTest/TestSConsign.py @@ -68,7 +68,7 @@ class TestSConsign(TestSCons): elif os.path.exists(self.script_path('sconsign')): sconsign = 'sconsign' else: - print "Can find neither 'sconsign.py' nor 'sconsign' scripts." + print("Can find neither 'sconsign.py' nor 'sconsign' scripts.") self.no_result() self.set_sconsign(sconsign) diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py index 6be4696..845e99c 100644 --- a/QMTest/scons_tdb.py +++ b/QMTest/scons_tdb.py @@ -20,7 +20,7 @@ # 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 division + """ QMTest classes to support SCons' testing and Aegis-inspired workflow. @@ -92,7 +92,7 @@ def get_explicit_arguments(e): # Determine which subset of the 'arguments' have been set # explicitly. explicit_arguments = {} - for name, field in arguments.items(): + for name, field in list(arguments.items()): # Do not record computed fields. if field.IsComputed(): continue @@ -337,14 +337,14 @@ class AegisChangeStream(AegisStream): # We'd like to use the _FormatStatistics() method to do # this, but it's wrapped around the list in Result.outcomes, # so it's simpler to just do it ourselves. - print " %6d tests total\n" % self._num_tests + print(" %6d tests total\n" % self._num_tests) for outcome in AegisTest.aegis_outcomes: if self._outcome_counts[outcome] != 0: - print " %6d (%3.0f%%) tests %s" % ( + print(" %6d (%3.0f%%) tests %s" % ( self._outcome_counts[outcome], self._percent(outcome), outcome - ) + )) class AegisBaselineStream(AegisStream): def WriteResult(self, result): @@ -368,19 +368,19 @@ class AegisBaselineStream(AegisStream): # this, but it's wrapped around the list in Result.outcomes, # so it's simpler to just do it ourselves. if self._outcome_counts[AegisTest.FAIL]: - print " %6d (%3.0f%%) tests as expected" % ( + print(" %6d (%3.0f%%) tests as expected" % ( self._outcome_counts[AegisTest.FAIL], self._percent(AegisTest.FAIL), - ) + )) non_fail_outcomes = list(AegisTest.aegis_outcomes[:]) non_fail_outcomes.remove(AegisTest.FAIL) for outcome in non_fail_outcomes: if self._outcome_counts[outcome] != 0: - print " %6d (%3.0f%%) tests unexpected %s" % ( + print(" %6d (%3.0f%%) tests unexpected %s" % ( self._outcome_counts[outcome], self._percent(outcome), outcome, - ) + )) class AegisBatchStream(FileResultStream): def __init__(self, arguments): diff --git a/bench/bench.py b/bench/bench.py index 74dbf12..1a98d8c 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -23,7 +23,7 @@ # # This will allow (as much as possible) us to time just the code itself, # not Python function call overhead. -from __future__ import division + import getopt import sys @@ -94,7 +94,7 @@ exec(open(args[0], 'rU').read()) try: FunctionList except NameError: - function_names = sorted([x for x in locals().keys() if x[:4] == FunctionPrefix]) + function_names = sorted([x for x in list(locals().keys()) if x[:4] == FunctionPrefix]) l = [locals()[f] for f in function_names] FunctionList = [f for f in l if isinstance(f, types.FunctionType)] @@ -113,12 +113,12 @@ def display(label, results): total = 0.0 for r in results: total += r - print " %8.3f" % ((total * 1e6) / len(results)), ':', label + print(" %8.3f" % ((total * 1e6) / len(results)), ':', label) for func in FunctionList: if func.__doc__: d = ' (' + func.__doc__ + ')' else: d = '' - print func.__name__ + d + ':' + print(func.__name__ + d + ':') for label, args, kw in Data: r = timer(func, *args, **kw) diff --git a/bench/env.__setitem__.py b/bench/env.__setitem__.py index b17b59e..284653e 100644 --- a/bench/env.__setitem__.py +++ b/bench/env.__setitem__.py @@ -33,15 +33,15 @@ class Timing(object): def times(num=1000000, init='', title='Results:', **statements): # time each statement timings = [] - for n, s in statements.items(): + for n, s in list(statements.items()): t = Timing(n, num, init, s) t.timeit() timings.append(t) - print - print title + print() + print(title) for i in sorted([(i.getResult(),i.name) for i in timings]): - print " %9.3f s %s" % i + print(" %9.3f s %s" % i) # Import the necessary local SCons.* modules used by some of our # alternative implementations below, first manipulating sys.path so @@ -287,7 +287,7 @@ else: # that the timer will use to get at these classes. class_names = [] -for n in locals().keys(): +for n in list(locals().keys()): #if n.startswith('env_'): if n[:4] == 'env_': class_names.append(n) @@ -339,9 +339,9 @@ def run_it(title, init): s['init'] = init times(**s) -print 'Environment __setitem__ benchmark using', -print 'Python', sys.version.split()[0], -print 'on', sys.platform, os.name +print('Environment __setitem__ benchmark using', end=' ') +print('Python', sys.version.split()[0], end=' ') +print('on', sys.platform, os.name) run_it('Results for re-adding an existing variable name 100 times:', common_imports + """ diff --git a/bench/is_types.py b/bench/is_types.py index 69c029f..b6da0d2 100644 --- a/bench/is_types.py +++ b/bench/is_types.py @@ -17,11 +17,11 @@ InstanceType = types.InstanceType DictType = dict ListType = list StringType = str -try: unicode +try: str except NameError: UnicodeType = None else: - UnicodeType = unicode + UnicodeType = str # The original implementations, pretty straightforward checks for the @@ -36,7 +36,7 @@ def original_is_List(e): if UnicodeType is not None: def original_is_String(e): - return isinstance(e, (str,unicode,UserString)) + return isinstance(e, (str,UserString)) else: def original_is_String(e): return isinstance(e, (str,UserString)) @@ -58,7 +58,7 @@ def checkInstanceType_is_List(e): if UnicodeType is not None: def checkInstanceType_is_String(e): return isinstance(e, str) \ - or isinstance(e, unicode) \ + or isinstance(e, str) \ or (isinstance(e, types.InstanceType) and isinstance(e, UserString)) else: def checkInstanceType_is_String(e): @@ -84,7 +84,7 @@ if UnicodeType is not None: def cache_type_e_is_String(e): t = type(e) return t is str \ - or t is unicode \ + or t is str \ or (t is types.InstanceType and isinstance(e, UserString)) else: def cache_type_e_is_String(e): @@ -136,7 +136,7 @@ if UnicodeType is not None: t = type(obj) if t is types.InstanceType: t = instanceTypeMap.get(obj.__class__, t) - elif t is unicode: + elif t is str: t = str return t else: diff --git a/bench/timeit.py b/bench/timeit.py index c5fef12..2840010 100644 --- a/bench/timeit.py +++ b/bench/timeit.py @@ -46,7 +46,7 @@ be aware of it. The baseline overhead can be measured by invoking the program without arguments. The baseline overhead differs between Python versions! """ -from __future__ import division + try: import gc @@ -122,7 +122,7 @@ class Timer(object): self.src = src # Save for traceback display code = compile(src, dummy_src_name, "exec") ns = {} - exec code in globals(), ns + exec(code, globals(), ns) self.inner = ns["inner"] def print_exc(self, file=None): @@ -216,9 +216,9 @@ def main(args=None): opts, args = getopt.getopt(args, "n:s:r:tcvh", ["number=", "setup=", "repeat=", "time", "clock", "verbose", "help"]) - except getopt.error, err: - print err - print "use -h/--help for command line help" + except getopt.error as err: + print(err) + print("use -h/--help for command line help") return 2 timer = default_timer stmt = "\n".join(args) or "pass" @@ -245,7 +245,7 @@ def main(args=None): precision = precision + 1 verbose = precision + 1 if o in ("-h", "--help"): - print __doc__, + print(__doc__, end=' ') return 0 setup = "\n".join(setup) or "pass" # Include the current directory, so that local imports work (sys.path @@ -264,7 +264,7 @@ def main(args=None): t.print_exc() return 1 if verbose: - print "%d loops -> %.*g secs" % (number, precision, x) + print("%d loops -> %.*g secs" % (number, precision, x)) if x >= 0.2: break try: @@ -274,18 +274,18 @@ def main(args=None): return 1 best = min(r) if verbose: - print "raw times:", ' '.join(["%.*g" % (precision, x) for x in r]) - print "%d loops," % number, + print("raw times:", ' '.join(["%.*g" % (precision, x) for x in r])) + print("%d loops," % number, end=' ') usec = best * 1e6 / number if usec < 1000: - print "best of %d: %.*g usec per loop" % (repeat, precision, usec) + print("best of %d: %.*g usec per loop" % (repeat, precision, usec)) else: msec = usec / 1000 if msec < 1000: - print "best of %d: %.*g msec per loop" % (repeat, precision, msec) + print("best of %d: %.*g msec per loop" % (repeat, precision, msec)) else: sec = msec / 1000 - print "best of %d: %.*g sec per loop" % (repeat, precision, sec) + print("best of %d: %.*g sec per loop" % (repeat, precision, sec)) return None if __name__ == "__main__": diff --git a/bin/Command.py b/bin/Command.py index 8702f51..768caed 100644 --- a/bin/Command.py +++ b/bin/Command.py @@ -109,18 +109,18 @@ Usage: script-template.py [-hnq] try: try: opts, args = getopt.getopt(argv[1:], short_options, long_options) - except getopt.error, msg: + except getopt.error as msg: raise Usage(msg) for o, a in opts: if o in ('-h', '--help'): - print helpstr + print(helpstr) sys.exit(0) elif o in ('-n', '--no-exec'): Command.execute = Command.do_not_execute elif o in ('-q', '--quiet'): Command.display = Command.do_not_display - except Usage, err: + except Usage as err: sys.stderr.write(err.msg) sys.stderr.write('use -h to get help') return 2 diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py index dc9d161..453e241 100644 --- a/bin/SConsDoc.py +++ b/bin/SConsDoc.py @@ -210,12 +210,12 @@ class Libxml2ValidityHandler: def error(self, msg, data): if data != ARG: - raise Exception, "Error handler did not receive correct argument" + raise Exception("Error handler did not receive correct argument") self.errors.append(msg) def warning(self, msg, data): if data != ARG: - raise Exception, "Warning handler did not receive correct argument" + raise Exception("Warning handler did not receive correct argument") self.warnings.append(msg) @@ -332,16 +332,16 @@ if not has_libxml2: xmlschema = etree.XMLSchema(xmlschema_context) try: doc = etree.parse(fpath) - except Exception, e: - print "ERROR: %s fails to parse:"%fpath - print e + except Exception as e: + print("ERROR: %s fails to parse:"%fpath) + print(e) return False doc.xinclude() try: xmlschema.assertValid(doc) - except Exception, e: - print "ERROR: %s fails to validate:" % fpath - print e + except Exception as e: + print("ERROR: %s fails to validate:" % fpath) + print(e) return False return True @@ -477,8 +477,8 @@ else: if err or eh.errors: for e in eh.errors: - print e.rstrip("\n") - print "%s fails to validate" % fpath + print(e.rstrip("\n")) + print("%s fails to validate" % fpath) return False return True @@ -599,7 +599,7 @@ class SConsDocTree: # Create xpath context self.xpath_context = self.doc.xpathNewContext() # Register namespaces - for key, val in self.nsmap.iteritems(): + for key, val in self.nsmap.items(): self.xpath_context.xpathRegisterNs(key, val) def __del__(self): @@ -637,8 +637,8 @@ def validate_all_xml(dpaths, xsdfile=default_xsd): fails = [] for idx, fp in enumerate(fpaths): fpath = os.path.join(path, fp) - print "%.2f%s (%d/%d) %s" % (float(idx+1)*100.0/float(len(fpaths)), - perc, idx+1, len(fpaths),fp) + print("%.2f%s (%d/%d) %s" % (float(idx+1)*100.0/float(len(fpaths)), + perc, idx+1, len(fpaths),fp)) if not tf.validateXml(fp, xmlschema_context): fails.append(fp) @@ -810,7 +810,7 @@ def importfile(path): file = open(path, 'r') try: module = imp.load_module(name, file, path, (ext, 'r', kind)) - except ImportError, e: + except ImportError as e: sys.stderr.write("Could not import %s: %s\n" % (path, e)) return None file.close() diff --git a/bin/SConsExamples.py b/bin/SConsExamples.py index 9823a05..e3a7502 100644 --- a/bin/SConsExamples.py +++ b/bin/SConsExamples.py @@ -265,7 +265,7 @@ def ensureExampleOutputsExist(dpath): os.mkdir(generated_examples) examples = readAllExampleInfos(dpath) - for key, value in examples.iteritems(): + for key, value in examples.items(): # Process all scons_output tags for o in value.outputs: cpath = os.path.join(generated_examples, @@ -303,10 +303,10 @@ def createAllExampleOutputs(dpath): examples = readAllExampleInfos(dpath) total = len(examples) idx = 0 - for key, value in examples.iteritems(): + for key, value in examples.items(): # Process all scons_output tags - print "%.2f%s (%d/%d) %s" % (float(idx + 1) * 100.0 / float(total), - perc, idx + 1, total, key) + print("%.2f%s (%d/%d) %s" % (float(idx + 1) * 100.0 / float(total), + perc, idx + 1, total, key)) create_scons_output(value) # Process all scons_example_file tags @@ -344,7 +344,7 @@ def collectSConsExampleNames(fpath): if n not in suffixes: suffixes[n] = [] else: - print "Error: Example in file '%s' is missing a name!" % fpath + print("Error: Example in file '%s' is missing a name!" % fpath) failed_suffixes = True for o in stf.findAll(t.root, "scons_output", SConsDoc.dbxid, @@ -353,11 +353,11 @@ def collectSConsExampleNames(fpath): if stf.hasAttribute(o, 'example'): n = stf.getAttribute(o, 'example') else: - print "Error: scons_output in file '%s' is missing an example name!" % fpath + print("Error: scons_output in file '%s' is missing an example name!" % fpath) failed_suffixes = True if n not in suffixes: - print "Error: scons_output in file '%s' is referencing non-existent example '%s'!" % (fpath, n) + print("Error: scons_output in file '%s' is referencing non-existent example '%s'!" % (fpath, n)) failed_suffixes = True continue @@ -365,13 +365,13 @@ def collectSConsExampleNames(fpath): if stf.hasAttribute(o, 'suffix'): s = stf.getAttribute(o, 'suffix') else: - print "Error: scons_output in file '%s' (example '%s') is missing a suffix!" % (fpath, n) + print("Error: scons_output in file '%s' (example '%s') is missing a suffix!" % (fpath, n)) failed_suffixes = True if s not in suffixes[n]: suffixes[n].append(s) else: - print "Error: scons_output in file '%s' (example '%s') is using a duplicate suffix '%s'!" % (fpath, n, s) + print("Error: scons_output in file '%s' (example '%s') is using a duplicate suffix '%s'!" % (fpath, n, s)) failed_suffixes = True return names, failed_suffixes @@ -392,7 +392,7 @@ def exampleNamesAreUnique(dpath): unique = False i = allnames.intersection(names) if i: - print "Not unique in %s are: %s" % (fpath, ', '.join(i)) + print("Not unique in %s are: %s" % (fpath, ', '.join(i))) unique = False allnames |= names diff --git a/bin/calibrate.py b/bin/calibrate.py index 8ed2ece..31c04e8 100644 --- a/bin/calibrate.py +++ b/bin/calibrate.py @@ -20,7 +20,7 @@ # 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 division + import optparse import os @@ -48,7 +48,7 @@ def main(argv=None): for arg in args: if len(args) > 1: - print arg + ':' + print(arg + ':') command = [sys.executable, 'runtest.py'] if opts.package: @@ -67,9 +67,9 @@ def main(argv=None): try: elapsed = float(em.group(1)) except AttributeError: - print output + print(output) raise - print "run %3d: %7.3f: %s" % (run, elapsed, ' '.join(vm.groups())) + print("run %3d: %7.3f: %s" % (run, elapsed, ' '.join(vm.groups()))) if opts.min < elapsed and elapsed < opts.max: good += 1 else: diff --git a/bin/caller-tree.py b/bin/caller-tree.py index 03c1616..327e6a1 100644 --- a/bin/caller-tree.py +++ b/bin/caller-tree.py @@ -74,19 +74,19 @@ for line in sys.stdin.readlines(): stack = [] def print_entry(e, level, calls): - print '%-72s%6s' % ((' '*2*level) + e.file_line_func, calls) + print('%-72s%6s' % ((' '*2*level) + e.file_line_func, calls)) if e in stack: - print (' '*2*(level+1))+'RECURSION' - print + print((' '*2*(level+1))+'RECURSION') + print() elif e.called_by: stack.append(e) for c in e.called_by: print_entry(c[0], level+1, c[1]) stack.pop() else: - print + print() -for e in [ e for e in AllCalls.values() if not e.calls ]: +for e in [ e for e in list(AllCalls.values()) if not e.calls ]: print_entry(e, 0, '') # Local Variables: diff --git a/bin/docs-create-example-outputs.py b/bin/docs-create-example-outputs.py index 30dc0ee..b2dfbea 100644 --- a/bin/docs-create-example-outputs.py +++ b/bin/docs-create-example-outputs.py @@ -9,11 +9,11 @@ import sys import SConsExamples if __name__ == "__main__": - print "Checking whether all example names are unique..." + print("Checking whether all example names are unique...") if SConsExamples.exampleNamesAreUnique(os.path.join('doc','user')): - print "OK" + print("OK") else: - print "Not all example names and suffixes are unique! Please correct the errors listed above and try again." + print("Not all example names and suffixes are unique! Please correct the errors listed above and try again.") sys.exit(0) SConsExamples.createAllExampleOutputs(os.path.join('doc','user')) diff --git a/bin/docs-update-generated.py b/bin/docs-update-generated.py index 66b22c0..2b419a4 100644 --- a/bin/docs-update-generated.py +++ b/bin/docs-update-generated.py @@ -38,7 +38,7 @@ def generate_all(): try: os.makedirs(gen_folder) except: - print "Couldn't create destination folder %s! Exiting..." % gen_folder + print("Couldn't create destination folder %s! Exiting..." % gen_folder) return # Call scons-proc.py os.system('python %s -b %s -f %s -t %s -v %s %s' % diff --git a/bin/docs-validate.py b/bin/docs-validate.py index c445c3f..e5d0659 100644 --- a/bin/docs-validate.py +++ b/bin/docs-validate.py @@ -10,9 +10,9 @@ import SConsDoc if __name__ == "__main__": if len(sys.argv)>1: if SConsDoc.validate_all_xml((sys.argv[1],)): - print "OK" + print("OK") else: - print "Validation failed! Please correct the errors above and try again." + print("Validation failed! Please correct the errors above and try again.") else: if SConsDoc.validate_all_xml(['src', os.path.join('doc','design'), @@ -22,6 +22,6 @@ if __name__ == "__main__": os.path.join('doc','reference'), os.path.join('doc','user') ]): - print "OK" + print("OK") else: - print "Validation failed! Please correct the errors above and try again." + print("Validation failed! Please correct the errors above and try again.") diff --git a/bin/install_python.py b/bin/install_python.py index 86807af..dca37d0 100644 --- a/bin/install_python.py +++ b/bin/install_python.py @@ -48,7 +48,7 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] try: try: opts, args = getopt.getopt(argv[1:], short_options, long_options) - except getopt.error, msg: + except getopt.error as msg: raise Usage(msg) for o, a in opts: @@ -57,7 +57,7 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] elif o in ('-d', '--downloads'): downloads_dir = a elif o in ('-h', '--help'): - print helpstr + print(helpstr) sys.exit(0) elif o in ('-n', '--no-exec'): CommandRunner.execute = CommandRunner.do_not_execute @@ -65,7 +65,7 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] prefix = a elif o in ('-q', '--quiet'): CommandRunner.display = CommandRunner.do_not_display - except Usage, err: + except Usage as err: sys.stderr.write(str(err.msg) + '\n') sys.stderr.write('use -h to get help\n') return 2 diff --git a/bin/install_scons.py b/bin/install_scons.py index 00129f6..b732193 100644 --- a/bin/install_scons.py +++ b/bin/install_scons.py @@ -23,7 +23,7 @@ import os import shutil import sys import tarfile -import urllib +import urllib.request, urllib.parse, urllib.error from Command import CommandRunner, Usage @@ -129,7 +129,7 @@ Usage: install_scons.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] try: try: opts, args = getopt.getopt(argv[1:], short_options, long_options) - except getopt.error, msg: + except getopt.error as msg: raise Usage(msg) for o, a in opts: @@ -138,7 +138,7 @@ Usage: install_scons.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] elif o in ('-d', '--downloads'): downloads_dir = a elif o in ('-h', '--help'): - print helpstr + print(helpstr) sys.exit(0) elif o in ('-n', '--no-exec'): CommandRunner.execute = CommandRunner.do_not_execute @@ -146,7 +146,7 @@ Usage: install_scons.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] prefix = a elif o in ('-q', '--quiet'): CommandRunner.display = CommandRunner.do_not_display - except Usage, err: + except Usage as err: sys.stderr.write(str(err.msg) + '\n') sys.stderr.write('use -h to get help\n') return 2 @@ -171,7 +171,7 @@ Usage: install_scons.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] if not os.path.exists(tar_gz): if not os.path.exists(downloads_dir): cmd.run('mkdir %(downloads_dir)s') - cmd.run((urllib.urlretrieve, tar_gz_url, tar_gz), + cmd.run((urllib.request.urlretrieve, tar_gz_url, tar_gz), 'wget -O %(tar_gz)s %(tar_gz_url)s') def extract(tar_gz): diff --git a/bin/linecount.py b/bin/linecount.py index 6f49dca..2d478f0 100644 --- a/bin/linecount.py +++ b/bin/linecount.py @@ -21,7 +21,7 @@ # in each category, the number of non-blank lines, and the number of # non-comment lines. The last figure (non-comment) lines is the most # interesting one for most purposes. -from __future__ import division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -98,23 +98,23 @@ all_tests = Collection('all tests', src_tests.files + test_tests.files) def ratio(over, under): return "%.2f" % (float(len(over)) / float(len(under))) -print fmt % ('', '', '', '', '', 'non-blank') -print fmt % ('', 'files', 'lines', 'non-blank', 'non-comment', 'non-comment') -print -print fmt % src_Tests_py_tests.printables() -print fmt % src_test_tests.printables() -print -print fmt % src_tests.printables() -print fmt % test_tests.printables() -print -print fmt % all_tests.printables() -print fmt % sources.printables() -print -print fmt % ('ratio:', +print(fmt % ('', '', '', '', '', 'non-blank')) +print(fmt % ('', 'files', 'lines', 'non-blank', 'non-comment', 'non-comment')) +print() +print(fmt % src_Tests_py_tests.printables()) +print(fmt % src_test_tests.printables()) +print() +print(fmt % src_tests.printables()) +print(fmt % test_tests.printables()) +print() +print(fmt % all_tests.printables()) +print(fmt % sources.printables()) +print() +print(fmt % ('ratio:', ratio(all_tests, sources), ratio(all_tests.lines(), sources.lines()), ratio(all_tests.non_blank(), sources.non_blank()), ratio(all_tests.non_comment(), sources.non_comment()), ratio(all_tests.non_blank_non_comment(), sources.non_blank_non_comment()) - ) + )) diff --git a/bin/memlogs.py b/bin/memlogs.py index 9d957c9..0409dfe 100644 --- a/bin/memlogs.py +++ b/bin/memlogs.py @@ -27,20 +27,20 @@ import sys filenames = sys.argv[1:] if not filenames: - print """Usage: memlogs.py file [...] + print("""Usage: memlogs.py file [...] Summarizes the --debug=memory numbers from one or more build logs. -""" +""") sys.exit(0) fmt = "%12s %12s %12s %12s %s" -print fmt % ("pre-read", "post-read", "pre-build", "post-build", "") +print(fmt % ("pre-read", "post-read", "pre-build", "post-build", "")) for fname in sys.argv[1:]: lines = [l for l in open(fname).readlines() if l[:7] == 'Memory '] t = tuple([l.split()[-1] for l in lines]) + (fname,) - print fmt % t + print(fmt % t) # Local Variables: # tab-width:4 diff --git a/bin/memoicmp.py b/bin/memoicmp.py index 812af66..5021c41 100644 --- a/bin/memoicmp.py +++ b/bin/memoicmp.py @@ -23,20 +23,20 @@ def memoize_cmp(filea, fileb): ma = memoize_output(filea) mb = memoize_output(fileb) - print 'All output: %s / %s [delta]'%(filea, fileb) - print '----------HITS---------- ---------MISSES---------' + print('All output: %s / %s [delta]'%(filea, fileb)) + print('----------HITS---------- ---------MISSES---------') cfmt='%7d/%-7d [%d]' ma_o = [] mb_o = [] mab = [] - for k in ma.keys(): - if k in mb.keys(): + for k in list(ma.keys()): + if k in list(mb.keys()): if k not in mab: mab.append(k) else: ma_o.append(k) - for k in mb.keys(): - if k in ma.keys(): + for k in list(mb.keys()): + if k in list(ma.keys()): if k not in mab: mab.append(k) else: @@ -49,26 +49,26 @@ def memoize_cmp(filea, fileb): for k in mab: hits = cfmt%(ma[k][0], mb[k][0], mb[k][0]-ma[k][0]) miss = cfmt%(ma[k][1], mb[k][1], mb[k][1]-ma[k][1]) - print '%-24s %-24s %s'%(hits, miss, k) + print('%-24s %-24s %s'%(hits, miss, k)) for k in ma_o: hits = '%7d/ --'%(ma[k][0]) miss = '%7d/ --'%(ma[k][1]) - print '%-24s %-24s %s'%(hits, miss, k) + print('%-24s %-24s %s'%(hits, miss, k)) for k in mb_o: hits = ' -- /%-7d'%(mb[k][0]) miss = ' -- /%-7d'%(mb[k][1]) - print '%-24s %-24s %s'%(hits, miss, k) + print('%-24s %-24s %s'%(hits, miss, k)) - print '-'*(24+24+1+20) + print('-'*(24+24+1+20)) if __name__ == "__main__": if len(sys.argv) != 3: - print """Usage: %s file1 file2 + print("""Usage: %s file1 file2 -Compares --debug=memomize output from file1 against file2."""%sys.argv[0] +Compares --debug=memomize output from file1 against file2."""%sys.argv[0]) sys.exit(1) memoize_cmp(sys.argv[1], sys.argv[2]) diff --git a/bin/objcounts.py b/bin/objcounts.py index 0662012..25b985b 100644 --- a/bin/objcounts.py +++ b/bin/objcounts.py @@ -27,10 +27,10 @@ import sys filenames = sys.argv[1:] if len(sys.argv) != 3: - print """Usage: objcounts.py file1 file2 + print("""Usage: objcounts.py file1 file2 Compare the --debug=object counts from two build logs. -""" +""") sys.exit(0) def fetch_counts(fname): @@ -47,7 +47,7 @@ c1 = fetch_counts(sys.argv[1]) c2 = fetch_counts(sys.argv[2]) common = {} -for k in c1.keys(): +for k in list(c1.keys()): try: common[k] = (c1[k], c2[k]) except KeyError: @@ -58,7 +58,7 @@ for k in c1.keys(): if not '.' in k: s = '.'+k l = len(s) - for k2 in c2.keys(): + for k2 in list(c2.keys()): if k2[-l:] == s: common[k2] = (c1[k], c2[k2]) del c1[k] @@ -81,10 +81,9 @@ def diffstr(c1, c2): return " %5s/%-5s %-8s" % (c1, c2, d) def printline(c1, c2, classname): - print \ - diffstr(c1[2], c2[2]) + \ + print(diffstr(c1[2], c2[2]) + \ diffstr(c1[3], c2[3]) + \ - ' ' + classname + ' ' + classname) for k in sorted(common.keys()): c = common[k] diff --git a/bin/scons-diff.py b/bin/scons-diff.py index 52bd51b..5181fa1 100644 --- a/bin/scons-diff.py +++ b/bin/scons-diff.py @@ -43,7 +43,7 @@ def diff_line(left, right): opts = ' ' + ' '.join(diff_options) else: opts = '' - print 'diff%s %s %s' % (opts, left, right) + print('diff%s %s %s' % (opts, left, right)) for o, a in opts: if o in ('-c', '-u'): @@ -51,7 +51,7 @@ for o, a in opts: context = int(a) diff_options.append(o) elif o in ('-h', '--help'): - print Usage + print(Usage) sys.exit(0) elif o in ('-n'): diff_options.append(o) @@ -161,9 +161,9 @@ def diff_file(left, right): else: if text: diff_line(left, right) - print text, + print(text, end=' ') elif report_same: - print 'Files %s and %s are identical' % (left, right) + print('Files %s and %s are identical' % (left, right)) def diff_dir(left, right): llist = os.listdir(left) @@ -173,16 +173,16 @@ def diff_dir(left, right): u[l] = 1 for r in rlist: u[r] = 1 - for x in sorted([ x for x in u.keys() if x[-4:] != '.pyc' ]): + for x in sorted([ x for x in list(u.keys()) if x[-4:] != '.pyc' ]): if x in llist: if x in rlist: do_diff(os.path.join(left, x), os.path.join(right, x), recursive) else: - print 'Only in %s: %s' % (left, x) + print('Only in %s: %s' % (left, x)) else: - print 'Only in %s: %s' % (right, x) + print('Only in %s: %s' % (right, x)) do_diff(left, right, True) diff --git a/bin/scons-proc.py b/bin/scons-proc.py index 9567db8..19be4c3 100644 --- a/bin/scons-proc.py +++ b/bin/scons-proc.py @@ -106,7 +106,7 @@ Link_Entities_Header = """\ class SCons_XML(object): def __init__(self, entries, **kw): self.values = entries - for k, v in kw.items(): + for k, v in list(kw.items()): setattr(self, k, v) def fopen(self, name): @@ -344,25 +344,25 @@ def write_output_files(h, buildersfiles, functionsfiles, processor_class = SCons_XML # Step 1: Creating entity files for builders, functions,... -print "Generating entity files..." +print("Generating entity files...") h = parse_docs(args, False) write_output_files(h, buildersfiles, functionsfiles, toolsfiles, variablesfiles, SCons_XML.write_mod) # Step 2: Validating all input files -print "Validating files against SCons XSD..." +print("Validating files against SCons XSD...") if SConsDoc.validate_all_xml(['src']): - print "OK" + print("OK") else: - print "Validation failed! Please correct the errors above and try again." + print("Validation failed! Please correct the errors above and try again.") # Step 3: Creating actual documentation snippets, using the # fully resolved and updated entities from the *.mod files. -print "Updating documentation for builders, tools and functions..." +print("Updating documentation for builders, tools and functions...") h = parse_docs(args, True) write_output_files(h, buildersfiles, functionsfiles, toolsfiles, variablesfiles, SCons_XML.write) -print "Done" +print("Done") # Local Variables: # tab-width:4 diff --git a/bin/scons-test.py b/bin/scons-test.py index 046cf4b..788fc6d 100644 --- a/bin/scons-test.py +++ b/bin/scons-test.py @@ -60,7 +60,7 @@ for o, a in opts: outdir = a elif o == '-v' or o == '--verbose': def printname(x): - print x + print(x) elif o == '--xml': format = o @@ -148,34 +148,34 @@ else: if format == '--xml': - print "" - print " " + print("") + print(" ") sys_keys = ['byteorder', 'exec_prefix', 'executable', 'maxint', 'maxunicode', 'platform', 'prefix', 'version', 'version_info'] for k in sys_keys: - print " <%s>%s" % (k, sys.__dict__[k], k) - print " " + print(" <%s>%s" % (k, sys.__dict__[k], k)) + print(" ") fmt = '%a %b %d %H:%M:%S %Y' - print " " + print(" ") - print " %s" % tempdir + print(" %s" % tempdir) def print_version_info(tag, module): - print " <%s>" % tag - print " %s" % module.__version__ - print " %s" % module.__build__ - print " %s" % module.__buildsys__ - print " %s" % module.__date__ - print " %s" % module.__developer__ - print " " % tag - - print " " + print(" <%s>" % tag) + print(" %s" % module.__version__) + print(" %s" % module.__build__) + print(" %s" % module.__buildsys__) + print(" %s" % module.__date__) + print(" %s" % module.__developer__) + print(" " % tag) + + print(" ") print_version_info("script", scons) print_version_info("engine", SCons) - print " " + print(" ") environ_keys = [ 'PATH', @@ -213,32 +213,32 @@ if format == '--xml': 'USER', ] - print " " + print(" ") for key in sorted(environ_keys): value = os.environ.get(key) if value: - print " " - print " %s" % key - print " %s" % value - print " " - print " " + print(" ") + print(" %s" % key) + print(" %s" % value) + print(" ") + print(" ") command = '"%s" runtest.py -q -o - --xml %s' % (sys.executable, runtest_args) #print command os.system(command) - print "" + print("") else: def print_version_info(tag, module): - print "\t%s: v%s.%s, %s, by %s on %s" % (tag, + print("\t%s: v%s.%s, %s, by %s on %s" % (tag, module.__version__, module.__build__, module.__date__, module.__developer__, - module.__buildsys__) + module.__buildsys__)) - print "SCons by Steven Knight et al.:" + print("SCons by Steven Knight et al.:") print_version_info("script", scons) print_version_info("engine", SCons) diff --git a/bin/scons-unzip.py b/bin/scons-unzip.py index d4ec4bf..75d3281 100644 --- a/bin/scons-unzip.py +++ b/bin/scons-unzip.py @@ -32,7 +32,7 @@ for o, a in opts: outdir = a elif o == '-v' or o == '--verbose': def printname(x): - print x + print(x) if len(args) != 1: sys.stderr.write("scons-unzip.py: \n") diff --git a/bin/scons_dev_master.py b/bin/scons_dev_master.py index 3c41ac0..71034ad 100644 --- a/bin/scons_dev_master.py +++ b/bin/scons_dev_master.py @@ -131,12 +131,12 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER] try: try: opts, args = getopt.getopt(argv[1:], short_options, long_options) - except getopt.error, msg: + except getopt.error as msg: raise Usage(msg) for o, a in opts: if o in ('-h', '--help'): - print helpstr + print(helpstr) sys.exit(0) elif o in ('-n', '--no-exec'): CommandRunner.execute = CommandRunner.do_not_execute @@ -148,7 +148,7 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER] username = a elif o in ('-y', '--yes', '--assume-yes'): yesflag = o - except Usage, err: + except Usage as err: sys.stderr.write(str(err.msg) + '\n') sys.stderr.write('use -h to get help\n') return 2 diff --git a/bin/svn-bisect.py b/bin/svn-bisect.py index 77bda58..f262366 100755 --- a/bin/svn-bisect.py +++ b/bin/svn-bisect.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- Python -*- -from __future__ import division + import sys from math import log, ceil @@ -28,22 +28,22 @@ script = script_args[2:] # print an error message and quit def error(s): - print >>sys.stderr, "******", s, "******" + print("******", s, "******", file=sys.stderr) sys.exit(1) # update to the specified version and run test def testfail(revision): "Return true if test fails" - print "Updating to revision", revision + print("Updating to revision", revision) if subprocess.call(["svn","up","-qr",str(revision)]) != 0: m = "SVN did not update properly to revision %d" raise RuntimeError(m % revision) return subprocess.call(script,shell=False) != 0 # confirm that the endpoints are different -print "****** Checking upper bracket", upper +print("****** Checking upper bracket", upper) upperfails = testfail(upper) -print "****** Checking lower bracket", lower +print("****** Checking lower bracket", lower) lowerfails = testfail(lower) if upperfails == lowerfails: error("Upper and lower revisions must bracket the failure") @@ -51,7 +51,7 @@ if upperfails == lowerfails: # binary search for transition msg = "****** max %d revisions to test (bug bracketed by [%d,%d])" while upper-lower > 1: - print msg % (ceil(log(upper-lower,2)), lower, upper) + print(msg % (ceil(log(upper-lower,2)), lower, upper)) mid = (lower + upper)//2 midfails = testfail(mid) @@ -64,7 +64,7 @@ while upper-lower > 1: # show which revision was first to fail if upperfails != lowerfails: lower = upper -print "The error was caused by revision", lower +print("The error was caused by revision", lower) # Local Variables: # tab-width:4 diff --git a/bin/update-release-info.py b/bin/update-release-info.py index 338bba9..f60c187 100644 --- a/bin/update-release-info.py +++ b/bin/update-release-info.py @@ -73,14 +73,14 @@ if len(sys.argv) < 2: else: mode = sys.argv[1] if mode not in ['develop', 'release', 'post']: - print("""ERROR: `%s' as a parameter is invalid; it must be one of -\tdevelop, release, or post. The default is develop.""" % mode) + print(("""ERROR: `%s' as a parameter is invalid; it must be one of +\tdevelop, release, or post. The default is develop.""" % mode)) sys.exit(1) # Get configuration information config = dict() -exec open('ReleaseConfig').read() in globals(), config +exec(open('ReleaseConfig').read(), globals(), config) try: version_tuple = config['version_tuple'] @@ -90,9 +90,9 @@ except KeyError: print('''ERROR: Config file must contain at least version_tuple, \tunsupported_python_version, and deprecated_python_version.''') sys.exit(1) -if DEBUG: print 'version tuple', version_tuple -if DEBUG: print 'unsupported Python version', unsupported_version -if DEBUG: print 'deprecated Python version', deprecated_version +if DEBUG: print('version tuple', version_tuple) +if DEBUG: print('unsupported Python version', unsupported_version) +if DEBUG: print('deprecated Python version', deprecated_version) try: release_date = config['release_date'] @@ -102,9 +102,9 @@ else: if len(release_date) == 3: release_date = release_date + time.localtime()[3:6] if len(release_date) != 6: - print '''ERROR: Invalid release date''', release_date + print('''ERROR: Invalid release date''', release_date) sys.exit(1) -if DEBUG: print 'release date', release_date +if DEBUG: print('release date', release_date) if mode == 'develop' and version_tuple[3] != 'alpha': version_tuple == version_tuple[:3] + ('alpha', 0) @@ -119,11 +119,11 @@ if len(version_tuple) > 3: version_type = version_tuple[3] else: version_type = 'final' -if DEBUG: print 'version string', version_string +if DEBUG: print('version string', version_string) if version_type not in ['alpha', 'beta', 'candidate', 'final']: - print("""ERROR: `%s' is not a valid release type in version tuple; -\tit must be one of alpha, beta, candidate, or final""" % version_type) + print(("""ERROR: `%s' is not a valid release type in version tuple; +\tit must be one of alpha, beta, candidate, or final""" % version_type)) sys.exit(1) try: @@ -133,13 +133,13 @@ except KeyError: month_year = 'MONTH YEAR' else: month_year = time.strftime('%B %Y', release_date + (0,0,0)) -if DEBUG: print 'month year', month_year +if DEBUG: print('month year', month_year) try: copyright_years = config['copyright_years'] except KeyError: copyright_years = ', '.join(map(str, list(range(2001, release_date[0] + 1)))) -if DEBUG: print 'copyright years', copyright_years +if DEBUG: print('copyright years', copyright_years) class UpdateFile(object): """ @@ -218,7 +218,7 @@ class UpdateFile(object): XXX ''' if self.file is not None and self.content != self.orig: - print 'Updating ' + self.file + '...' + print('Updating ' + self.file + '...') open(self.file, 'w').write(self.content) if mode == 'post': @@ -332,7 +332,7 @@ t.replace_assign('deprecated_python_version', str(deprecated_version)) # Update doc/user/main.{in,xml} -docyears = ', '.join(map(str, iter(range(2004, release_date[0] + 1)))) +docyears = ', '.join(map(str, iter(list(range(2004, release_date[0] + 1))))) t = UpdateFile(os.path.join('doc', 'user', 'main.in')) if DEBUG: t.file = '/tmp/main.in' ## TODO debug these diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py index b3cd520..40f5ca1 100755 --- a/bin/xmlagenda.py +++ b/bin/xmlagenda.py @@ -89,7 +89,7 @@ for issue in issues: writer.writerow(['','','','','','','']) for member in team: writer.writerow(['','',member,'','','','']) -print "Exported %d issues to editlist.csv. Ready to upload to Google."%len(issues) +print("Exported %d issues to editlist.csv. Ready to upload to Google."%len(issues)) # Local Variables: # tab-width:4 diff --git a/review.py b/review.py index 23e4b10..72e187e 100644 --- a/review.py +++ b/review.py @@ -1,1805 +1,1806 @@ -#!/usr/bin/env python -# -# Copyright 2007 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Tool for uploading diffs from a version control system to the codereview app. - -Usage summary: upload.py [options] [-- diff_options] [path...] - -Diff options are passed to the diff command of the underlying system. - -Supported version control systems: - Git - Mercurial - Subversion - -It is important for Git/Mercurial users to specify a tree/node/branch to diff -against by using the '--rev' option. -""" -# This code is derived from appcfg.py in the App Engine SDK (open source), -# and from ASPN recipe #146306. - -import ConfigParser -import cookielib -import fnmatch -import getpass -import logging -import mimetypes -import optparse -import os -import re -import socket -import subprocess -import sys -import urllib -import urllib2 -import urlparse - -# The md5 module was deprecated in Python 2.5. -try: - from hashlib import md5 -except ImportError: - from md5 import md5 - -try: - import readline -except ImportError: - pass - -try: - import keyring -except ImportError: - keyring = None - -# The logging verbosity: -# 0: Errors only. -# 1: Status messages. -# 2: Info logs. -# 3: Debug logs. -verbosity = 1 - -# The account type used for authentication. -# This line could be changed by the review server (see handler for -# upload.py). -AUTH_ACCOUNT_TYPE = "GOOGLE" - -# URL of the default review server. As for AUTH_ACCOUNT_TYPE, this line could be -# changed by the review server (see handler for upload.py). -DEFAULT_REVIEW_SERVER = "codereview.appspot.com" - -# Max size of patch or base file. -MAX_UPLOAD_SIZE = 900 * 1024 - -# Constants for version control names. Used by GuessVCSName. -VCS_GIT = "Git" -VCS_MERCURIAL = "Mercurial" -VCS_SUBVERSION = "Subversion" -VCS_UNKNOWN = "Unknown" - -# whitelist for non-binary filetypes which do not start with "text/" -# .mm (Objective-C) shows up as application/x-freemind on my Linux box. -TEXT_MIMETYPES = ['application/javascript', 'application/x-javascript', - 'application/xml', 'application/x-freemind', - 'application/x-sh'] - -VCS_ABBREVIATIONS = { - VCS_MERCURIAL.lower(): VCS_MERCURIAL, - "hg": VCS_MERCURIAL, - VCS_SUBVERSION.lower(): VCS_SUBVERSION, - "svn": VCS_SUBVERSION, - VCS_GIT.lower(): VCS_GIT, -} - -# The result of parsing Subversion's [auto-props] setting. -svn_auto_props_map = None - -def GetEmail(prompt): - """Prompts the user for their email address and returns it. - - The last used email address is saved to a file and offered up as a suggestion - to the user. If the user presses enter without typing in anything the last - used email address is used. If the user enters a new address, it is saved - for next time we prompt. - - """ - last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") - last_email = "" - if os.path.exists(last_email_file_name): - try: - last_email_file = open(last_email_file_name, "r") - last_email = last_email_file.readline().strip("\n") - last_email_file.close() - prompt += " [%s]" % last_email - except IOError, e: - pass - email = raw_input(prompt + ": ").strip() - if email: - try: - last_email_file = open(last_email_file_name, "w") - last_email_file.write(email) - last_email_file.close() - except IOError, e: - pass - else: - email = last_email - return email - - -def StatusUpdate(msg): - """Print a status message to stdout. - - If 'verbosity' is greater than 0, print the message. - - Args: - msg: The string to print. - """ - if verbosity > 0: - print msg - - -def ErrorExit(msg): - """Print an error message to stderr and exit.""" - print >>sys.stderr, msg - sys.exit(1) - - -class ClientLoginError(urllib2.HTTPError): - """Raised to indicate there was an error authenticating with ClientLogin.""" - - def __init__(self, url, code, msg, headers, args): - urllib2.HTTPError.__init__(self, url, code, msg, headers, None) - self.args = args - self.reason = args["Error"] - self.info = args.get("Info", None) - - -class AbstractRpcServer(object): - """Provides a common interface for a simple RPC server.""" - - def __init__(self, host, auth_function, host_override=None, extra_headers={}, - save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): - """Creates a new HttpRpcServer. - - Args: - host: The host to send requests to. - auth_function: A function that takes no arguments and returns an - (email, password) tuple when called. Will be called if authentication - is required. - host_override: The host header to send to the server (defaults to host). - extra_headers: A dict of extra headers to append to every request. - save_cookies: If True, save the authentication cookies to local disk. - If False, use an in-memory cookiejar instead. Subclasses must - implement this functionality. Defaults to False. - account_type: Account type used for authentication. Defaults to - AUTH_ACCOUNT_TYPE. - """ - self.host = host - if (not self.host.startswith("http://") and - not self.host.startswith("https://")): - self.host = "http://" + self.host - self.host_override = host_override - self.auth_function = auth_function - self.authenticated = False - self.extra_headers = extra_headers - self.save_cookies = save_cookies - self.account_type = account_type - self.opener = self._GetOpener() - if self.host_override: - logging.info("Server: %s; Host: %s", self.host, self.host_override) - else: - logging.info("Server: %s", self.host) - - def _GetOpener(self): - """Returns an OpenerDirector for making HTTP requests. - - Returns: - A urllib2.OpenerDirector object. - """ - raise NotImplementedError() - - def _CreateRequest(self, url, data=None): - """Creates a new urllib request.""" - logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib2.Request(url, data=data) - if self.host_override: - req.add_header("Host", self.host_override) - for key, value in self.extra_headers.iteritems(): - req.add_header(key, value) - return req - - def _GetAuthToken(self, email, password): - """Uses ClientLogin to authenticate the user, returning an auth token. - - Args: - email: The user's email address - password: The user's password - - Raises: - ClientLoginError: If there was an error authenticating with ClientLogin. - HTTPError: If there was some other form of HTTP error. - - Returns: - The authentication token returned by ClientLogin. - """ - account_type = self.account_type - if self.host.endswith(".google.com"): - # Needed for use inside Google. - account_type = "HOSTED" - req = self._CreateRequest( - url="https://www.google.com/accounts/ClientLogin", - data=urllib.urlencode({ - "Email": email, - "Passwd": password, - "service": "ah", - "source": "rietveld-codereview-upload", - "accountType": account_type, - }), - ) - try: - response = self.opener.open(req) - response_body = response.read() - response_dict = dict(x.split("=") - for x in response_body.split("\n") if x) - return response_dict["Auth"] - except urllib2.HTTPError, e: - if e.code == 403: - body = e.read() - response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) - raise ClientLoginError(req.get_full_url(), e.code, e.msg, - e.headers, response_dict) - else: - raise - - def _GetAuthCookie(self, auth_token): - """Fetches authentication cookies for an authentication token. - - Args: - auth_token: The authentication token returned by ClientLogin. - - Raises: - HTTPError: If there was an error fetching the authentication cookies. - """ - # This is a dummy value to allow us to identify when we're successful. - continue_location = "http://localhost/" - args = {"continue": continue_location, "auth": auth_token} - req = self._CreateRequest("%s/_ah/login?%s" % - (self.host, urllib.urlencode(args))) - try: - response = self.opener.open(req) - except urllib2.HTTPError, e: - response = e - if (response.code != 302 or - response.info()["location"] != continue_location): - raise urllib2.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) - self.authenticated = True - - def _Authenticate(self): - """Authenticates the user. - - The authentication process works as follows: - 1) We get a username and password from the user - 2) We use ClientLogin to obtain an AUTH token for the user - (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). - 3) We pass the auth token to /_ah/login on the server to obtain an - authentication cookie. If login was successful, it tries to redirect - us to the URL we provided. - - If we attempt to access the upload API without first obtaining an - authentication cookie, it returns a 401 response (or a 302) and - directs us to authenticate ourselves with ClientLogin. - """ - for i in range(3): - credentials = self.auth_function() - try: - auth_token = self._GetAuthToken(credentials[0], credentials[1]) - except ClientLoginError, e: - print >>sys.stderr, '' - if e.reason == "BadAuthentication": - if e.info == "InvalidSecondFactor": - print >>sys.stderr, ( - "Use an application-specific password instead " - "of your regular account password.\n" - "See http://www.google.com/" - "support/accounts/bin/answer.py?answer=185833") - else: - print >>sys.stderr, "Invalid username or password." - elif e.reason == "CaptchaRequired": - print >>sys.stderr, ( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.\n" - "If you are using a Google Apps account the URL is:\n" - "https://www.google.com/a/yourdomain.com/UnlockCaptcha") - elif e.reason == "NotVerified": - print >>sys.stderr, "Account not verified." - elif e.reason == "TermsNotAgreed": - print >>sys.stderr, "User has not agreed to TOS." - elif e.reason == "AccountDeleted": - print >>sys.stderr, "The user account has been deleted." - elif e.reason == "AccountDisabled": - print >>sys.stderr, "The user account has been disabled." - break - elif e.reason == "ServiceDisabled": - print >>sys.stderr, ("The user's access to the service has been " - "disabled.") - elif e.reason == "ServiceUnavailable": - print >>sys.stderr, "The service is not available; try again later." - else: - # Unknown error. - raise - print >>sys.stderr, '' - continue - self._GetAuthCookie(auth_token) - return - - def Send(self, request_path, payload=None, - content_type="application/octet-stream", - timeout=None, - extra_headers=None, - **kwargs): - """Sends an RPC and returns the response. - - Args: - request_path: The path to send the request to, eg /api/appversion/create. - payload: The body of the request, or None to send an empty request. - content_type: The Content-Type header to use. - timeout: timeout in seconds; default None i.e. no timeout. - (Note: for large requests on OS X, the timeout doesn't work right.) - extra_headers: Dict containing additional HTTP headers that should be - included in the request (string header names mapped to their values), - or None to not include any additional headers. - kwargs: Any keyword arguments are converted into query string parameters. - - Returns: - The response body, as a string. - """ - # TODO: Don't require authentication. Let the server say - # whether it is necessary. - if not self.authenticated: - self._Authenticate() - - old_timeout = socket.getdefaulttimeout() - socket.setdefaulttimeout(timeout) - try: - tries = 0 - while True: - tries += 1 - args = dict(kwargs) - url = "%s%s" % (self.host, request_path) - if args: - url += "?" + urllib.urlencode(args) - req = self._CreateRequest(url=url, data=payload) - req.add_header("Content-Type", content_type) - if extra_headers: - for header, value in extra_headers.items(): - req.add_header(header, value) - try: - f = self.opener.open(req) - response = f.read() - f.close() - return response - except urllib2.HTTPError, e: - if tries > 3: - raise - elif e.code == 401 or e.code == 302: - self._Authenticate() -## elif e.code >= 500 and e.code < 600: -## # Server Error - try again. -## continue - elif e.code == 301: - # Handle permanent redirect manually. - url = e.info()["location"] - url_loc = urlparse.urlparse(url) - self.host = '%s://%s' % (url_loc[0], url_loc[1]) - else: - raise - finally: - socket.setdefaulttimeout(old_timeout) - - -class HttpRpcServer(AbstractRpcServer): - """Provides a simplified RPC-style interface for HTTP requests.""" - - def _Authenticate(self): - """Save the cookie jar after authentication.""" - super(HttpRpcServer, self)._Authenticate() - if self.save_cookies: - StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) - self.cookie_jar.save() - - def _GetOpener(self): - """Returns an OpenerDirector that supports cookies and ignores redirects. - - Returns: - A urllib2.OpenerDirector object. - """ - opener = urllib2.OpenerDirector() - opener.add_handler(urllib2.ProxyHandler()) - opener.add_handler(urllib2.UnknownHandler()) - opener.add_handler(urllib2.HTTPHandler()) - opener.add_handler(urllib2.HTTPDefaultErrorHandler()) - opener.add_handler(urllib2.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) - if self.save_cookies: - self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = cookielib.MozillaCookieJar(self.cookie_file) - if os.path.exists(self.cookie_file): - try: - self.cookie_jar.load() - self.authenticated = True - StatusUpdate("Loaded authentication cookies from %s" % - self.cookie_file) - except (cookielib.LoadError, IOError): - # Failed to load cookies - just ignore them. - pass - else: - # Create an empty cookie file with mode 600 - fd = os.open(self.cookie_file, os.O_CREAT, 0600) - os.close(fd) - # Always chmod the cookie file - os.chmod(self.cookie_file, 0600) - else: - # Don't save cookies across runs of update.py. - self.cookie_jar = cookielib.CookieJar() - opener.add_handler(urllib2.HTTPCookieProcessor(self.cookie_jar)) - return opener - - -parser = optparse.OptionParser( - usage="%prog [options] [-- diff_options] [path...]") -parser.add_option("-y", "--assume_yes", action="store_true", - dest="assume_yes", default=False, - help="Assume that the answer to yes/no questions is 'yes'.") -# Logging -group = parser.add_option_group("Logging options") -group.add_option("-q", "--quiet", action="store_const", const=0, - dest="verbose", help="Print errors only.") -group.add_option("-v", "--verbose", action="store_const", const=2, - dest="verbose", default=1, - help="Print info level logs.") -group.add_option("--noisy", action="store_const", const=3, - dest="verbose", help="Print all logs.") -# Review server -group = parser.add_option_group("Review server options") -group.add_option("-s", "--server", action="store", dest="server", - default=DEFAULT_REVIEW_SERVER, - metavar="SERVER", - help=("The server to upload to. The format is host[:port]. " - "Defaults to '%default'.")) -group.add_option("-e", "--email", action="store", dest="email", - metavar="EMAIL", default=None, - help="The username to use. Will prompt if omitted.") -group.add_option("-H", "--host", action="store", dest="host", - metavar="HOST", default=None, - help="Overrides the Host header sent with all RPCs.") -group.add_option("--no_cookies", action="store_false", - dest="save_cookies", default=True, - help="Do not save authentication cookies to local disk.") -group.add_option("--account_type", action="store", dest="account_type", - metavar="TYPE", default=AUTH_ACCOUNT_TYPE, - choices=["GOOGLE", "HOSTED"], - help=("Override the default account type " - "(defaults to '%default', " - "valid choices are 'GOOGLE' and 'HOSTED').")) -# Issue -group = parser.add_option_group("Issue options") -group.add_option("-d", "--description", action="store", dest="description", - metavar="DESCRIPTION", default=None, - help="Optional description when creating an issue.") -group.add_option("-f", "--description_file", action="store", - dest="description_file", metavar="DESCRIPTION_FILE", - default=None, - help="Optional path of a file that contains " - "the description when creating an issue.") -group.add_option("-r", "--reviewers", action="store", dest="reviewers", - metavar="REVIEWERS", default=None, - help="Add reviewers (comma separated email addresses).") -group.add_option("--cc", action="store", dest="cc", - metavar="CC", default="dev@scons.tigris.org", - help="Add CC (comma separated email addresses).") -group.add_option("--private", action="store_true", dest="private", - default=False, - help="Make the issue restricted to reviewers and those CCed") -# Upload options -group = parser.add_option_group("Patch options") -group.add_option("-m", "--message", action="store", dest="message", - metavar="MESSAGE", default=None, - help="A message to identify the patch. " - "Will prompt if omitted.") -group.add_option("-i", "--issue", type="int", action="store", - metavar="ISSUE", default=None, - help="Issue number to which to add. Defaults to new issue.") -group.add_option("--base_url", action="store", dest="base_url", default=None, - help="Base repository URL (listed as \"Base URL\" when " - "viewing issue). If omitted, will be guessed automatically " - "for SVN repos and left blank for others.") -group.add_option("--download_base", action="store_true", - dest="download_base", default=False, - help="Base files will be downloaded by the server " - "(side-by-side diffs may not work on files with CRs).") -group.add_option("--rev", action="store", dest="revision", - metavar="REV", default=None, - help="Base revision/branch/tree to diff against. Use " - "rev1:rev2 range to review already committed changeset.") -group.add_option("--send_mail", action="store_true", - dest="send_mail", default=True, - help="Send notification email to reviewers.") -group.add_option("--vcs", action="store", dest="vcs", - metavar="VCS", default="svn", - help=("Version control system (optional, usually upload.py " - "already guesses the right VCS).")) -group.add_option("--emulate_svn_auto_props", action="store_true", - dest="emulate_svn_auto_props", default=False, - help=("Emulate Subversion's auto properties feature.")) - - -def GetRpcServer(server, email=None, host_override=None, save_cookies=True, - account_type=AUTH_ACCOUNT_TYPE): - """Returns an instance of an AbstractRpcServer. - - Args: - server: String containing the review server URL. - email: String containing user's email address. - host_override: If not None, string containing an alternate hostname to use - in the host header. - save_cookies: Whether authentication cookies should be saved to disk. - account_type: Account type for authentication, either 'GOOGLE' - or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. - - Returns: - A new AbstractRpcServer, on which RPC calls can be made. - """ - - rpc_server_class = HttpRpcServer - - # If this is the dev_appserver, use fake authentication. - host = (host_override or server).lower() - if re.match(r'(http://)?localhost([:/]|$)', host): - if email is None: - email = "test@example.com" - logging.info("Using debug user %s. Override with --email" % email) - server = rpc_server_class( - server, - lambda: (email, "password"), - host_override=host_override, - extra_headers={"Cookie": - 'dev_appserver_login="%s:False"' % email}, - save_cookies=save_cookies, - account_type=account_type) - # Don't try to talk to ClientLogin. - server.authenticated = True - return server - - def GetUserCredentials(): - """Prompts the user for a username and password.""" - # Create a local alias to the email variable to avoid Python's crazy - # scoping rules. - local_email = email - if local_email is None: - local_email = GetEmail("Email (login for uploading to %s)" % server) - password = None - if keyring: - password = keyring.get_password(host, local_email) - if password is not None: - print "Using password from system keyring." - else: - password = getpass.getpass("Password for %s: " % local_email) - if keyring: - answer = raw_input("Store password in system keyring?(y/N) ").strip() - if answer == "y": - keyring.set_password(host, local_email, password) - return (local_email, password) - - return rpc_server_class(server, - GetUserCredentials, - host_override=host_override, - save_cookies=save_cookies) - - -def EncodeMultipartFormData(fields, files): - """Encode form fields for multipart/form-data. - - Args: - fields: A sequence of (name, value) elements for regular form fields. - files: A sequence of (name, filename, value) elements for data to be - uploaded as files. - Returns: - (content_type, body) ready for httplib.HTTP instance. - - Source: - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 - """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' - CRLF = '\r\n' - lines = [] - for (key, value) in fields: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"' % key) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - for (key, filename, value) in files: - lines.append('--' + BOUNDARY) - lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % - (key, filename)) - lines.append('Content-Type: %s' % GetContentType(filename)) - lines.append('') - if isinstance(value, unicode): - value = value.encode('utf-8') - lines.append(value) - lines.append('--' + BOUNDARY + '--') - lines.append('') - body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - -def GetContentType(filename): - """Helper to guess the content-type from the filename.""" - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - -# Use a shell for subcommands on Windows to get a PATH search. -use_shell = sys.platform.startswith("win") - -def RunShellWithReturnCodeAndStderr(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout, stderr and the return code. - - Args: - command: Command to execute. - print_output: If True, the output is printed to stdout. - If False, both stdout and stderr are ignored. - universal_newlines: Use universal_newlines flag (default: True). - - Returns: - Tuple (stdout, stderr, return code) - """ - logging.info("Running %s", command) - env = env.copy() - env['LC_MESSAGES'] = 'C' - p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=use_shell, universal_newlines=universal_newlines, - env=env) - if print_output: - output_array = [] - while True: - line = p.stdout.readline() - if not line: - break - print line.strip("\n") - output_array.append(line) - output = "".join(output_array) - else: - output = p.stdout.read() - p.wait() - errout = p.stderr.read() - if print_output and errout: - print >>sys.stderr, errout - p.stdout.close() - p.stderr.close() - return output, errout, p.returncode - -def RunShellWithReturnCode(command, print_output=False, - universal_newlines=True, - env=os.environ): - """Executes a command and returns the output from stdout and the return code.""" - out, err, retcode = RunShellWithReturnCodeAndStderr(command, print_output, - universal_newlines, env) - return out, retcode - -def RunShell(command, silent_ok=False, universal_newlines=True, - print_output=False, env=os.environ): - data, retcode = RunShellWithReturnCode(command, print_output, - universal_newlines, env) - if retcode: - ErrorExit("Got error status from %s:\n%s" % (command, data)) - if not silent_ok and not data: - ErrorExit("No output from %s" % command) - return data - - -class VersionControlSystem(object): - """Abstract base class providing an interface to the VCS.""" - - def __init__(self, options): - """Constructor. - - Args: - options: Command line options. - """ - self.options = options - - def PostProcessDiff(self, diff): - """Return the diff with any special post processing this VCS needs, e.g. - to include an svn-style "Index:".""" - return diff - - def GenerateDiff(self, args): - """Return the current diff as a string. - - Args: - args: Extra arguments to pass to the diff command. - """ - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - def CheckForUnknownFiles(self): - """Show an "are you sure?" prompt if there are unknown files.""" - unknown_files = self.GetUnknownFiles() - if unknown_files: - print "The following files are not added to version control:" - for line in unknown_files: - print line - prompt = "Are you sure to continue?(y/N) " - answer = raw_input(prompt).strip() - if answer != "y": - ErrorExit("User aborted") - - def GetBaseFile(self, filename): - """Get the content of the upstream version of a file. - - Returns: - A tuple (base_content, new_content, is_binary, status) - base_content: The contents of the base file. - new_content: For text files, this is empty. For binary files, this is - the contents of the new file, since the diff output won't contain - information to reconstruct the current file. - is_binary: True iff the file is binary. - status: The status of the file. - """ - - raise NotImplementedError( - "abstract method -- subclass %s must override" % self.__class__) - - - def GetBaseFiles(self, diff): - """Helper that calls GetBase file for each file in the patch. - - Returns: - A dictionary that maps from filename to GetBaseFile's tuple. Filenames - are retrieved based on lines that start with "Index:" or - "Property changes on:". - """ - files = {} - for line in diff.splitlines(True): - if line.startswith('Index:') or line.startswith('Property changes on:'): - unused, filename = line.split(':', 1) - # On Windows if a file has property changes its filename uses '\' - # instead of '/'. - filename = filename.strip().replace('\\', '/') - files[filename] = self.GetBaseFile(filename) - return files - - - def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, - files): - """Uploads the base files (and if necessary, the current ones as well).""" - - def UploadFile(filename, file_id, content, is_binary, status, is_base): - """Uploads a file to the server.""" - file_too_large = False - if is_base: - type = "base" - else: - type = "current" - if len(content) > MAX_UPLOAD_SIZE: - print ("Not uploading the %s file for %s because it's too large." % - (type, filename)) - file_too_large = True - content = "" - checksum = md5(content).hexdigest() - if options.verbose > 0 and not file_too_large: - print "Uploading %s file for %s" % (type, filename) - url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) - form_fields = [("filename", filename), - ("status", status), - ("checksum", checksum), - ("is_binary", str(is_binary)), - ("is_current", str(not is_base)), - ] - if file_too_large: - form_fields.append(("file_too_large", "1")) - if options.email: - form_fields.append(("user", options.email)) - ctype, body = EncodeMultipartFormData(form_fields, - [("data", filename, content)]) - response_body = rpc_server.Send(url, body, - content_type=ctype) - if not response_body.startswith("OK"): - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - - patches = dict() - [patches.setdefault(v, k) for k, v in patch_list] - for filename in patches.keys(): - base_content, new_content, is_binary, status = files[filename] - file_id_str = patches.get(filename) - if file_id_str.find("nobase") != -1: - base_content = None - file_id_str = file_id_str[file_id_str.rfind("_") + 1:] - file_id = int(file_id_str) - if base_content != None: - UploadFile(filename, file_id, base_content, is_binary, status, True) - if new_content != None: - UploadFile(filename, file_id, new_content, is_binary, status, False) - - def IsImage(self, filename): - """Returns true if the filename has an image extension.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False - return mimetype.startswith("image/") - - def IsBinary(self, filename): - """Returns true if the guessed mimetyped isnt't in text group.""" - mimetype = mimetypes.guess_type(filename)[0] - if not mimetype: - return False # e.g. README, "real" binaries usually have an extension - # special case for text files which don't start with text/ - if mimetype in TEXT_MIMETYPES: - return False - return not mimetype.startswith("text/") - - -class SubversionVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Subversion.""" - - def __init__(self, options): - super(SubversionVCS, self).__init__(options) - if self.options.revision: - match = re.match(r"(\d+)(:(\d+))?", self.options.revision) - if not match: - ErrorExit("Invalid Subversion revision %s." % self.options.revision) - self.rev_start = match.group(1) - self.rev_end = match.group(3) - else: - self.rev_start = self.rev_end = None - # Cache output from "svn list -r REVNO dirname". - # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). - self.svnls_cache = {} - # Base URL is required to fetch files deleted in an older revision. - # Result is cached to not guess it over and over again in GetBaseFile(). - required = self.options.download_base or self.options.revision is not None - self.svn_base = self._GuessBase(required) - - def GuessBase(self, required): - """Wrapper for _GuessBase.""" - return self.svn_base - - def _GuessBase(self, required): - """Returns base URL for current diff. - - Args: - required: If true, exits if the url can't be guessed, otherwise None is - returned. - """ - info = RunShell(["svn", "info"]) - for line in info.splitlines(): - if line.startswith("URL: "): - url = line.split()[1] - scheme, netloc, path, params, query, fragment = urlparse.urlparse(url) - guess = "" - if netloc == "svn.python.org" and scheme == "svn+ssh": - path = "projects" + path - scheme = "http" - guess = "Python " - elif netloc.endswith(".googlecode.com"): - scheme = "http" - guess = "Google Code " - path = path + "/" - base = urlparse.urlunparse((scheme, netloc, path, params, - query, fragment)) - logging.info("Guessed %sbase = %s", guess, base) - return base - if required: - ErrorExit("Can't find URL in output from svn info") - return None - - def GenerateDiff(self, args): - cmd = ["svn", "diff"] - if self.options.revision: - cmd += ["-r", self.options.revision] - cmd.extend(args) - data = RunShell(cmd) - count = 0 - for line in data.splitlines(): - if line.startswith("Index:") or line.startswith("Property changes on:"): - count += 1 - logging.info(line) - if not count: - ErrorExit("No valid patches found in output from svn diff") - return data - - def _CollapseKeywords(self, content, keyword_str): - """Collapses SVN keywords.""" - # svn cat translates keywords but svn diff doesn't. As a result of this - # behavior patching.PatchChunks() fails with a chunk mismatch error. - # This part was originally written by the Review Board development team - # who had the same problem (http://reviews.review-board.org/r/276/). - # Mapping of keywords to known aliases - svn_keywords = { - # Standard keywords - 'Date': ['Date', 'LastChangedDate'], - 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], - 'Author': ['Author', 'LastChangedBy'], - 'HeadURL': ['HeadURL', 'URL'], - 'Id': ['Id'], - - # Aliases - 'LastChangedDate': ['LastChangedDate', 'Date'], - 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], - 'LastChangedBy': ['LastChangedBy', 'Author'], - 'URL': ['URL', 'HeadURL'], - } - - def repl(m): - if m.group(2): - return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) - return "$%s$" % m.group(1) - keywords = [keyword - for name in keyword_str.split(" ") - for keyword in svn_keywords.get(name, [])] - return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) - - def GetUnknownFiles(self): - status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) - unknown_files = [] - for line in status.split("\n"): - if line and line[0] == "?": - unknown_files.append(line) - return unknown_files - - def ReadFile(self, filename): - """Returns the contents of a file.""" - file = open(filename, 'rb') - result = "" - try: - result = file.read() - finally: - file.close() - return result - - def GetStatus(self, filename): - """Returns the status of a file.""" - if not self.options.revision: - status = RunShell(["svn", "status", "--ignore-externals", filename]) - if not status: - ErrorExit("svn status returned no output for %s" % filename) - status_lines = status.splitlines() - # If file is in a cl, the output will begin with - # "\n--- Changelist 'cl_name':\n". See - # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt - if (len(status_lines) == 3 and - not status_lines[0] and - status_lines[1].startswith("--- Changelist")): - status = status_lines[2] - else: - status = status_lines[0] - # If we have a revision to diff against we need to run "svn list" - # for the old and the new revision and compare the results to get - # the correct status for a file. - else: - dirname, relfilename = os.path.split(filename) - if dirname not in self.svnls_cache: - cmd = ["svn", "list", "-r", self.rev_start, dirname or "."] - out, err, returncode = RunShellWithReturnCodeAndStderr(cmd) - if returncode: - # Directory might not yet exist at start revison - # svn: Unable to find repository location for 'abc' in revision nnn - if re.match('^svn: Unable to find repository location for .+ in revision \d+', err): - old_files = () - else: - ErrorExit("Failed to get status for %s:\n%s" % (filename, err)) - else: - old_files = out.splitlines() - args = ["svn", "list"] - if self.rev_end: - args += ["-r", self.rev_end] - cmd = args + [dirname or "."] - out, returncode = RunShellWithReturnCode(cmd) - if returncode: - ErrorExit("Failed to run command %s" % cmd) - self.svnls_cache[dirname] = (old_files, out.splitlines()) - old_files, new_files = self.svnls_cache[dirname] - if relfilename in old_files and relfilename not in new_files: - status = "D " - elif relfilename in old_files and relfilename in new_files: - status = "M " - else: - status = "A " - return status - - def GetBaseFile(self, filename): - status = self.GetStatus(filename) - base_content = None - new_content = None - - # If a file is copied its status will be "A +", which signifies - # "addition-with-history". See "svn st" for more information. We need to - # upload the original file or else diff parsing will fail if the file was - # edited. - if status[0] == "A" and status[3] != "+": - # We'll need to upload the new content if we're adding a binary file - # since diff's output won't contain it. - mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], - silent_ok=True) - base_content = "" - is_binary = bool(mimetype) and not mimetype.startswith("text/") - if is_binary and self.IsImage(filename): - new_content = self.ReadFile(filename) - elif (status[0] in ("M", "D", "R") or - (status[0] == "A" and status[3] == "+") or # Copied file. - (status[0] == " " and status[1] == "M")): # Property change. - args = [] - if self.options.revision: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - # Don't change filename, it's needed later. - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:mime-type", url] - mimetype, returncode = RunShellWithReturnCode(cmd) - if returncode: - # File does not exist in the requested revision. - # Reset mimetype, it contains an error message. - mimetype = "" - else: - mimetype = mimetype.strip() - get_base = False - is_binary = (bool(mimetype) and - not mimetype.startswith("text/") and - not mimetype in TEXT_MIMETYPES) - if status[0] == " ": - # Empty base content just to force an upload. - base_content = "" - elif is_binary: - if self.IsImage(filename): - get_base = True - if status[0] == "M": - if not self.rev_end: - new_content = self.ReadFile(filename) - else: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) - new_content = RunShell(["svn", "cat", url], - universal_newlines=True, silent_ok=True) - else: - base_content = "" - else: - get_base = True - - if get_base: - if is_binary: - universal_newlines = False - else: - universal_newlines = True - if self.rev_start: - # "svn cat -r REV delete_file.txt" doesn't work. cat requires - # the full URL with "@REV" appended instead of using "-r" option. - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - else: - base_content, ret_code = RunShellWithReturnCode( - ["svn", "cat", filename], universal_newlines=universal_newlines) - if ret_code and status[0] == "R": - # It's a replaced file without local history (see issue208). - # The base file needs to be fetched from the server. - url = "%s/%s" % (self.svn_base, filename) - base_content = RunShell(["svn", "cat", url], - universal_newlines=universal_newlines, - silent_ok=True) - elif ret_code: - ErrorExit("Got error status from 'svn cat %s'" % filename) - if not is_binary: - args = [] - if self.rev_start: - url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) - else: - url = filename - args += ["-r", "BASE"] - cmd = ["svn"] + args + ["propget", "svn:keywords", url] - keywords, returncode = RunShellWithReturnCode(cmd) - if keywords and not returncode: - base_content = self._CollapseKeywords(base_content, keywords) - else: - StatusUpdate("svn status returned unexpected output: %s" % status) - sys.exit(1) - return base_content, new_content, is_binary, status[0:5] - - -class GitVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Git.""" - - def __init__(self, options): - super(GitVCS, self).__init__(options) - # Map of filename -> (hash before, hash after) of base file. - # Hashes for "no such file" are represented as None. - self.hashes = {} - # Map of new filename -> old filename for renames. - self.renames = {} - - def PostProcessDiff(self, gitdiff): - """Converts the diff output to include an svn-style "Index:" line as well - as record the hashes of the files, so we can upload them along with our - diff.""" - # Special used by git to indicate "no such content". - NULL_HASH = "0"*40 - - def IsFileNew(filename): - return filename in self.hashes and self.hashes[filename][0] is None - - def AddSubversionPropertyChange(filename): - """Add svn's property change information into the patch if given file is - new file. - - We use Subversion's auto-props setting to retrieve its property. - See http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2 for - Subversion's [auto-props] setting. - """ - if self.options.emulate_svn_auto_props and IsFileNew(filename): - svnprops = GetSubversionPropertyChanges(filename) - if svnprops: - svndiff.append("\n" + svnprops + "\n") - - svndiff = [] - filecount = 0 - filename = None - for line in gitdiff.splitlines(): - match = re.match(r"diff --git a/(.*) b/(.*)$", line) - if match: - # Add auto property here for previously seen file. - if filename is not None: - AddSubversionPropertyChange(filename) - filecount += 1 - # Intentionally use the "after" filename so we can show renames. - filename = match.group(2) - svndiff.append("Index: %s\n" % filename) - if match.group(1) != match.group(2): - self.renames[match.group(2)] = match.group(1) - else: - # The "index" line in a git diff looks like this (long hashes elided): - # index 82c0d44..b2cee3f 100755 - # We want to save the left hash, as that identifies the base file. - match = re.match(r"index (\w+)\.\.(\w+)", line) - if match: - before, after = (match.group(1), match.group(2)) - if before == NULL_HASH: - before = None - if after == NULL_HASH: - after = None - self.hashes[filename] = (before, after) - svndiff.append(line + "\n") - if not filecount: - ErrorExit("No valid patches found in output from git diff") - # Add auto property for the last seen file. - assert filename is not None - AddSubversionPropertyChange(filename) - return "".join(svndiff) - - def GenerateDiff(self, extra_args): - extra_args = extra_args[:] - if self.options.revision: - if ":" in self.options.revision: - extra_args = self.options.revision.split(":", 1) + extra_args - else: - extra_args = [self.options.revision] + extra_args - - # --no-ext-diff is broken in some versions of Git, so try to work around - # this by overriding the environment (but there is still a problem if the - # git config key "diff.external" is used). - env = os.environ.copy() - if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] - return RunShell(["git", "diff", "--no-ext-diff", "--full-index", "-M"] - + extra_args, env=env) - - def GetUnknownFiles(self): - status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], - silent_ok=True) - return status.splitlines() - - def GetFileContent(self, file_hash, is_binary): - """Returns the content of a file identified by its git hash.""" - data, retcode = RunShellWithReturnCode(["git", "show", file_hash], - universal_newlines=not is_binary) - if retcode: - ErrorExit("Got error status from 'git show %s'" % file_hash) - return data - - def GetBaseFile(self, filename): - hash_before, hash_after = self.hashes.get(filename, (None,None)) - base_content = None - new_content = None - is_binary = self.IsBinary(filename) - status = None - - if filename in self.renames: - status = "A +" # Match svn attribute name for renames. - if filename not in self.hashes: - # If a rename doesn't change the content, we never get a hash. - base_content = RunShell(["git", "show", "HEAD:" + filename]) - elif not hash_before: - status = "A" - base_content = "" - elif not hash_after: - status = "D" - else: - status = "M" - - is_image = self.IsImage(filename) - - # Grab the before/after content if we need it. - # We should include file contents if it's text or it's an image. - if not is_binary or is_image: - # Grab the base content if we don't have it already. - if base_content is None and hash_before: - base_content = self.GetFileContent(hash_before, is_binary) - # Only include the "after" file if it's an image; otherwise it - # it is reconstructed from the diff. - if is_image and hash_after: - new_content = self.GetFileContent(hash_after, is_binary) - - return (base_content, new_content, is_binary, status) - - -class MercurialVCS(VersionControlSystem): - """Implementation of the VersionControlSystem interface for Mercurial.""" - - def __init__(self, options, repo_dir): - super(MercurialVCS, self).__init__(options) - # Absolute path to repository (we can be in a subdir) - self.repo_dir = os.path.normpath(repo_dir) - # Compute the subdir - cwd = os.path.normpath(os.getcwd()) - assert cwd.startswith(self.repo_dir) - self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") - if self.options.revision: - self.base_rev = self.options.revision - else: - self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() - - def _GetRelPath(self, filename): - """Get relative path of a file according to the current directory, - given its logical path in the repo.""" - assert filename.startswith(self.subdir), (filename, self.subdir) - return filename[len(self.subdir):].lstrip(r"\/") - - def GenerateDiff(self, extra_args): - cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args - data = RunShell(cmd, silent_ok=True) - svndiff = [] - filecount = 0 - for line in data.splitlines(): - m = re.match("diff --git a/(\S+) b/(\S+)", line) - if m: - # Modify line to make it look like as it comes from svn diff. - # With this modification no changes on the server side are required - # to make upload.py work with Mercurial repos. - # NOTE: for proper handling of moved/copied files, we have to use - # the second filename. - filename = m.group(2) - svndiff.append("Index: %s" % filename) - svndiff.append("=" * 67) - filecount += 1 - logging.info(line) - else: - svndiff.append(line) - if not filecount: - ErrorExit("No valid patches found in output from hg diff") - return "\n".join(svndiff) + "\n" - - def GetUnknownFiles(self): - """Return a list of files unknown to the VCS.""" - args = [] - status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], - silent_ok=True) - unknown_files = [] - for line in status.splitlines(): - st, fn = line.split(" ", 1) - if st == "?": - unknown_files.append(fn) - return unknown_files - - def GetBaseFile(self, filename): - # "hg status" and "hg cat" both take a path relative to the current subdir - # rather than to the repo root, but "hg diff" has given us the full path - # to the repo root. - base_content = "" - new_content = None - is_binary = False - oldrelpath = relpath = self._GetRelPath(filename) - # "hg status -C" returns two lines for moved/copied files, one otherwise - out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) - out = out.splitlines() - # HACK: strip error message about missing file/directory if it isn't in - # the working copy - if out[0].startswith('%s: ' % relpath): - out = out[1:] - status, _ = out[0].split(' ', 1) - if len(out) > 1 and status == "A": - # Moved/copied => considered as modified, use old filename to - # retrieve base contents - oldrelpath = out[1].strip() - status = "M" - if ":" in self.base_rev: - base_rev = self.base_rev.split(":", 1)[0] - else: - base_rev = self.base_rev - if status != "A": - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True) - is_binary = "\0" in base_content # Mercurial's heuristic - if status != "R": - new_content = open(relpath, "rb").read() - is_binary = is_binary or "\0" in new_content - if is_binary and base_content: - # Fetch again without converting newlines - base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], - silent_ok=True, universal_newlines=False) - if not is_binary or not self.IsImage(relpath): - new_content = None - return base_content, new_content, is_binary, status - - -# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. -def SplitPatch(data): - """Splits a patch into separate pieces for each file. - - Args: - data: A string containing the output of svn diff. - - Returns: - A list of 2-tuple (filename, text) where text is the svn diff output - pertaining to filename. - """ - patches = [] - filename = None - diff = [] - for line in data.splitlines(True): - new_filename = None - if line.startswith('Index:'): - unused, new_filename = line.split(':', 1) - new_filename = new_filename.strip() - elif line.startswith('Property changes on:'): - unused, temp_filename = line.split(':', 1) - # When a file is modified, paths use '/' between directories, however - # when a property is modified '\' is used on Windows. Make them the same - # otherwise the file shows up twice. - temp_filename = temp_filename.strip().replace('\\', '/') - if temp_filename != filename: - # File has property changes but no modifications, create a new diff. - new_filename = temp_filename - if new_filename: - if filename and diff: - patches.append((filename, ''.join(diff))) - filename = new_filename - diff = [line] - continue - if diff is not None: - diff.append(line) - if filename and diff: - patches.append((filename, ''.join(diff))) - return patches - - -def UploadSeparatePatches(issue, rpc_server, patchset, data, options): - """Uploads a separate patch for each file in the diff output. - - Returns a list of [patch_key, filename] for each file. - """ - patches = SplitPatch(data) - rv = [] - for patch in patches: - if len(patch[1]) > MAX_UPLOAD_SIZE: - print ("Not uploading the patch for " + patch[0] + - " because the file is too large.") - continue - form_fields = [("filename", patch[0])] - if not options.download_base: - form_fields.append(("content_upload", "1")) - files = [("data", "data.diff", patch[1])] - ctype, body = EncodeMultipartFormData(form_fields, files) - url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) - print "Uploading patch for " + patch[0] - response_body = rpc_server.Send(url, body, content_type=ctype) - lines = response_body.splitlines() - if not lines or lines[0] != "OK": - StatusUpdate(" --> %s" % response_body) - sys.exit(1) - rv.append([lines[1], patch[0]]) - return rv - - -def GuessVCSName(): - """Helper to guess the version control system. - - This examines the current directory, guesses which VersionControlSystem - we're using, and returns an string indicating which VCS is detected. - - Returns: - A pair (vcs, output). vcs is a string indicating which VCS was detected - and is one of VCS_GIT, VCS_MERCURIAL, VCS_SUBVERSION, or VCS_UNKNOWN. - output is a string containing any interesting output from the vcs - detection routine, or None if there is nothing interesting. - """ - def RunDetectCommand(vcs_type, command): - """Helper to detect VCS by executing command. - - Returns: - A pair (vcs, output) or None. Throws exception on error. - """ - try: - out, returncode = RunShellWithReturnCode(command) - if returncode == 0: - return (vcs_type, out.strip()) - except OSError, (errcode, message): - if errcode != errno.ENOENT: # command not found code - raise - - # Mercurial has a command to get the base directory of a repository - # Try running it, but don't die if we don't have hg installed. - # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. - res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) - if res != None: - return res - - # Subversion has a .svn in all working directories. - if os.path.isdir('.svn'): - logging.info("Guessed VCS = Subversion") - return (VCS_SUBVERSION, None) - - # Git has a command to test if you're in a git tree. - # Try running it, but don't die if we don't have git installed. - res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", - "--is-inside-work-tree"]) - if res != None: - return res - - return (VCS_UNKNOWN, None) - - -def GuessVCS(options): - """Helper to guess the version control system. - - This verifies any user-specified VersionControlSystem (by command line - or environment variable). If the user didn't specify one, this examines - the current directory, guesses which VersionControlSystem we're using, - and returns an instance of the appropriate class. Exit with an error - if we can't figure it out. - - Returns: - A VersionControlSystem instance. Exits if the VCS can't be guessed. - """ - vcs = options.vcs - if not vcs: - vcs = os.environ.get("CODEREVIEW_VCS") - if vcs: - v = VCS_ABBREVIATIONS.get(vcs.lower()) - if v is None: - ErrorExit("Unknown version control system %r specified." % vcs) - (vcs, extra_output) = (v, None) - else: - (vcs, extra_output) = GuessVCSName() - - if vcs == VCS_MERCURIAL: - if extra_output is None: - extra_output = RunShell(["hg", "root"]).strip() - return MercurialVCS(options, extra_output) - elif vcs == VCS_SUBVERSION: - return SubversionVCS(options) - elif vcs == VCS_GIT: - return GitVCS(options) - - ErrorExit(("Could not guess version control system. " - "Are you in a working copy directory?")) - - -def CheckReviewer(reviewer): - """Validate a reviewer -- either a nickname or an email addres. - - Args: - reviewer: A nickname or an email address. - - Calls ErrorExit() if it is an invalid email address. - """ - if "@" not in reviewer: - return # Assume nickname - parts = reviewer.split("@") - if len(parts) > 2: - ErrorExit("Invalid email address: %r" % reviewer) - assert len(parts) == 2 - if "." not in parts[1]: - ErrorExit("Invalid email address: %r" % reviewer) - - -def LoadSubversionAutoProperties(): - """Returns the content of [auto-props] section of Subversion's config file as - a dictionary. - - Returns: - A dictionary whose key-value pair corresponds the [auto-props] section's - key-value pair. - In following cases, returns empty dictionary: - - config file doesn't exist, or - - 'enable-auto-props' is not set to 'true-like-value' in [miscellany]. - """ - if os.name == 'nt': - subversion_config = os.environ.get("APPDATA") + "\\Subversion\\config" - else: - subversion_config = os.path.expanduser("~/.subversion/config") - if not os.path.exists(subversion_config): - return {} - config = ConfigParser.ConfigParser() - config.read(subversion_config) - if (config.has_section("miscellany") and - config.has_option("miscellany", "enable-auto-props") and - config.getboolean("miscellany", "enable-auto-props") and - config.has_section("auto-props")): - props = {} - for file_pattern in config.options("auto-props"): - props[file_pattern] = ParseSubversionPropertyValues( - config.get("auto-props", file_pattern)) - return props - else: - return {} - -def ParseSubversionPropertyValues(props): - """Parse the given property value which comes from [auto-props] section and - returns a list whose element is a (svn_prop_key, svn_prop_value) pair. - - See the following doctest for example. - - >>> ParseSubversionPropertyValues('svn:eol-style=LF') - [('svn:eol-style', 'LF')] - >>> ParseSubversionPropertyValues('svn:mime-type=image/jpeg') - [('svn:mime-type', 'image/jpeg')] - >>> ParseSubversionPropertyValues('svn:eol-style=LF;svn:executable') - [('svn:eol-style', 'LF'), ('svn:executable', '*')] - """ - key_value_pairs = [] - for prop in props.split(";"): - key_value = prop.split("=") - assert len(key_value) <= 2 - if len(key_value) == 1: - # If value is not given, use '*' as a Subversion's convention. - key_value_pairs.append((key_value[0], "*")) - else: - key_value_pairs.append((key_value[0], key_value[1])) - return key_value_pairs - - -def GetSubversionPropertyChanges(filename): - """Return a Subversion's 'Property changes on ...' string, which is used in - the patch file. - - Args: - filename: filename whose property might be set by [auto-props] config. - - Returns: - A string like 'Property changes on |filename| ...' if given |filename| - matches any entries in [auto-props] section. None, otherwise. - """ - global svn_auto_props_map - if svn_auto_props_map is None: - svn_auto_props_map = LoadSubversionAutoProperties() - - all_props = [] - for file_pattern, props in svn_auto_props_map.items(): - if fnmatch.fnmatch(filename, file_pattern): - all_props.extend(props) - if all_props: - return FormatSubversionPropertyChanges(filename, all_props) - return None - - -def FormatSubversionPropertyChanges(filename, props): - """Returns Subversion's 'Property changes on ...' strings using given filename - and properties. - - Args: - filename: filename - props: A list whose element is a (svn_prop_key, svn_prop_value) pair. - - Returns: - A string which can be used in the patch file for Subversion. - - See the following doctest for example. - - >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) - Property changes on: foo.cc - ___________________________________________________________________ - Added: svn:eol-style - + LF - - """ - prop_changes_lines = [ - "Property changes on: %s" % filename, - "___________________________________________________________________"] - for key, value in props: - prop_changes_lines.append("Added: " + key) - prop_changes_lines.append(" + " + value) - return "\n".join(prop_changes_lines) + "\n" - - -def RealMain(argv, data=None): - """The real main function. - - Args: - argv: Command line arguments. - data: Diff contents. If None (default) the diff is generated by - the VersionControlSystem implementation returned by GuessVCS(). - - Returns: - A 2-tuple (issue id, patchset id). - The patchset id is None if the base files are not uploaded by this - script (applies only to SVN checkouts). - """ - options, args = parser.parse_args(argv[1:]) - global verbosity - verbosity = options.verbose - if verbosity >= 3: - logging.getLogger().setLevel(logging.DEBUG) - elif verbosity >= 2: - logging.getLogger().setLevel(logging.INFO) - - vcs = GuessVCS(options) - - base = options.base_url - if isinstance(vcs, SubversionVCS): - # Guessing the base field is only supported for Subversion. - # Note: Fetching base files may become deprecated in future releases. - guessed_base = vcs.GuessBase(options.download_base) - if base: - if guessed_base and base != guessed_base: - print "Using base URL \"%s\" from --base_url instead of \"%s\"" % \ - (base, guessed_base) - else: - base = guessed_base - - if not base and options.download_base: - options.download_base = True - logging.info("Enabled upload of base file") - if not options.assume_yes: - vcs.CheckForUnknownFiles() - if data is None: - data = vcs.GenerateDiff(args) - data = vcs.PostProcessDiff(data) - files = vcs.GetBaseFiles(data) - if verbosity >= 1: - print "Upload server:", options.server, "(change with -s/--server)" - if options.issue: - prompt = "Message describing this patch set: " - else: - prompt = "New issue subject: " - message = options.message or raw_input(prompt).strip() - if not message: - ErrorExit("A non-empty message is required") - rpc_server = GetRpcServer(options.server, - options.email, - options.host, - options.save_cookies, - options.account_type) - form_fields = [("subject", message)] - if base: - b = urlparse.urlparse(base) - username, netloc = urllib.splituser(b.netloc) - if username: - logging.info("Removed username from base URL") - base = urlparse.urlunparse((b.scheme, netloc, b.path, b.params, - b.query, b.fragment)) - form_fields.append(("base", base)) - if options.issue: - form_fields.append(("issue", str(options.issue))) - if options.email: - form_fields.append(("user", options.email)) - if options.reviewers: - for reviewer in options.reviewers.split(','): - CheckReviewer(reviewer) - form_fields.append(("reviewers", options.reviewers)) - if options.cc: - for cc in options.cc.split(','): - CheckReviewer(cc) - form_fields.append(("cc", options.cc)) - description = options.description - if options.description_file: - if options.description: - ErrorExit("Can't specify description and description_file") - file = open(options.description_file, 'r') - description = file.read() - file.close() - if description: - form_fields.append(("description", description)) - # Send a hash of all the base file so the server can determine if a copy - # already exists in an earlier patchset. - base_hashes = "" - for file, info in files.iteritems(): - if not info[0] is None: - checksum = md5(info[0]).hexdigest() - if base_hashes: - base_hashes += "|" - base_hashes += checksum + ":" + file - form_fields.append(("base_hashes", base_hashes)) - if options.private: - if options.issue: - print "Warning: Private flag ignored when updating an existing issue." - else: - form_fields.append(("private", "1")) - # If we're uploading base files, don't send the email before the uploads, so - # that it contains the file status. - if options.send_mail and options.download_base: - form_fields.append(("send_mail", "1")) - if not options.download_base: - form_fields.append(("content_upload", "1")) - if len(data) > MAX_UPLOAD_SIZE: - print "Patch is large, so uploading file patches separately." - uploaded_diff_file = [] - form_fields.append(("separate_patches", "1")) - else: - uploaded_diff_file = [("data", "data.diff", data)] - ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) - response_body = rpc_server.Send("/upload", body, content_type=ctype) - patchset = None - if not options.download_base or not uploaded_diff_file: - lines = response_body.splitlines() - if len(lines) >= 2: - msg = lines[0] - patchset = lines[1].strip() - patches = [x.split(" ", 1) for x in lines[2:]] - else: - msg = response_body - else: - msg = response_body - StatusUpdate(msg) - if not response_body.startswith("Issue created.") and \ - not response_body.startswith("Issue updated."): - sys.exit(0) - issue = msg[msg.rfind("/")+1:] - - if not uploaded_diff_file: - result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) - if not options.download_base: - patches = result - - if not options.download_base: - vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) - if options.send_mail: - rpc_server.Send("/" + issue + "/mail", payload="") - return issue, patchset - - -def main(): - try: - logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" - "%(lineno)s %(message)s ")) - os.environ['LC_ALL'] = 'C' - RealMain(sys.argv) - except KeyboardInterrupt: - print - StatusUpdate("Interrupted.") - sys.exit(1) - - -if __name__ == "__main__": - main() - +#!/usr/bin/env python +# +# Copyright 2007 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Tool for uploading diffs from a version control system to the codereview app. + +Usage summary: upload.py [options] [-- diff_options] [path...] + +Diff options are passed to the diff command of the underlying system. + +Supported version control systems: + Git + Mercurial + Subversion + +It is important for Git/Mercurial users to specify a tree/node/branch to diff +against by using the '--rev' option. +""" +# This code is derived from appcfg.py in the App Engine SDK (open source), +# and from ASPN recipe #146306. + +import configparser +import http.cookiejar +import fnmatch +import getpass +import logging +import mimetypes +import optparse +import os +import re +import socket +import subprocess +import sys +import urllib.request, urllib.parse, urllib.error +import urllib.request, urllib.error, urllib.parse +import urllib.parse + +# The md5 module was deprecated in Python 2.5. +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +try: + import readline +except ImportError: + pass + +try: + import keyring +except ImportError: + keyring = None + +# The logging verbosity: +# 0: Errors only. +# 1: Status messages. +# 2: Info logs. +# 3: Debug logs. +verbosity = 1 + +# The account type used for authentication. +# This line could be changed by the review server (see handler for +# upload.py). +AUTH_ACCOUNT_TYPE = "GOOGLE" + +# URL of the default review server. As for AUTH_ACCOUNT_TYPE, this line could be +# changed by the review server (see handler for upload.py). +DEFAULT_REVIEW_SERVER = "codereview.appspot.com" + +# Max size of patch or base file. +MAX_UPLOAD_SIZE = 900 * 1024 + +# Constants for version control names. Used by GuessVCSName. +VCS_GIT = "Git" +VCS_MERCURIAL = "Mercurial" +VCS_SUBVERSION = "Subversion" +VCS_UNKNOWN = "Unknown" + +# whitelist for non-binary filetypes which do not start with "text/" +# .mm (Objective-C) shows up as application/x-freemind on my Linux box. +TEXT_MIMETYPES = ['application/javascript', 'application/x-javascript', + 'application/xml', 'application/x-freemind', + 'application/x-sh'] + +VCS_ABBREVIATIONS = { + VCS_MERCURIAL.lower(): VCS_MERCURIAL, + "hg": VCS_MERCURIAL, + VCS_SUBVERSION.lower(): VCS_SUBVERSION, + "svn": VCS_SUBVERSION, + VCS_GIT.lower(): VCS_GIT, +} + +# The result of parsing Subversion's [auto-props] setting. +svn_auto_props_map = None + +def GetEmail(prompt): + """Prompts the user for their email address and returns it. + + The last used email address is saved to a file and offered up as a suggestion + to the user. If the user presses enter without typing in anything the last + used email address is used. If the user enters a new address, it is saved + for next time we prompt. + + """ + last_email_file_name = os.path.expanduser("~/.last_codereview_email_address") + last_email = "" + if os.path.exists(last_email_file_name): + try: + last_email_file = open(last_email_file_name, "r") + last_email = last_email_file.readline().strip("\n") + last_email_file.close() + prompt += " [%s]" % last_email + except IOError as e: + pass + email = input(prompt + ": ").strip() + if email: + try: + last_email_file = open(last_email_file_name, "w") + last_email_file.write(email) + last_email_file.close() + except IOError as e: + pass + else: + email = last_email + return email + + +def StatusUpdate(msg): + """Print a status message to stdout. + + If 'verbosity' is greater than 0, print the message. + + Args: + msg: The string to print. + """ + if verbosity > 0: + print(msg) + + +def ErrorExit(msg): + """Print an error message to stderr and exit.""" + print(msg, file=sys.stderr) + sys.exit(1) + + +class ClientLoginError(urllib.error.HTTPError): + """Raised to indicate there was an error authenticating with ClientLogin.""" + + def __init__(self, url, code, msg, headers, args): + urllib.error.HTTPError.__init__(self, url, code, msg, headers, None) + self.args = args + self.reason = args["Error"] + self.info = args.get("Info", None) + + +class AbstractRpcServer(object): + """Provides a common interface for a simple RPC server.""" + + def __init__(self, host, auth_function, host_override=None, extra_headers={}, + save_cookies=False, account_type=AUTH_ACCOUNT_TYPE): + """Creates a new HttpRpcServer. + + Args: + host: The host to send requests to. + auth_function: A function that takes no arguments and returns an + (email, password) tuple when called. Will be called if authentication + is required. + host_override: The host header to send to the server (defaults to host). + extra_headers: A dict of extra headers to append to every request. + save_cookies: If True, save the authentication cookies to local disk. + If False, use an in-memory cookiejar instead. Subclasses must + implement this functionality. Defaults to False. + account_type: Account type used for authentication. Defaults to + AUTH_ACCOUNT_TYPE. + """ + self.host = host + if (not self.host.startswith("http://") and + not self.host.startswith("https://")): + self.host = "http://" + self.host + self.host_override = host_override + self.auth_function = auth_function + self.authenticated = False + self.extra_headers = extra_headers + self.save_cookies = save_cookies + self.account_type = account_type + self.opener = self._GetOpener() + if self.host_override: + logging.info("Server: %s; Host: %s", self.host, self.host_override) + else: + logging.info("Server: %s", self.host) + + def _GetOpener(self): + """Returns an OpenerDirector for making HTTP requests. + + Returns: + A urllib2.OpenerDirector object. + """ + raise NotImplementedError() + + def _CreateRequest(self, url, data=None): + """Creates a new urllib request.""" + logging.debug("Creating request for: '%s' with payload:\n%s", url, data) + req = urllib.request.Request(url, data=data) + if self.host_override: + req.add_header("Host", self.host_override) + for key, value in self.extra_headers.items(): + req.add_header(key, value) + return req + + def _GetAuthToken(self, email, password): + """Uses ClientLogin to authenticate the user, returning an auth token. + + Args: + email: The user's email address + password: The user's password + + Raises: + ClientLoginError: If there was an error authenticating with ClientLogin. + HTTPError: If there was some other form of HTTP error. + + Returns: + The authentication token returned by ClientLogin. + """ + account_type = self.account_type + if self.host.endswith(".google.com"): + # Needed for use inside Google. + account_type = "HOSTED" + req = self._CreateRequest( + url="https://www.google.com/accounts/ClientLogin", + data=urllib.parse.urlencode({ + "Email": email, + "Passwd": password, + "service": "ah", + "source": "rietveld-codereview-upload", + "accountType": account_type, + }), + ) + try: + response = self.opener.open(req) + response_body = response.read() + response_dict = dict(x.split("=") + for x in response_body.split("\n") if x) + return response_dict["Auth"] + except urllib.error.HTTPError as e: + if e.code == 403: + body = e.read() + response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) + raise ClientLoginError(req.get_full_url(), e.code, e.msg, + e.headers, response_dict) + else: + raise + + def _GetAuthCookie(self, auth_token): + """Fetches authentication cookies for an authentication token. + + Args: + auth_token: The authentication token returned by ClientLogin. + + Raises: + HTTPError: If there was an error fetching the authentication cookies. + """ + # This is a dummy value to allow us to identify when we're successful. + continue_location = "http://localhost/" + args = {"continue": continue_location, "auth": auth_token} + req = self._CreateRequest("%s/_ah/login?%s" % + (self.host, urllib.parse.urlencode(args))) + try: + response = self.opener.open(req) + except urllib.error.HTTPError as e: + response = e + if (response.code != 302 or + response.info()["location"] != continue_location): + raise urllib.error.HTTPError(req.get_full_url(), response.code, response.msg, + response.headers, response.fp) + self.authenticated = True + + def _Authenticate(self): + """Authenticates the user. + + The authentication process works as follows: + 1) We get a username and password from the user + 2) We use ClientLogin to obtain an AUTH token for the user + (see http://code.google.com/apis/accounts/AuthForInstalledApps.html). + 3) We pass the auth token to /_ah/login on the server to obtain an + authentication cookie. If login was successful, it tries to redirect + us to the URL we provided. + + If we attempt to access the upload API without first obtaining an + authentication cookie, it returns a 401 response (or a 302) and + directs us to authenticate ourselves with ClientLogin. + """ + for i in range(3): + credentials = self.auth_function() + try: + auth_token = self._GetAuthToken(credentials[0], credentials[1]) + except ClientLoginError as e: + print('', file=sys.stderr) + if e.reason == "BadAuthentication": + if e.info == "InvalidSecondFactor": + print(( + "Use an application-specific password instead " + "of your regular account password.\n" + "See http://www.google.com/" + "support/accounts/bin/answer.py?answer=185833"), file=sys.stderr) + else: + print("Invalid username or password.", file=sys.stderr) + elif e.reason == "CaptchaRequired": + print(( + "Please go to\n" + "https://www.google.com/accounts/DisplayUnlockCaptcha\n" + "and verify you are a human. Then try again.\n" + "If you are using a Google Apps account the URL is:\n" + "https://www.google.com/a/yourdomain.com/UnlockCaptcha"), file=sys.stderr) + elif e.reason == "NotVerified": + print("Account not verified.", file=sys.stderr) + elif e.reason == "TermsNotAgreed": + print("User has not agreed to TOS.", file=sys.stderr) + elif e.reason == "AccountDeleted": + print("The user account has been deleted.", file=sys.stderr) + elif e.reason == "AccountDisabled": + print("The user account has been disabled.", file=sys.stderr) + break + elif e.reason == "ServiceDisabled": + print(("The user's access to the service has been " + "disabled."), file=sys.stderr) + elif e.reason == "ServiceUnavailable": + print("The service is not available; try again later.", file=sys.stderr) + else: + # Unknown error. + raise + print('', file=sys.stderr) + continue + self._GetAuthCookie(auth_token) + return + + def Send(self, request_path, payload=None, + content_type="application/octet-stream", + timeout=None, + extra_headers=None, + **kwargs): + """Sends an RPC and returns the response. + + Args: + request_path: The path to send the request to, eg /api/appversion/create. + payload: The body of the request, or None to send an empty request. + content_type: The Content-Type header to use. + timeout: timeout in seconds; default None i.e. no timeout. + (Note: for large requests on OS X, the timeout doesn't work right.) + extra_headers: Dict containing additional HTTP headers that should be + included in the request (string header names mapped to their values), + or None to not include any additional headers. + kwargs: Any keyword arguments are converted into query string parameters. + + Returns: + The response body, as a string. + """ + # TODO: Don't require authentication. Let the server say + # whether it is necessary. + if not self.authenticated: + self._Authenticate() + + old_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(timeout) + try: + tries = 0 + while True: + tries += 1 + args = dict(kwargs) + url = "%s%s" % (self.host, request_path) + if args: + url += "?" + urllib.parse.urlencode(args) + req = self._CreateRequest(url=url, data=payload) + req.add_header("Content-Type", content_type) + if extra_headers: + for header, value in list(extra_headers.items()): + req.add_header(header, value) + try: + f = self.opener.open(req) + response = f.read() + f.close() + return response + except urllib.error.HTTPError as e: + if tries > 3: + raise + elif e.code == 401 or e.code == 302: + self._Authenticate() +## elif e.code >= 500 and e.code < 600: +## # Server Error - try again. +## continue + elif e.code == 301: + # Handle permanent redirect manually. + url = e.info()["location"] + url_loc = urllib.parse.urlparse(url) + self.host = '%s://%s' % (url_loc[0], url_loc[1]) + else: + raise + finally: + socket.setdefaulttimeout(old_timeout) + + +class HttpRpcServer(AbstractRpcServer): + """Provides a simplified RPC-style interface for HTTP requests.""" + + def _Authenticate(self): + """Save the cookie jar after authentication.""" + super(HttpRpcServer, self)._Authenticate() + if self.save_cookies: + StatusUpdate("Saving authentication cookies to %s" % self.cookie_file) + self.cookie_jar.save() + + def _GetOpener(self): + """Returns an OpenerDirector that supports cookies and ignores redirects. + + Returns: + A urllib2.OpenerDirector object. + """ + opener = urllib.request.OpenerDirector() + opener.add_handler(urllib.request.ProxyHandler()) + opener.add_handler(urllib.request.UnknownHandler()) + opener.add_handler(urllib.request.HTTPHandler()) + opener.add_handler(urllib.request.HTTPDefaultErrorHandler()) + opener.add_handler(urllib.request.HTTPSHandler()) + opener.add_handler(urllib2.HTTPErrorProcessor()) + if self.save_cookies: + self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") + self.cookie_jar = http.cookiejar.MozillaCookieJar(self.cookie_file) + if os.path.exists(self.cookie_file): + try: + self.cookie_jar.load() + self.authenticated = True + StatusUpdate("Loaded authentication cookies from %s" % + self.cookie_file) + except (http.cookiejar.LoadError, IOError): + # Failed to load cookies - just ignore them. + pass + else: + # Create an empty cookie file with mode 600 + fd = os.open(self.cookie_file, os.O_CREAT, 0o600) + os.close(fd) + # Always chmod the cookie file + os.chmod(self.cookie_file, 0o600) + else: + # Don't save cookies across runs of update.py. + self.cookie_jar = http.cookiejar.CookieJar() + opener.add_handler(urllib.request.HTTPCookieProcessor(self.cookie_jar)) + return opener + + +parser = optparse.OptionParser( + usage="%prog [options] [-- diff_options] [path...]") +parser.add_option("-y", "--assume_yes", action="store_true", + dest="assume_yes", default=False, + help="Assume that the answer to yes/no questions is 'yes'.") +# Logging +group = parser.add_option_group("Logging options") +group.add_option("-q", "--quiet", action="store_const", const=0, + dest="verbose", help="Print errors only.") +group.add_option("-v", "--verbose", action="store_const", const=2, + dest="verbose", default=1, + help="Print info level logs.") +group.add_option("--noisy", action="store_const", const=3, + dest="verbose", help="Print all logs.") +# Review server +group = parser.add_option_group("Review server options") +group.add_option("-s", "--server", action="store", dest="server", + default=DEFAULT_REVIEW_SERVER, + metavar="SERVER", + help=("The server to upload to. The format is host[:port]. " + "Defaults to '%default'.")) +group.add_option("-e", "--email", action="store", dest="email", + metavar="EMAIL", default=None, + help="The username to use. Will prompt if omitted.") +group.add_option("-H", "--host", action="store", dest="host", + metavar="HOST", default=None, + help="Overrides the Host header sent with all RPCs.") +group.add_option("--no_cookies", action="store_false", + dest="save_cookies", default=True, + help="Do not save authentication cookies to local disk.") +group.add_option("--account_type", action="store", dest="account_type", + metavar="TYPE", default=AUTH_ACCOUNT_TYPE, + choices=["GOOGLE", "HOSTED"], + help=("Override the default account type " + "(defaults to '%default', " + "valid choices are 'GOOGLE' and 'HOSTED').")) +# Issue +group = parser.add_option_group("Issue options") +group.add_option("-d", "--description", action="store", dest="description", + metavar="DESCRIPTION", default=None, + help="Optional description when creating an issue.") +group.add_option("-f", "--description_file", action="store", + dest="description_file", metavar="DESCRIPTION_FILE", + default=None, + help="Optional path of a file that contains " + "the description when creating an issue.") +group.add_option("-r", "--reviewers", action="store", dest="reviewers", + metavar="REVIEWERS", default=None, + help="Add reviewers (comma separated email addresses).") +group.add_option("--cc", action="store", dest="cc", + metavar="CC", default="dev@scons.tigris.org", + help="Add CC (comma separated email addresses).") +group.add_option("--private", action="store_true", dest="private", + default=False, + help="Make the issue restricted to reviewers and those CCed") +# Upload options +group = parser.add_option_group("Patch options") +group.add_option("-m", "--message", action="store", dest="message", + metavar="MESSAGE", default=None, + help="A message to identify the patch. " + "Will prompt if omitted.") +group.add_option("-i", "--issue", type="int", action="store", + metavar="ISSUE", default=None, + help="Issue number to which to add. Defaults to new issue.") +group.add_option("--base_url", action="store", dest="base_url", default=None, + help="Base repository URL (listed as \"Base URL\" when " + "viewing issue). If omitted, will be guessed automatically " + "for SVN repos and left blank for others.") +group.add_option("--download_base", action="store_true", + dest="download_base", default=False, + help="Base files will be downloaded by the server " + "(side-by-side diffs may not work on files with CRs).") +group.add_option("--rev", action="store", dest="revision", + metavar="REV", default=None, + help="Base revision/branch/tree to diff against. Use " + "rev1:rev2 range to review already committed changeset.") +group.add_option("--send_mail", action="store_true", + dest="send_mail", default=True, + help="Send notification email to reviewers.") +group.add_option("--vcs", action="store", dest="vcs", + metavar="VCS", default="svn", + help=("Version control system (optional, usually upload.py " + "already guesses the right VCS).")) +group.add_option("--emulate_svn_auto_props", action="store_true", + dest="emulate_svn_auto_props", default=False, + help=("Emulate Subversion's auto properties feature.")) + + +def GetRpcServer(server, email=None, host_override=None, save_cookies=True, + account_type=AUTH_ACCOUNT_TYPE): + """Returns an instance of an AbstractRpcServer. + + Args: + server: String containing the review server URL. + email: String containing user's email address. + host_override: If not None, string containing an alternate hostname to use + in the host header. + save_cookies: Whether authentication cookies should be saved to disk. + account_type: Account type for authentication, either 'GOOGLE' + or 'HOSTED'. Defaults to AUTH_ACCOUNT_TYPE. + + Returns: + A new AbstractRpcServer, on which RPC calls can be made. + """ + + rpc_server_class = HttpRpcServer + + # If this is the dev_appserver, use fake authentication. + host = (host_override or server).lower() + if re.match(r'(http://)?localhost([:/]|$)', host): + if email is None: + email = "test@example.com" + logging.info("Using debug user %s. Override with --email" % email) + server = rpc_server_class( + server, + lambda: (email, "password"), + host_override=host_override, + extra_headers={"Cookie": + 'dev_appserver_login="%s:False"' % email}, + save_cookies=save_cookies, + account_type=account_type) + # Don't try to talk to ClientLogin. + server.authenticated = True + return server + + def GetUserCredentials(): + """Prompts the user for a username and password.""" + # Create a local alias to the email variable to avoid Python's crazy + # scoping rules. + local_email = email + if local_email is None: + local_email = GetEmail("Email (login for uploading to %s)" % server) + password = None + if keyring: + password = keyring.get_password(host, local_email) + if password is not None: + print("Using password from system keyring.") + else: + password = getpass.getpass("Password for %s: " % local_email) + if keyring: + answer = input("Store password in system keyring?(y/N) ").strip() + if answer == "y": + keyring.set_password(host, local_email, password) + return (local_email, password) + + return rpc_server_class(server, + GetUserCredentials, + host_override=host_override, + save_cookies=save_cookies) + + +def EncodeMultipartFormData(fields, files): + """Encode form fields for multipart/form-data. + + Args: + fields: A sequence of (name, value) elements for regular form fields. + files: A sequence of (name, filename, value) elements for data to be + uploaded as files. + Returns: + (content_type, body) ready for httplib.HTTP instance. + + Source: + http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 + """ + BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' + CRLF = '\r\n' + lines = [] + for (key, value) in fields: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"' % key) + lines.append('') + if isinstance(value, str): + value = value.encode('utf-8') + lines.append(value) + for (key, filename, value) in files: + lines.append('--' + BOUNDARY) + lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)) + lines.append('Content-Type: %s' % GetContentType(filename)) + lines.append('') + if isinstance(value, str): + value = value.encode('utf-8') + lines.append(value) + lines.append('--' + BOUNDARY + '--') + lines.append('') + body = CRLF.join(lines) + content_type = 'multipart/form-data; boundary=%s' % BOUNDARY + return content_type, body + + +def GetContentType(filename): + """Helper to guess the content-type from the filename.""" + return mimetypes.guess_type(filename)[0] or 'application/octet-stream' + + +# Use a shell for subcommands on Windows to get a PATH search. +use_shell = sys.platform.startswith("win") + +def RunShellWithReturnCodeAndStderr(command, print_output=False, + universal_newlines=True, + env=os.environ): + """Executes a command and returns the output from stdout, stderr and the return code. + + Args: + command: Command to execute. + print_output: If True, the output is printed to stdout. + If False, both stdout and stderr are ignored. + universal_newlines: Use universal_newlines flag (default: True). + + Returns: + Tuple (stdout, stderr, return code) + """ + logging.info("Running %s", command) + env = env.copy() + env['LC_MESSAGES'] = 'C' + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=use_shell, universal_newlines=universal_newlines, + env=env) + if print_output: + output_array = [] + while True: + line = p.stdout.readline() + if not line: + break + print(line.strip("\n")) + output_array.append(line) + output = "".join(output_array) + else: + output = p.stdout.read() + p.wait() + errout = p.stderr.read() + if print_output and errout: + print(errout, file=sys.stderr) + p.stdout.close() + p.stderr.close() + return output, errout, p.returncode + +def RunShellWithReturnCode(command, print_output=False, + universal_newlines=True, + env=os.environ): + """Executes a command and returns the output from stdout and the return code.""" + out, err, retcode = RunShellWithReturnCodeAndStderr(command, print_output, + universal_newlines, env) + return out, retcode + +def RunShell(command, silent_ok=False, universal_newlines=True, + print_output=False, env=os.environ): + data, retcode = RunShellWithReturnCode(command, print_output, + universal_newlines, env) + if retcode: + ErrorExit("Got error status from %s:\n%s" % (command, data)) + if not silent_ok and not data: + ErrorExit("No output from %s" % command) + return data + + +class VersionControlSystem(object): + """Abstract base class providing an interface to the VCS.""" + + def __init__(self, options): + """Constructor. + + Args: + options: Command line options. + """ + self.options = options + + def PostProcessDiff(self, diff): + """Return the diff with any special post processing this VCS needs, e.g. + to include an svn-style "Index:".""" + return diff + + def GenerateDiff(self, args): + """Return the current diff as a string. + + Args: + args: Extra arguments to pass to the diff command. + """ + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + def CheckForUnknownFiles(self): + """Show an "are you sure?" prompt if there are unknown files.""" + unknown_files = self.GetUnknownFiles() + if unknown_files: + print("The following files are not added to version control:") + for line in unknown_files: + print(line) + prompt = "Are you sure to continue?(y/N) " + answer = input(prompt).strip() + if answer != "y": + ErrorExit("User aborted") + + def GetBaseFile(self, filename): + """Get the content of the upstream version of a file. + + Returns: + A tuple (base_content, new_content, is_binary, status) + base_content: The contents of the base file. + new_content: For text files, this is empty. For binary files, this is + the contents of the new file, since the diff output won't contain + information to reconstruct the current file. + is_binary: True iff the file is binary. + status: The status of the file. + """ + + raise NotImplementedError( + "abstract method -- subclass %s must override" % self.__class__) + + + def GetBaseFiles(self, diff): + """Helper that calls GetBase file for each file in the patch. + + Returns: + A dictionary that maps from filename to GetBaseFile's tuple. Filenames + are retrieved based on lines that start with "Index:" or + "Property changes on:". + """ + files = {} + for line in diff.splitlines(True): + if line.startswith('Index:') or line.startswith('Property changes on:'): + unused, filename = line.split(':', 1) + # On Windows if a file has property changes its filename uses '\' + # instead of '/'. + filename = filename.strip().replace('\\', '/') + files[filename] = self.GetBaseFile(filename) + return files + + + def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, + files): + """Uploads the base files (and if necessary, the current ones as well).""" + + def UploadFile(filename, file_id, content, is_binary, status, is_base): + """Uploads a file to the server.""" + file_too_large = False + if is_base: + type = "base" + else: + type = "current" + if len(content) > MAX_UPLOAD_SIZE: + print(("Not uploading the %s file for %s because it's too large." % + (type, filename))) + file_too_large = True + content = "" + checksum = md5(content).hexdigest() + if options.verbose > 0 and not file_too_large: + print("Uploading %s file for %s" % (type, filename)) + url = "/%d/upload_content/%d/%d" % (int(issue), int(patchset), file_id) + form_fields = [("filename", filename), + ("status", status), + ("checksum", checksum), + ("is_binary", str(is_binary)), + ("is_current", str(not is_base)), + ] + if file_too_large: + form_fields.append(("file_too_large", "1")) + if options.email: + form_fields.append(("user", options.email)) + ctype, body = EncodeMultipartFormData(form_fields, + [("data", filename, content)]) + response_body = rpc_server.Send(url, body, + content_type=ctype) + if not response_body.startswith("OK"): + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + + patches = dict() + [patches.setdefault(v, k) for k, v in patch_list] + for filename in list(patches.keys()): + base_content, new_content, is_binary, status = files[filename] + file_id_str = patches.get(filename) + if file_id_str.find("nobase") != -1: + base_content = None + file_id_str = file_id_str[file_id_str.rfind("_") + 1:] + file_id = int(file_id_str) + if base_content != None: + UploadFile(filename, file_id, base_content, is_binary, status, True) + if new_content != None: + UploadFile(filename, file_id, new_content, is_binary, status, False) + + def IsImage(self, filename): + """Returns true if the filename has an image extension.""" + mimetype = mimetypes.guess_type(filename)[0] + if not mimetype: + return False + return mimetype.startswith("image/") + + def IsBinary(self, filename): + """Returns true if the guessed mimetyped isnt't in text group.""" + mimetype = mimetypes.guess_type(filename)[0] + if not mimetype: + return False # e.g. README, "real" binaries usually have an extension + # special case for text files which don't start with text/ + if mimetype in TEXT_MIMETYPES: + return False + return not mimetype.startswith("text/") + + +class SubversionVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Subversion.""" + + def __init__(self, options): + super(SubversionVCS, self).__init__(options) + if self.options.revision: + match = re.match(r"(\d+)(:(\d+))?", self.options.revision) + if not match: + ErrorExit("Invalid Subversion revision %s." % self.options.revision) + self.rev_start = match.group(1) + self.rev_end = match.group(3) + else: + self.rev_start = self.rev_end = None + # Cache output from "svn list -r REVNO dirname". + # Keys: dirname, Values: 2-tuple (ouput for start rev and end rev). + self.svnls_cache = {} + # Base URL is required to fetch files deleted in an older revision. + # Result is cached to not guess it over and over again in GetBaseFile(). + required = self.options.download_base or self.options.revision is not None + self.svn_base = self._GuessBase(required) + + def GuessBase(self, required): + """Wrapper for _GuessBase.""" + return self.svn_base + + def _GuessBase(self, required): + """Returns base URL for current diff. + + Args: + required: If true, exits if the url can't be guessed, otherwise None is + returned. + """ + info = RunShell(["svn", "info"]) + for line in info.splitlines(): + if line.startswith("URL: "): + url = line.split()[1] + scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url) + guess = "" + if netloc == "svn.python.org" and scheme == "svn+ssh": + path = "projects" + path + scheme = "http" + guess = "Python " + elif netloc.endswith(".googlecode.com"): + scheme = "http" + guess = "Google Code " + path = path + "/" + base = urllib.parse.urlunparse((scheme, netloc, path, params, + query, fragment)) + logging.info("Guessed %sbase = %s", guess, base) + return base + if required: + ErrorExit("Can't find URL in output from svn info") + return None + + def GenerateDiff(self, args): + cmd = ["svn", "diff"] + if self.options.revision: + cmd += ["-r", self.options.revision] + cmd.extend(args) + data = RunShell(cmd) + count = 0 + for line in data.splitlines(): + if line.startswith("Index:") or line.startswith("Property changes on:"): + count += 1 + logging.info(line) + if not count: + ErrorExit("No valid patches found in output from svn diff") + return data + + def _CollapseKeywords(self, content, keyword_str): + """Collapses SVN keywords.""" + # svn cat translates keywords but svn diff doesn't. As a result of this + # behavior patching.PatchChunks() fails with a chunk mismatch error. + # This part was originally written by the Review Board development team + # who had the same problem (http://reviews.review-board.org/r/276/). + # Mapping of keywords to known aliases + svn_keywords = { + # Standard keywords + 'Date': ['Date', 'LastChangedDate'], + 'Revision': ['Revision', 'LastChangedRevision', 'Rev'], + 'Author': ['Author', 'LastChangedBy'], + 'HeadURL': ['HeadURL', 'URL'], + 'Id': ['Id'], + + # Aliases + 'LastChangedDate': ['LastChangedDate', 'Date'], + 'LastChangedRevision': ['LastChangedRevision', 'Rev', 'Revision'], + 'LastChangedBy': ['LastChangedBy', 'Author'], + 'URL': ['URL', 'HeadURL'], + } + + def repl(m): + if m.group(2): + return "$%s::%s$" % (m.group(1), " " * len(m.group(3))) + return "$%s$" % m.group(1) + keywords = [keyword + for name in keyword_str.split(" ") + for keyword in svn_keywords.get(name, [])] + return re.sub(r"\$(%s):(:?)([^\$]+)\$" % '|'.join(keywords), repl, content) + + def GetUnknownFiles(self): + status = RunShell(["svn", "status", "--ignore-externals"], silent_ok=True) + unknown_files = [] + for line in status.split("\n"): + if line and line[0] == "?": + unknown_files.append(line) + return unknown_files + + def ReadFile(self, filename): + """Returns the contents of a file.""" + file = open(filename, 'rb') + result = "" + try: + result = file.read() + finally: + file.close() + return result + + def GetStatus(self, filename): + """Returns the status of a file.""" + if not self.options.revision: + status = RunShell(["svn", "status", "--ignore-externals", filename]) + if not status: + ErrorExit("svn status returned no output for %s" % filename) + status_lines = status.splitlines() + # If file is in a cl, the output will begin with + # "\n--- Changelist 'cl_name':\n". See + # http://svn.collab.net/repos/svn/trunk/notes/changelist-design.txt + if (len(status_lines) == 3 and + not status_lines[0] and + status_lines[1].startswith("--- Changelist")): + status = status_lines[2] + else: + status = status_lines[0] + # If we have a revision to diff against we need to run "svn list" + # for the old and the new revision and compare the results to get + # the correct status for a file. + else: + dirname, relfilename = os.path.split(filename) + if dirname not in self.svnls_cache: + cmd = ["svn", "list", "-r", self.rev_start, dirname or "."] + out, err, returncode = RunShellWithReturnCodeAndStderr(cmd) + if returncode: + # Directory might not yet exist at start revison + # svn: Unable to find repository location for 'abc' in revision nnn + if re.match('^svn: Unable to find repository location for .+ in revision \d+', err): + old_files = () + else: + ErrorExit("Failed to get status for %s:\n%s" % (filename, err)) + else: + old_files = out.splitlines() + args = ["svn", "list"] + if self.rev_end: + args += ["-r", self.rev_end] + cmd = args + [dirname or "."] + out, returncode = RunShellWithReturnCode(cmd) + if returncode: + ErrorExit("Failed to run command %s" % cmd) + self.svnls_cache[dirname] = (old_files, out.splitlines()) + old_files, new_files = self.svnls_cache[dirname] + if relfilename in old_files and relfilename not in new_files: + status = "D " + elif relfilename in old_files and relfilename in new_files: + status = "M " + else: + status = "A " + return status + + def GetBaseFile(self, filename): + status = self.GetStatus(filename) + base_content = None + new_content = None + + # If a file is copied its status will be "A +", which signifies + # "addition-with-history". See "svn st" for more information. We need to + # upload the original file or else diff parsing will fail if the file was + # edited. + if status[0] == "A" and status[3] != "+": + # We'll need to upload the new content if we're adding a binary file + # since diff's output won't contain it. + mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], + silent_ok=True) + base_content = "" + is_binary = bool(mimetype) and not mimetype.startswith("text/") + if is_binary and self.IsImage(filename): + new_content = self.ReadFile(filename) + elif (status[0] in ("M", "D", "R") or + (status[0] == "A" and status[3] == "+") or # Copied file. + (status[0] == " " and status[1] == "M")): # Property change. + args = [] + if self.options.revision: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + # Don't change filename, it's needed later. + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:mime-type", url] + mimetype, returncode = RunShellWithReturnCode(cmd) + if returncode: + # File does not exist in the requested revision. + # Reset mimetype, it contains an error message. + mimetype = "" + else: + mimetype = mimetype.strip() + get_base = False + is_binary = (bool(mimetype) and + not mimetype.startswith("text/") and + not mimetype in TEXT_MIMETYPES) + if status[0] == " ": + # Empty base content just to force an upload. + base_content = "" + elif is_binary: + if self.IsImage(filename): + get_base = True + if status[0] == "M": + if not self.rev_end: + new_content = self.ReadFile(filename) + else: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_end) + new_content = RunShell(["svn", "cat", url], + universal_newlines=True, silent_ok=True) + else: + base_content = "" + else: + get_base = True + + if get_base: + if is_binary: + universal_newlines = False + else: + universal_newlines = True + if self.rev_start: + # "svn cat -r REV delete_file.txt" doesn't work. cat requires + # the full URL with "@REV" appended instead of using "-r" option. + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + base_content = RunShell(["svn", "cat", url], + universal_newlines=universal_newlines, + silent_ok=True) + else: + base_content, ret_code = RunShellWithReturnCode( + ["svn", "cat", filename], universal_newlines=universal_newlines) + if ret_code and status[0] == "R": + # It's a replaced file without local history (see issue208). + # The base file needs to be fetched from the server. + url = "%s/%s" % (self.svn_base, filename) + base_content = RunShell(["svn", "cat", url], + universal_newlines=universal_newlines, + silent_ok=True) + elif ret_code: + ErrorExit("Got error status from 'svn cat %s'" % filename) + if not is_binary: + args = [] + if self.rev_start: + url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) + else: + url = filename + args += ["-r", "BASE"] + cmd = ["svn"] + args + ["propget", "svn:keywords", url] + keywords, returncode = RunShellWithReturnCode(cmd) + if keywords and not returncode: + base_content = self._CollapseKeywords(base_content, keywords) + else: + StatusUpdate("svn status returned unexpected output: %s" % status) + sys.exit(1) + return base_content, new_content, is_binary, status[0:5] + + +class GitVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Git.""" + + def __init__(self, options): + super(GitVCS, self).__init__(options) + # Map of filename -> (hash before, hash after) of base file. + # Hashes for "no such file" are represented as None. + self.hashes = {} + # Map of new filename -> old filename for renames. + self.renames = {} + + def PostProcessDiff(self, gitdiff): + """Converts the diff output to include an svn-style "Index:" line as well + as record the hashes of the files, so we can upload them along with our + diff.""" + # Special used by git to indicate "no such content". + NULL_HASH = "0"*40 + + def IsFileNew(filename): + return filename in self.hashes and self.hashes[filename][0] is None + + def AddSubversionPropertyChange(filename): + """Add svn's property change information into the patch if given file is + new file. + + We use Subversion's auto-props setting to retrieve its property. + See http://svnbook.red-bean.com/en/1.1/ch07.html#svn-ch-7-sect-1.3.2 for + Subversion's [auto-props] setting. + """ + if self.options.emulate_svn_auto_props and IsFileNew(filename): + svnprops = GetSubversionPropertyChanges(filename) + if svnprops: + svndiff.append("\n" + svnprops + "\n") + + svndiff = [] + filecount = 0 + filename = None + for line in gitdiff.splitlines(): + match = re.match(r"diff --git a/(.*) b/(.*)$", line) + if match: + # Add auto property here for previously seen file. + if filename is not None: + AddSubversionPropertyChange(filename) + filecount += 1 + # Intentionally use the "after" filename so we can show renames. + filename = match.group(2) + svndiff.append("Index: %s\n" % filename) + if match.group(1) != match.group(2): + self.renames[match.group(2)] = match.group(1) + else: + # The "index" line in a git diff looks like this (long hashes elided): + # index 82c0d44..b2cee3f 100755 + # We want to save the left hash, as that identifies the base file. + match = re.match(r"index (\w+)\.\.(\w+)", line) + if match: + before, after = (match.group(1), match.group(2)) + if before == NULL_HASH: + before = None + if after == NULL_HASH: + after = None + self.hashes[filename] = (before, after) + svndiff.append(line + "\n") + if not filecount: + ErrorExit("No valid patches found in output from git diff") + # Add auto property for the last seen file. + assert filename is not None + AddSubversionPropertyChange(filename) + return "".join(svndiff) + + def GenerateDiff(self, extra_args): + extra_args = extra_args[:] + if self.options.revision: + if ":" in self.options.revision: + extra_args = self.options.revision.split(":", 1) + extra_args + else: + extra_args = [self.options.revision] + extra_args + + # --no-ext-diff is broken in some versions of Git, so try to work around + # this by overriding the environment (but there is still a problem if the + # git config key "diff.external" is used). + env = os.environ.copy() + if 'GIT_EXTERNAL_DIFF' in env: del env['GIT_EXTERNAL_DIFF'] + return RunShell(["git", "diff", "--no-ext-diff", "--full-index", "-M"] + + extra_args, env=env) + + def GetUnknownFiles(self): + status = RunShell(["git", "ls-files", "--exclude-standard", "--others"], + silent_ok=True) + return status.splitlines() + + def GetFileContent(self, file_hash, is_binary): + """Returns the content of a file identified by its git hash.""" + data, retcode = RunShellWithReturnCode(["git", "show", file_hash], + universal_newlines=not is_binary) + if retcode: + ErrorExit("Got error status from 'git show %s'" % file_hash) + return data + + def GetBaseFile(self, filename): + hash_before, hash_after = self.hashes.get(filename, (None,None)) + base_content = None + new_content = None + is_binary = self.IsBinary(filename) + status = None + + if filename in self.renames: + status = "A +" # Match svn attribute name for renames. + if filename not in self.hashes: + # If a rename doesn't change the content, we never get a hash. + base_content = RunShell(["git", "show", "HEAD:" + filename]) + elif not hash_before: + status = "A" + base_content = "" + elif not hash_after: + status = "D" + else: + status = "M" + + is_image = self.IsImage(filename) + + # Grab the before/after content if we need it. + # We should include file contents if it's text or it's an image. + if not is_binary or is_image: + # Grab the base content if we don't have it already. + if base_content is None and hash_before: + base_content = self.GetFileContent(hash_before, is_binary) + # Only include the "after" file if it's an image; otherwise it + # it is reconstructed from the diff. + if is_image and hash_after: + new_content = self.GetFileContent(hash_after, is_binary) + + return (base_content, new_content, is_binary, status) + + +class MercurialVCS(VersionControlSystem): + """Implementation of the VersionControlSystem interface for Mercurial.""" + + def __init__(self, options, repo_dir): + super(MercurialVCS, self).__init__(options) + # Absolute path to repository (we can be in a subdir) + self.repo_dir = os.path.normpath(repo_dir) + # Compute the subdir + cwd = os.path.normpath(os.getcwd()) + assert cwd.startswith(self.repo_dir) + self.subdir = cwd[len(self.repo_dir):].lstrip(r"\/") + if self.options.revision: + self.base_rev = self.options.revision + else: + self.base_rev = RunShell(["hg", "parent", "-q"]).split(':')[1].strip() + + def _GetRelPath(self, filename): + """Get relative path of a file according to the current directory, + given its logical path in the repo.""" + assert filename.startswith(self.subdir), (filename, self.subdir) + return filename[len(self.subdir):].lstrip(r"\/") + + def GenerateDiff(self, extra_args): + cmd = ["hg", "diff", "--git", "-r", self.base_rev] + extra_args + data = RunShell(cmd, silent_ok=True) + svndiff = [] + filecount = 0 + for line in data.splitlines(): + m = re.match("diff --git a/(\S+) b/(\S+)", line) + if m: + # Modify line to make it look like as it comes from svn diff. + # With this modification no changes on the server side are required + # to make upload.py work with Mercurial repos. + # NOTE: for proper handling of moved/copied files, we have to use + # the second filename. + filename = m.group(2) + svndiff.append("Index: %s" % filename) + svndiff.append("=" * 67) + filecount += 1 + logging.info(line) + else: + svndiff.append(line) + if not filecount: + ErrorExit("No valid patches found in output from hg diff") + return "\n".join(svndiff) + "\n" + + def GetUnknownFiles(self): + """Return a list of files unknown to the VCS.""" + args = [] + status = RunShell(["hg", "status", "--rev", self.base_rev, "-u", "."], + silent_ok=True) + unknown_files = [] + for line in status.splitlines(): + st, fn = line.split(" ", 1) + if st == "?": + unknown_files.append(fn) + return unknown_files + + def GetBaseFile(self, filename): + # "hg status" and "hg cat" both take a path relative to the current subdir + # rather than to the repo root, but "hg diff" has given us the full path + # to the repo root. + base_content = "" + new_content = None + is_binary = False + oldrelpath = relpath = self._GetRelPath(filename) + # "hg status -C" returns two lines for moved/copied files, one otherwise + out = RunShell(["hg", "status", "-C", "--rev", self.base_rev, relpath]) + out = out.splitlines() + # HACK: strip error message about missing file/directory if it isn't in + # the working copy + if out[0].startswith('%s: ' % relpath): + out = out[1:] + status, _ = out[0].split(' ', 1) + if len(out) > 1 and status == "A": + # Moved/copied => considered as modified, use old filename to + # retrieve base contents + oldrelpath = out[1].strip() + status = "M" + if ":" in self.base_rev: + base_rev = self.base_rev.split(":", 1)[0] + else: + base_rev = self.base_rev + if status != "A": + base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], + silent_ok=True) + is_binary = "\0" in base_content # Mercurial's heuristic + if status != "R": + new_content = open(relpath, "rb").read() + is_binary = is_binary or "\0" in new_content + if is_binary and base_content: + # Fetch again without converting newlines + base_content = RunShell(["hg", "cat", "-r", base_rev, oldrelpath], + silent_ok=True, universal_newlines=False) + if not is_binary or not self.IsImage(relpath): + new_content = None + return base_content, new_content, is_binary, status + + +# NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. +def SplitPatch(data): + """Splits a patch into separate pieces for each file. + + Args: + data: A string containing the output of svn diff. + + Returns: + A list of 2-tuple (filename, text) where text is the svn diff output + pertaining to filename. + """ + patches = [] + filename = None + diff = [] + for line in data.splitlines(True): + new_filename = None + if line.startswith('Index:'): + unused, new_filename = line.split(':', 1) + new_filename = new_filename.strip() + elif line.startswith('Property changes on:'): + unused, temp_filename = line.split(':', 1) + # When a file is modified, paths use '/' between directories, however + # when a property is modified '\' is used on Windows. Make them the same + # otherwise the file shows up twice. + temp_filename = temp_filename.strip().replace('\\', '/') + if temp_filename != filename: + # File has property changes but no modifications, create a new diff. + new_filename = temp_filename + if new_filename: + if filename and diff: + patches.append((filename, ''.join(diff))) + filename = new_filename + diff = [line] + continue + if diff is not None: + diff.append(line) + if filename and diff: + patches.append((filename, ''.join(diff))) + return patches + + +def UploadSeparatePatches(issue, rpc_server, patchset, data, options): + """Uploads a separate patch for each file in the diff output. + + Returns a list of [patch_key, filename] for each file. + """ + patches = SplitPatch(data) + rv = [] + for patch in patches: + if len(patch[1]) > MAX_UPLOAD_SIZE: + print(("Not uploading the patch for " + patch[0] + + " because the file is too large.")) + continue + form_fields = [("filename", patch[0])] + if not options.download_base: + form_fields.append(("content_upload", "1")) + files = [("data", "data.diff", patch[1])] + ctype, body = EncodeMultipartFormData(form_fields, files) + url = "/%d/upload_patch/%d" % (int(issue), int(patchset)) + print("Uploading patch for " + patch[0]) + response_body = rpc_server.Send(url, body, content_type=ctype) + lines = response_body.splitlines() + if not lines or lines[0] != "OK": + StatusUpdate(" --> %s" % response_body) + sys.exit(1) + rv.append([lines[1], patch[0]]) + return rv + + +def GuessVCSName(): + """Helper to guess the version control system. + + This examines the current directory, guesses which VersionControlSystem + we're using, and returns an string indicating which VCS is detected. + + Returns: + A pair (vcs, output). vcs is a string indicating which VCS was detected + and is one of VCS_GIT, VCS_MERCURIAL, VCS_SUBVERSION, or VCS_UNKNOWN. + output is a string containing any interesting output from the vcs + detection routine, or None if there is nothing interesting. + """ + def RunDetectCommand(vcs_type, command): + """Helper to detect VCS by executing command. + + Returns: + A pair (vcs, output) or None. Throws exception on error. + """ + try: + out, returncode = RunShellWithReturnCode(command) + if returncode == 0: + return (vcs_type, out.strip()) + except OSError as xxx_todo_changeme: + (errcode, message) = xxx_todo_changeme.args + if errcode != errno.ENOENT: # command not found code + raise + + # Mercurial has a command to get the base directory of a repository + # Try running it, but don't die if we don't have hg installed. + # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. + res = RunDetectCommand(VCS_MERCURIAL, ["hg", "root"]) + if res != None: + return res + + # Subversion has a .svn in all working directories. + if os.path.isdir('.svn'): + logging.info("Guessed VCS = Subversion") + return (VCS_SUBVERSION, None) + + # Git has a command to test if you're in a git tree. + # Try running it, but don't die if we don't have git installed. + res = RunDetectCommand(VCS_GIT, ["git", "rev-parse", + "--is-inside-work-tree"]) + if res != None: + return res + + return (VCS_UNKNOWN, None) + + +def GuessVCS(options): + """Helper to guess the version control system. + + This verifies any user-specified VersionControlSystem (by command line + or environment variable). If the user didn't specify one, this examines + the current directory, guesses which VersionControlSystem we're using, + and returns an instance of the appropriate class. Exit with an error + if we can't figure it out. + + Returns: + A VersionControlSystem instance. Exits if the VCS can't be guessed. + """ + vcs = options.vcs + if not vcs: + vcs = os.environ.get("CODEREVIEW_VCS") + if vcs: + v = VCS_ABBREVIATIONS.get(vcs.lower()) + if v is None: + ErrorExit("Unknown version control system %r specified." % vcs) + (vcs, extra_output) = (v, None) + else: + (vcs, extra_output) = GuessVCSName() + + if vcs == VCS_MERCURIAL: + if extra_output is None: + extra_output = RunShell(["hg", "root"]).strip() + return MercurialVCS(options, extra_output) + elif vcs == VCS_SUBVERSION: + return SubversionVCS(options) + elif vcs == VCS_GIT: + return GitVCS(options) + + ErrorExit(("Could not guess version control system. " + "Are you in a working copy directory?")) + + +def CheckReviewer(reviewer): + """Validate a reviewer -- either a nickname or an email addres. + + Args: + reviewer: A nickname or an email address. + + Calls ErrorExit() if it is an invalid email address. + """ + if "@" not in reviewer: + return # Assume nickname + parts = reviewer.split("@") + if len(parts) > 2: + ErrorExit("Invalid email address: %r" % reviewer) + assert len(parts) == 2 + if "." not in parts[1]: + ErrorExit("Invalid email address: %r" % reviewer) + + +def LoadSubversionAutoProperties(): + """Returns the content of [auto-props] section of Subversion's config file as + a dictionary. + + Returns: + A dictionary whose key-value pair corresponds the [auto-props] section's + key-value pair. + In following cases, returns empty dictionary: + - config file doesn't exist, or + - 'enable-auto-props' is not set to 'true-like-value' in [miscellany]. + """ + if os.name == 'nt': + subversion_config = os.environ.get("APPDATA") + "\\Subversion\\config" + else: + subversion_config = os.path.expanduser("~/.subversion/config") + if not os.path.exists(subversion_config): + return {} + config = configparser.ConfigParser() + config.read(subversion_config) + if (config.has_section("miscellany") and + config.has_option("miscellany", "enable-auto-props") and + config.getboolean("miscellany", "enable-auto-props") and + config.has_section("auto-props")): + props = {} + for file_pattern in config.options("auto-props"): + props[file_pattern] = ParseSubversionPropertyValues( + config.get("auto-props", file_pattern)) + return props + else: + return {} + +def ParseSubversionPropertyValues(props): + """Parse the given property value which comes from [auto-props] section and + returns a list whose element is a (svn_prop_key, svn_prop_value) pair. + + See the following doctest for example. + + >>> ParseSubversionPropertyValues('svn:eol-style=LF') + [('svn:eol-style', 'LF')] + >>> ParseSubversionPropertyValues('svn:mime-type=image/jpeg') + [('svn:mime-type', 'image/jpeg')] + >>> ParseSubversionPropertyValues('svn:eol-style=LF;svn:executable') + [('svn:eol-style', 'LF'), ('svn:executable', '*')] + """ + key_value_pairs = [] + for prop in props.split(";"): + key_value = prop.split("=") + assert len(key_value) <= 2 + if len(key_value) == 1: + # If value is not given, use '*' as a Subversion's convention. + key_value_pairs.append((key_value[0], "*")) + else: + key_value_pairs.append((key_value[0], key_value[1])) + return key_value_pairs + + +def GetSubversionPropertyChanges(filename): + """Return a Subversion's 'Property changes on ...' string, which is used in + the patch file. + + Args: + filename: filename whose property might be set by [auto-props] config. + + Returns: + A string like 'Property changes on |filename| ...' if given |filename| + matches any entries in [auto-props] section. None, otherwise. + """ + global svn_auto_props_map + if svn_auto_props_map is None: + svn_auto_props_map = LoadSubversionAutoProperties() + + all_props = [] + for file_pattern, props in list(svn_auto_props_map.items()): + if fnmatch.fnmatch(filename, file_pattern): + all_props.extend(props) + if all_props: + return FormatSubversionPropertyChanges(filename, all_props) + return None + + +def FormatSubversionPropertyChanges(filename, props): + """Returns Subversion's 'Property changes on ...' strings using given filename + and properties. + + Args: + filename: filename + props: A list whose element is a (svn_prop_key, svn_prop_value) pair. + + Returns: + A string which can be used in the patch file for Subversion. + + See the following doctest for example. + + >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) + Property changes on: foo.cc + ___________________________________________________________________ + Added: svn:eol-style + + LF + + """ + prop_changes_lines = [ + "Property changes on: %s" % filename, + "___________________________________________________________________"] + for key, value in props: + prop_changes_lines.append("Added: " + key) + prop_changes_lines.append(" + " + value) + return "\n".join(prop_changes_lines) + "\n" + + +def RealMain(argv, data=None): + """The real main function. + + Args: + argv: Command line arguments. + data: Diff contents. If None (default) the diff is generated by + the VersionControlSystem implementation returned by GuessVCS(). + + Returns: + A 2-tuple (issue id, patchset id). + The patchset id is None if the base files are not uploaded by this + script (applies only to SVN checkouts). + """ + options, args = parser.parse_args(argv[1:]) + global verbosity + verbosity = options.verbose + if verbosity >= 3: + logging.getLogger().setLevel(logging.DEBUG) + elif verbosity >= 2: + logging.getLogger().setLevel(logging.INFO) + + vcs = GuessVCS(options) + + base = options.base_url + if isinstance(vcs, SubversionVCS): + # Guessing the base field is only supported for Subversion. + # Note: Fetching base files may become deprecated in future releases. + guessed_base = vcs.GuessBase(options.download_base) + if base: + if guessed_base and base != guessed_base: + print("Using base URL \"%s\" from --base_url instead of \"%s\"" % \ + (base, guessed_base)) + else: + base = guessed_base + + if not base and options.download_base: + options.download_base = True + logging.info("Enabled upload of base file") + if not options.assume_yes: + vcs.CheckForUnknownFiles() + if data is None: + data = vcs.GenerateDiff(args) + data = vcs.PostProcessDiff(data) + files = vcs.GetBaseFiles(data) + if verbosity >= 1: + print("Upload server:", options.server, "(change with -s/--server)") + if options.issue: + prompt = "Message describing this patch set: " + else: + prompt = "New issue subject: " + message = options.message or input(prompt).strip() + if not message: + ErrorExit("A non-empty message is required") + rpc_server = GetRpcServer(options.server, + options.email, + options.host, + options.save_cookies, + options.account_type) + form_fields = [("subject", message)] + if base: + b = urllib.parse.urlparse(base) + username, netloc = urllib.parse.splituser(b.netloc) + if username: + logging.info("Removed username from base URL") + base = urllib.parse.urlunparse((b.scheme, netloc, b.path, b.params, + b.query, b.fragment)) + form_fields.append(("base", base)) + if options.issue: + form_fields.append(("issue", str(options.issue))) + if options.email: + form_fields.append(("user", options.email)) + if options.reviewers: + for reviewer in options.reviewers.split(','): + CheckReviewer(reviewer) + form_fields.append(("reviewers", options.reviewers)) + if options.cc: + for cc in options.cc.split(','): + CheckReviewer(cc) + form_fields.append(("cc", options.cc)) + description = options.description + if options.description_file: + if options.description: + ErrorExit("Can't specify description and description_file") + file = open(options.description_file, 'r') + description = file.read() + file.close() + if description: + form_fields.append(("description", description)) + # Send a hash of all the base file so the server can determine if a copy + # already exists in an earlier patchset. + base_hashes = "" + for file, info in files.items(): + if not info[0] is None: + checksum = md5(info[0]).hexdigest() + if base_hashes: + base_hashes += "|" + base_hashes += checksum + ":" + file + form_fields.append(("base_hashes", base_hashes)) + if options.private: + if options.issue: + print("Warning: Private flag ignored when updating an existing issue.") + else: + form_fields.append(("private", "1")) + # If we're uploading base files, don't send the email before the uploads, so + # that it contains the file status. + if options.send_mail and options.download_base: + form_fields.append(("send_mail", "1")) + if not options.download_base: + form_fields.append(("content_upload", "1")) + if len(data) > MAX_UPLOAD_SIZE: + print("Patch is large, so uploading file patches separately.") + uploaded_diff_file = [] + form_fields.append(("separate_patches", "1")) + else: + uploaded_diff_file = [("data", "data.diff", data)] + ctype, body = EncodeMultipartFormData(form_fields, uploaded_diff_file) + response_body = rpc_server.Send("/upload", body, content_type=ctype) + patchset = None + if not options.download_base or not uploaded_diff_file: + lines = response_body.splitlines() + if len(lines) >= 2: + msg = lines[0] + patchset = lines[1].strip() + patches = [x.split(" ", 1) for x in lines[2:]] + else: + msg = response_body + else: + msg = response_body + StatusUpdate(msg) + if not response_body.startswith("Issue created.") and \ + not response_body.startswith("Issue updated."): + sys.exit(0) + issue = msg[msg.rfind("/")+1:] + + if not uploaded_diff_file: + result = UploadSeparatePatches(issue, rpc_server, patchset, data, options) + if not options.download_base: + patches = result + + if not options.download_base: + vcs.UploadBaseFiles(issue, rpc_server, patches, patchset, options, files) + if options.send_mail: + rpc_server.Send("/" + issue + "/mail", payload="") + return issue, patchset + + +def main(): + try: + logging.basicConfig(format=("%(asctime).19s %(levelname)s %(filename)s:" + "%(lineno)s %(message)s ")) + os.environ['LC_ALL'] = 'C' + RealMain(sys.argv) + except KeyboardInterrupt: + print() + StatusUpdate("Interrupted.") + sys.exit(1) + + +if __name__ == "__main__": + main() + diff --git a/runtest.py b/runtest.py index 6beb4ba..65d7851 100755 --- a/runtest.py +++ b/runtest.py @@ -92,10 +92,10 @@ import time try: import threading - import Queue # 2to3: rename to queue + import queue # 2to3: rename to queue threading_ok = True except ImportError: - print "Can't import threading or queue" + print("Can't import threading or queue") threading_ok = False cwd = os.getcwd() @@ -187,12 +187,12 @@ class PassThroughOptionParser(OptionParser): def _process_long_opt(self, rargs, values): try: OptionParser._process_long_opt(self, rargs, values) - except BadOptionError, err: + except BadOptionError as err: self.largs.append(err.opt_str) def _process_short_opts(self, rargs, values): try: OptionParser._process_short_opts(self, rargs, values) - except BadOptionError, err: + except BadOptionError as err: self.largs.append(err.opt_str) parser = PassThroughOptionParser(add_help_option=False) @@ -240,7 +240,7 @@ for o, a in opts: a = os.path.join(cwd, a) testlistfile = a elif o in ['-h', '--help']: - print helpstr + print(helpstr) sys.exit(0) elif o in ['-j', '--jobs']: jobs = int(a) @@ -343,7 +343,7 @@ else: st = os.stat(f) except OSError: continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: return f return None @@ -590,7 +590,7 @@ else: base = os.path.join(base, os.path.split(url)[1]) if printcommand: - print command + print(command) if execute_tests: os.system(command) else: @@ -843,9 +843,9 @@ def run_test(t, io_lock, async=True): if suppress_stdout or suppress_stderr: sys.stdout.write(header) if not suppress_stdout and t.stdout: - print t.stdout + print(t.stdout) if not suppress_stderr and t.stderr: - print t.stderr + print(t.stderr) print_time_func("Test execution time: %.1f seconds\n", t.test_time) if io_lock: io_lock.release() @@ -863,9 +863,9 @@ class RunTest(threading.Thread): self.queue.task_done() if jobs > 1 and threading_ok: - print "Running tests using %d jobs"%jobs + print("Running tests using %d jobs"%jobs) # Start worker threads - queue = Queue.Queue() + queue = queue.Queue() io_lock = threading.Lock() for i in range(1, jobs): t = RunTest(queue, io_lock) @@ -878,7 +878,7 @@ if jobs > 1 and threading_ok: else: # Run tests serially if jobs > 1: - print "Ignoring -j%d option; no python threading module available."%jobs + print("Ignoring -j%d option; no python threading module available."%jobs) for t in tests: run_test(t, None, False) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index c1eef75..e8574cb 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -114,6 +114,7 @@ import SCons.Errors import SCons.Executor import SCons.Util import SCons.Subst +import collections # we use these a lot, so try to optimize them is_String = SCons.Util.is_String @@ -165,12 +166,12 @@ def _callable_contents(obj): """ try: # Test if obj is a method. - return _function_contents(obj.im_func) + return _function_contents(obj.__func__) except AttributeError: try: # Test if obj is a callable object. - return _function_contents(obj.__call__.im_func) + return _function_contents(obj.__call__.__func__) except AttributeError: try: @@ -190,12 +191,12 @@ def _object_contents(obj): """ try: # Test if obj is a method. - return _function_contents(obj.im_func) + return _function_contents(obj.__func__) except AttributeError: try: # Test if obj is a callable object. - return _function_contents(obj.__call__.im_func) + return _function_contents(obj.__call__.__func__) except AttributeError: try: @@ -269,17 +270,17 @@ def _code_contents(code): def _function_contents(func): """Return the signature contents of a function.""" - contents = [_code_contents(func.func_code)] + contents = [_code_contents(func.__code__)] # The function contents depends on the value of defaults arguments - if func.func_defaults: - contents.append(',(' + ','.join(map(_object_contents,func.func_defaults)) + ')') + if func.__defaults__: + contents.append(',(' + ','.join(map(_object_contents,func.__defaults__)) + ')') else: contents.append(',()') # The function contents depends on the closure captured cell values. try: - closure = func.func_closure or [] + closure = func.__closure__ or [] except AttributeError: # Older versions of Python do not support closures. closure = [] @@ -328,7 +329,7 @@ def _do_create_keywords(args, kw): cmdstrfunc = args[0] if cmdstrfunc is None or is_String(cmdstrfunc): kw['cmdstr'] = cmdstrfunc - elif callable(cmdstrfunc): + elif isinstance(cmdstrfunc, collections.Callable): kw['strfunction'] = cmdstrfunc else: raise SCons.Errors.UserError( @@ -359,7 +360,7 @@ def _do_create_action(act, kw): if is_List(act): return CommandAction(act, **kw) - if callable(act): + if isinstance(act, collections.Callable): try: gen = kw['generator'] del kw['generator'] @@ -492,7 +493,7 @@ class _ActionAction(ActionBase): self.targets = targets if batch_key: - if not callable(batch_key): + if not isinstance(batch_key, collections.Callable): # They have set batch_key, but not to their own # callable. The default behavior here will batch # *all* targets+sources using this action, separated @@ -512,7 +513,7 @@ class _ActionAction(ActionBase): # This code assumes s is a regular string, but should # work if it's unicode too. try: - sys.stdout.write(unicode(s + "\n")) + sys.stdout.write(str(s + "\n")) except UnicodeDecodeError: sys.stdout.write(s + "\n") @@ -553,7 +554,7 @@ class _ActionAction(ActionBase): source = executor.get_all_sources() t = ' and '.join(map(str, target)) l = '\n '.join(self.presub_lines(env)) - out = u"Building %s with action:\n %s\n" % (t, l) + out = "Building %s with action:\n %s\n" % (t, l) sys.stdout.write(out) cmd = None if show and self.strfunction: @@ -653,7 +654,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw): # Ensure that the ENV values are all strings: new_env = {} - for key, value in ENV.items(): + for key, value in list(ENV.items()): if is_List(value): # If the value is a list, then we assume it is a path list, # because that's a pretty common list-like value to stick @@ -672,7 +673,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw): try: return subprocess.Popen(cmd, **kw) - except EnvironmentError, e: + except EnvironmentError as e: if error == 'raise': raise # return a dummy Popen instance that only returns error class dummyPopen(object): @@ -779,7 +780,7 @@ class CommandAction(_ActionAction): ENV = get_default_ENV(env) # Ensure that the ENV values are all strings: - for key, value in ENV.items(): + for key, value in list(ENV.items()): if not is_String(value): if is_List(value): # If the value is a list, then we assume it is a @@ -1038,7 +1039,7 @@ class FunctionAction(_ActionAction): else: if strfunc is None: return None - if callable(strfunc): + if isinstance(strfunc, collections.Callable): return strfunc(target, source, env) name = self.function_name() tstr = array(target) @@ -1060,11 +1061,11 @@ class FunctionAction(_ActionAction): rsources = list(map(rfile, source)) try: result = self.execfunction(target=target, source=rsources, env=env) - except KeyboardInterrupt, e: + except KeyboardInterrupt as e: raise - except SystemExit, e: + except SystemExit as e: raise - except Exception, e: + except Exception as e: result = e exc_info = sys.exc_info() @@ -1179,11 +1180,11 @@ class ActionCaller(object): actfunc = self.parent.actfunc try: # "self.actfunc" is a function. - contents = str(actfunc.func_code.co_code) + contents = str(actfunc.__code__.co_code) except AttributeError: # "self.actfunc" is a callable object. try: - contents = str(actfunc.__call__.im_func.func_code.co_code) + contents = str(actfunc.__call__.__func__.__code__.co_code) except AttributeError: # No __call__() method, so it might be a builtin # or something like that. Do the best we can. @@ -1214,7 +1215,7 @@ class ActionCaller(object): def subst_kw(self, target, source, env): kw = {} - for key in self.kw.keys(): + for key in list(self.kw.keys()): kw[key] = self.subst(self.kw[key], target, source, env) return kw diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 13c3b6c..6edf373 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -133,7 +133,7 @@ class Environment(object): self.d['SPAWN'] = scons_env['SPAWN'] self.d['PSPAWN'] = scons_env['PSPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in kw.items(): + for k, v in list(kw.items()): self.d[k] = v # Just use the underlying scons_subst*() utility methods. def subst(self, strSubst, raw=0, target=[], source=[], conv=None): @@ -158,12 +158,12 @@ class Environment(object): def Clone(self, **kw): res = Environment() res.d = SCons.Util.semi_deepcopy(self.d) - for k, v in kw.items(): + for k, v in list(kw.items()): res.d[k] = v return res def sig_dict(self): d = {} - for k,v in self.items(): d[k] = v + for k,v in list(self.items()): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] @@ -270,7 +270,7 @@ def test_positional_args(pos_callback, cmd, **kw): try: #FUTURE a = SCons.Action.Action(cmd, [], **kw) a = SCons.Action.Action(cmd, [], **kw) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: s = str(e) m = 'Invalid command display variable' assert s.find(m) != -1, 'Unexpected string: %s' % s @@ -305,7 +305,7 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(cmd_action, ["string"]) - try: unicode + try: str except NameError: pass else: a2 = eval("SCons.Action.Action(u'string')") @@ -493,7 +493,7 @@ class _ActionActionTestCase(unittest.TestCase): def func(): pass try: a = SCons.Action.Action('foo', cmdstr='string', strfunction=func) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: s = str(e) m = 'Cannot have both strfunction and cmdstr args to Action()' assert s.find(m) != -1, 'Unexpected string: %s' % s diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 6dc9e17..6abcbcf 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -167,7 +167,7 @@ class DictCmdGenerator(SCons.Util.Selector): try: ret = SCons.Util.Selector.__call__(self, env, source, ext) - except KeyError, e: + except KeyError as e: raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e.args[0], e.args[1], e.args[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." % \ @@ -179,7 +179,7 @@ class CallableSelector(SCons.Util.Selector): finds if it can.""" def __call__(self, env, source): value = SCons.Util.Selector.__call__(self, env, source) - if callable(value): + if isinstance(value, collections.Callable): value = value(env, source) return value @@ -230,7 +230,7 @@ class OverrideWarner(collections.UserDict): def warn(self): if self.already_warned: return - for k in self.keys(): + for k in list(self.keys()): if k in misleading_keywords: alt = misleading_keywords[k] msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k) @@ -336,7 +336,7 @@ class EmitterProxy(object): # in strings. Maybe we should change that? while SCons.Util.is_String(emitter) and emitter in env: emitter = env[emitter] - if callable(emitter): + if isinstance(emitter, collections.Callable): target, source = emitter(target, source, env) elif SCons.Util.is_List(emitter): for e in emitter: @@ -426,7 +426,7 @@ class BuilderBase(object): src_builder = [ src_builder ] self.src_builder = src_builder - def __nonzero__(self): + def __bool__(self): raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead") def get_name(self, env): @@ -638,18 +638,18 @@ class BuilderBase(object): def get_prefix(self, env, sources=[]): prefix = self.prefix - if callable(prefix): + if isinstance(prefix, collections.Callable): prefix = prefix(env, sources) return env.subst(prefix) def set_suffix(self, suffix): - if not callable(suffix): + if not isinstance(suffix, collections.Callable): suffix = self.adjust_suffix(suffix) self.suffix = suffix def get_suffix(self, env, sources=[]): suffix = self.suffix - if callable(suffix): + if isinstance(suffix, collections.Callable): suffix = suffix(env, sources) return env.subst(suffix) @@ -658,7 +658,7 @@ class BuilderBase(object): src_suffix = [] elif not SCons.Util.is_List(src_suffix): src_suffix = [ src_suffix ] - self.src_suffix = [callable(suf) and suf or self.adjust_suffix(suf) for suf in src_suffix] + self.src_suffix = [isinstance(suf, collections.Callable) 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.""" @@ -868,7 +868,7 @@ def is_a_Builder(obj): """ return (isinstance(obj, BuilderBase) or isinstance(obj, CompositeBuilder) - or callable(obj)) + or isinstance(obj, collections.Callable)) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 766b8fe..da03a3c 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -77,7 +77,7 @@ class Environment(object): self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in kw.items(): + for k, v in list(kw.items()): self.d[k] = v global env_arg2nodes_called env_arg2nodes_called = None @@ -138,7 +138,7 @@ class Environment(object): return list(self.d.items()) def sig_dict(self): d = {} - for k,v in self.items(): d[k] = v + for k,v in list(self.items()): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] @@ -305,11 +305,11 @@ class BuilderTestCase(unittest.TestCase): #be = target.get_build_env() #assert be['VAR'] == 'foo', be['VAR'] - try: unicode + try: str except NameError: uni = str else: - uni = unicode + uni = str target = builder(env, target = uni('n12 n13'), source = [uni('n14 n15')])[0] @@ -325,7 +325,7 @@ class BuilderTestCase(unittest.TestCase): flag = 0 try: target = builder(env, None, source=n20) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown if a source node can't create a target." @@ -341,7 +341,7 @@ class BuilderTestCase(unittest.TestCase): suffix = '.s') try: builder(env, target = 'n22', source = 'n22') - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: pass else: raise Exception("Did not catch expected UserError.") @@ -1497,7 +1497,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo" @@ -1528,8 +1528,8 @@ class CompositeBuilderTestCase(unittest.TestCase): try: tgt.build() flag = 1 - except SCons.Errors.UserError, e: - print e + except SCons.Errors.UserError as e: + print(e) flag = 0 assert flag, "It should be possible to define actions in composite builders using variables." env['FOO_SUFFIX'] = '.BAR2' @@ -1581,7 +1581,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t5']' from `test5b.bar': Cannot build multiple sources with different extensions: .foo, .bar" @@ -1590,7 +1590,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t6']' from `test6b.foo': Cannot build multiple sources with different extensions: .bar, .foo" @@ -1599,7 +1599,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t4']' from `test4b.bar': Cannot build multiple sources with different extensions: .foo, .bar" @@ -1608,7 +1608,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='t7', source=[env.fs.File('test7')])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t7']': Cannot deduce file extension from source files: ['test7']" @@ -1617,7 +1617,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 0 try: builder(env, target='t8', source=['test8.unknown'])[0] - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: flag = 1 assert flag, "UserError should be thrown when we call a builder target with an unknown suffix." expect = "While building `['t8']' from `['test8.unknown']': Don't know how to build from a source file with suffix `.unknown'. Expected a suffix in this list: ['.foo', '.bar']." diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py index 21b435a..269040d 100644 --- a/src/engine/SCons/CacheDirTests.py +++ b/src/engine/SCons/CacheDirTests.py @@ -241,7 +241,7 @@ class FileTestCase(BaseTestCase): warn_caught = 0 try: f7.push_to_cache() - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: assert e.exc_info[0] == SCons.Warnings.CacheWriteErrorWarning warn_caught = 1 assert warn_caught diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 1c0c638..363c8b7 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -73,7 +73,7 @@ def dumpLoggedInstances(classes, file=sys.stdout): obj = ref() if obj is not None: file.write(' %s:\n' % obj) - for key, value in obj.__dict__.items(): + for key, value in list(obj.__dict__.items()): file.write(' %20s : %s\n' % (key, value)) @@ -143,7 +143,7 @@ def caller_trace(back=0): # print a single caller and its callers, if any def _dump_one_caller(key, file, level=0): leader = ' '*level - for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): + for v,c in sorted([(-v,c) for c,v in list(caller_dicts[key].items())]): file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) if c in caller_dicts: _dump_one_caller(c, file, level+1) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index a99bcc7..fe1f87b 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -31,7 +31,7 @@ from distutils.msvccompiler. # 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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -50,6 +50,7 @@ import SCons.Environment import SCons.PathList import SCons.Subst import SCons.Tool +import collections # A placeholder for a default Environment (for fetching source files # from source code management systems and the like). This must be @@ -221,7 +222,7 @@ def mkdir_func(dest): for entry in dest: try: os.makedirs(str(entry)) - except os.error, e: + except os.error as e: p = str(entry) if (e.args[0] == errno.EEXIST or (sys.platform=='win32' and e.args[0]==183)) \ @@ -325,9 +326,9 @@ def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None): if not itms: return itms - if not callable(c): + if not isinstance(c, collections.Callable): env_c = env['_concat'] - if env_c != _concat and callable(env_c): + if env_c != _concat and isinstance(env_c, collections.Callable): # There's a custom _concat() method in the construction # environment, and we've allowed people to set that in # the past (see test/custom-concat.py), so preserve the @@ -381,7 +382,7 @@ def processDefines(defs): else: l.append(str(d[0])) elif SCons.Util.is_Dict(d): - for macro,value in d.iteritems(): + for macro,value in d.items(): if value is not None: l.append(str(macro) + '=' + str(value)) else: diff --git a/src/engine/SCons/DefaultsTests.py b/src/engine/SCons/DefaultsTests.py index fd10c12..a36ca7c 100644 --- a/src/engine/SCons/DefaultsTests.py +++ b/src/engine/SCons/DefaultsTests.py @@ -69,7 +69,7 @@ class DefaultsTestCase(unittest.TestCase): test.write(file, "test\n") try: mkdir_func(file) - except os.error, e: + except os.error as e: pass else: fail("expected os.error") diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 55a8206..88b0553 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -58,6 +58,7 @@ import SCons.Subst import SCons.Tool import SCons.Util import SCons.Warnings +import collections class _Null(object): pass @@ -127,7 +128,7 @@ future_reserved_construction_var_names = [ def copy_non_reserved_keywords(dict): result = semi_deepcopy(dict) - for k in result.keys(): + for k in list(result.keys()): if k in reserved_construction_var_names: msg = "Ignoring attempt to set reserved variable `$%s'" SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) @@ -146,12 +147,12 @@ def _set_future_reserved(env, key, value): def _set_BUILDERS(env, key, value): try: bd = env._dict[key] - for k in bd.keys(): + for k in list(bd.keys()): del bd[k] except KeyError: bd = BuilderDict(kwbd, env) env._dict[key] = bd - for k, v in value.items(): + for k, v in list(value.items()): if not SCons.Builder.is_a_Builder(v): raise SCons.Errors.UserError('%s is not a Builder.' % repr(v)) bd.update(value) @@ -323,7 +324,7 @@ class BuilderDict(UserDict): delattr(self.env, item) def update(self, dict): - for i, v in dict.items(): + for i, v in list(dict.items()): self.__setitem__(i, v) @@ -517,7 +518,7 @@ class SubstitutionEnvironment(object): def subst_kw(self, kw, raw=0, target=None, source=None): nkw = {} - for k, v in kw.items(): + for k, v in list(kw.items()): k = self.subst(k, raw, target, source) if SCons.Util.is_String(v): v = self.subst(v, raw, target, source) @@ -591,7 +592,7 @@ class SubstitutionEnvironment(object): out,err = p.communicate() status = p.wait() if err: - sys.stderr.write(unicode(err)) + sys.stderr.write(str(err)) if status: raise OSError("'%s' exited %d" % (command, status)) return out @@ -629,7 +630,7 @@ class SubstitutionEnvironment(object): if not o: return self overrides = {} merges = None - for key, value in o.items(): + for key, value in list(o.items()): if key == 'parse_flags': merges = value else: @@ -814,7 +815,7 @@ class SubstitutionEnvironment(object): if not unique: self.Append(**args) return self - for key, value in args.items(): + for key, value in list(args.items()): if not value: continue try: @@ -1004,7 +1005,7 @@ class Base(SubstitutionEnvironment): # Now restore the passed-in and customized variables # to the environment, since the values the user set explicitly # should override any values set by the tools. - for key, val in save.items(): + for key, val in list(save.items()): self._dict[key] = val # Finally, apply any flags to be merged in @@ -1152,7 +1153,7 @@ class Base(SubstitutionEnvironment): in an Environment. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): # It would be easier on the eyes to write this using # "continue" statements whenever we finish processing an item, # but Python 1.5.2 apparently doesn't let you use "continue" @@ -1205,7 +1206,7 @@ class Base(SubstitutionEnvironment): # based on what we think the value looks like. if SCons.Util.is_List(val): if key == 'CPPDEFINES': - orig = orig.items() + orig = list(orig.items()) orig += val self._dict[key] = orig else: @@ -1216,7 +1217,7 @@ class Base(SubstitutionEnvironment): update_dict(val) except (AttributeError, TypeError, ValueError): if SCons.Util.is_Dict(val): - for k, v in val.items(): + for k, v in list(val.items()): orig[k] = v else: orig[val] = None @@ -1262,7 +1263,7 @@ class Base(SubstitutionEnvironment): values move to end. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_List(val): val = _delete_duplicates(val, delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1286,7 +1287,7 @@ class Base(SubstitutionEnvironment): tmp.append((i,)) val = tmp if SCons.Util.is_Dict(dk): - dk = dk.items() + dk = list(dk.items()) elif SCons.Util.is_String(dk): dk = [(dk,)] else: @@ -1327,11 +1328,11 @@ class Base(SubstitutionEnvironment): tmp.append((i,)) dk = tmp if SCons.Util.is_Dict(val): - val = val.items() + val = list(val.items()) elif SCons.Util.is_String(val): val = [(val,)] if delete_existing: - dk = filter(lambda x, val=val: x not in val, dk) + dk = list(filter(lambda x, val=val: x not in val, dk)) self._dict[key] = dk + val else: dk = [x for x in dk if x not in val] @@ -1340,7 +1341,7 @@ 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 = list(filter(lambda x, val=val: x not in val, dk)) self._dict[key] = dk + [val] else: if not val in dk: @@ -1350,7 +1351,7 @@ class Base(SubstitutionEnvironment): if SCons.Util.is_String(dk): dk = [dk] elif SCons.Util.is_Dict(dk): - dk = dk.items() + dk = list(dk.items()) if SCons.Util.is_String(val): if val in dk: val = [] @@ -1358,7 +1359,7 @@ class Base(SubstitutionEnvironment): val = [val] elif SCons.Util.is_Dict(val): tmp = [] - for i,j in val.iteritems(): + for i,j in val.items(): if j is not None: tmp.append((i,j)) else: @@ -1402,7 +1403,7 @@ class Base(SubstitutionEnvironment): # so the tools can use the new variables kw = copy_non_reserved_keywords(kw) new = {} - for key, value in kw.items(): + for key, value in list(kw.items()): new[key] = SCons.Subst.scons_subst_once(value, self, key) clone.Replace(**new) @@ -1469,7 +1470,7 @@ class Base(SubstitutionEnvironment): copy_function = self._copy_from_cache elif function == 'timestamp-match': function = self._changed_timestamp_match - elif not callable(function): + elif not isinstance(function, collections.Callable): raise UserError("Unknown Decider value %s" % repr(function)) # We don't use AddMethod because we don't want to turn the @@ -1602,7 +1603,7 @@ class Base(SubstitutionEnvironment): in an Environment. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): # It would be easier on the eyes to write this using # "continue" statements whenever we finish processing an item, # but Python 1.5.2 apparently doesn't let you use "continue" @@ -1656,7 +1657,7 @@ class Base(SubstitutionEnvironment): update_dict(val) except (AttributeError, TypeError, ValueError): if SCons.Util.is_Dict(val): - for k, v in val.items(): + for k, v in list(val.items()): orig[k] = v else: orig[val] = None @@ -1693,7 +1694,7 @@ class Base(SubstitutionEnvironment): values move to front. """ kw = copy_non_reserved_keywords(kw) - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_List(val): val = _delete_duplicates(val, not delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1768,7 +1769,7 @@ class Base(SubstitutionEnvironment): return os.path.join(dir, new_prefix+name+new_suffix) def SetDefault(self, **kw): - for k in kw.keys(): + for k in list(kw.keys()): if k in self._dict: del kw[k] self.Replace(**kw) @@ -1830,7 +1831,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in uniq.keys(): + for executor in list(uniq.keys()): executor.add_pre_action(action) return nodes @@ -1840,7 +1841,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in uniq.keys(): + for executor in list(uniq.keys()): executor.add_post_action(action) return nodes @@ -2235,7 +2236,7 @@ class Base(SubstitutionEnvironment): while (node != node.srcnode()): node = node.srcnode() return node - sources = map( final_source, sources ); + sources = list(map( final_source, sources )); # remove duplicates return list(set(sources)) @@ -2378,7 +2379,7 @@ def NoSubstitutionProxy(subject): def __setattr__(self, name, value): return setattr(self.__dict__['__subject'], name, value) def executor_to_lvars(self, kwdict): - if kwdict.has_key('executor'): + if 'executor' in kwdict: kwdict['lvars'] = kwdict['executor'].get_lvars() del kwdict['executor'] else: diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 45cf876..3af879a 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -160,7 +160,7 @@ class TestEnvironmentFixture(object): default_keys = { 'CC' : 'cc', 'CCFLAGS' : '-DNDEBUG', 'ENV' : { 'TMP' : '/tmp' } } - for key, value in default_keys.items(): + for key, value in list(default_keys.items()): if key not in kw: kw[key] = value if 'BUILDERS' not in kw: @@ -263,7 +263,7 @@ class SubstitutionTestCase(unittest.TestCase): assert isinstance(nodes[0], X) assert nodes[0].name == "Util.py UtilTests.py" - try: unicode + try: str except NameError: pass else: code = """if 1: @@ -272,7 +272,7 @@ class SubstitutionTestCase(unittest.TestCase): assert isinstance(nodes[0], X) assert nodes[0].name == u"Util.py UtilTests.py" \n""" - exec code in globals(), locals() + exec(code, globals(), locals()) nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory) assert len(nodes) == 2, nodes @@ -655,7 +655,7 @@ sys.exit(0) cmd = '%s %s' % (python, test.workpath('fail.py')) try: env.backtick(cmd) - except OSError, e: + except OSError as e: assert str(e) == "'%s' exited 1" % cmd, str(e) else: self.fail("did not catch expected OSError") @@ -1586,17 +1586,17 @@ def exists(env): env['XXX'] = copy.copy(input) try: env.Append(XXX = append) - except Exception, e: - if failed == 0: print - print " %s Append %s exception: %s" % \ - (repr(input), repr(append), e) + except Exception as e: + if failed == 0: print() + print(" %s Append %s exception: %s" % \ + (repr(input), repr(append), e)) failed = failed + 1 else: result = env['XXX'] if result != expect: - if failed == 0: print - print " %s Append %s => %s did not match %s" % \ - (repr(input), repr(append), repr(result), repr(expect)) + if failed == 0: print() + print(" %s Append %s => %s did not match %s" % \ + (repr(input), repr(append), repr(result), repr(expect))) failed = failed + 1 del cases[:3] assert failed == 0, "%d Append() cases failed" % failed @@ -1935,7 +1935,7 @@ def generate(env): assert x is None, x sub2_xxx_exe = test.workpath('sub2', 'xxx.exe') - os.chmod(sub2_xxx_exe, 0755) + os.chmod(sub2_xxx_exe, 0o755) env = self.TestEnvironment(ENV = { 'PATH' : [sub1, sub2] }) @@ -1943,7 +1943,7 @@ def generate(env): assert x == 'xxx.exe', x sub1_xxx_exe = test.workpath('sub1', 'xxx.exe') - os.chmod(sub1_xxx_exe, 0755) + os.chmod(sub1_xxx_exe, 0o755) x = env.Detect('xxx.exe') assert x == 'xxx.exe', x @@ -2258,17 +2258,17 @@ f5: \ env['XXX'] = copy.copy(input) try: env.Prepend(XXX = prepend) - except Exception, e: - if failed == 0: print - print " %s Prepend %s exception: %s" % \ - (repr(input), repr(prepend), e) + except Exception as e: + if failed == 0: print() + print(" %s Prepend %s exception: %s" % \ + (repr(input), repr(prepend), e)) failed = failed + 1 else: result = env['XXX'] if result != expect: - if failed == 0: print - print " %s Prepend %s => %s did not match %s" % \ - (repr(input), repr(prepend), repr(result), repr(expect)) + if failed == 0: print() + print(" %s Prepend %s => %s did not match %s" % \ + (repr(input), repr(prepend), repr(result), repr(expect))) failed = failed + 1 del cases[:3] assert failed == 0, "%d Prepend() cases failed" % failed @@ -2506,10 +2506,10 @@ def generate(env): os.mkdir(sub2_xxx_exe) test.write(sub3_xxx_exe, "\n") - os.chmod(sub3_xxx_exe, 0777) + os.chmod(sub3_xxx_exe, 0o777) test.write(sub4_xxx_exe, "\n") - os.chmod(sub4_xxx_exe, 0777) + os.chmod(sub4_xxx_exe, 0o777) env_path = os.environ['PATH'] diff --git a/src/engine/SCons/ErrorsTests.py b/src/engine/SCons/ErrorsTests.py index 9c8b925..97c9d55 100644 --- a/src/engine/SCons/ErrorsTests.py +++ b/src/engine/SCons/ErrorsTests.py @@ -35,7 +35,7 @@ class ErrorsTestCase(unittest.TestCase): raise SCons.Errors.BuildError( errstr = "foo", status=57, filename="file", exc_info=(1,2,3), node = "n", executor="e", action="a", command="c") - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: assert e.errstr == "foo" assert e.status == 57 assert e.exitstatus == 2, e.exitstatus @@ -50,7 +50,7 @@ class ErrorsTestCase(unittest.TestCase): try: raise SCons.Errors.BuildError("n", "foo", 57, 3, "file", "e", "a", "c", (1,2,3)) - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: assert e.errstr == "foo", e.errstr assert e.status == 57, e.status assert e.exitstatus == 3, e.exitstatus @@ -64,7 +64,7 @@ class ErrorsTestCase(unittest.TestCase): try: raise SCons.Errors.BuildError() - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: assert e.errstr == "Unknown error" assert e.status == 2 assert e.exitstatus == 2 @@ -80,21 +80,21 @@ class ErrorsTestCase(unittest.TestCase): """Test the InternalError exception.""" try: raise SCons.Errors.InternalError("test internal error") - except SCons.Errors.InternalError, e: + except SCons.Errors.InternalError as e: assert e.args == ("test internal error",) def test_UserError(self): """Test the UserError exception.""" try: raise SCons.Errors.UserError("test user error") - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert e.args == ("test user error",) def test_ExplicitExit(self): """Test the ExplicitExit exception.""" try: raise SCons.Errors.ExplicitExit("node") - except SCons.Errors.ExplicitExit, e: + except SCons.Errors.ExplicitExit as e: assert e.node == "node" if __name__ == "__main__": diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py index 6268984..3bc5bee 100644 --- a/src/engine/SCons/ExecutorTests.py +++ b/src/engine/SCons/ExecutorTests.py @@ -307,7 +307,7 @@ class ExecutorTestCase(unittest.TestCase): try: r = x.prepare() - except SCons.Errors.StopError, e: + except SCons.Errors.StopError as e: assert str(e) == "Source `s2' not found, needed by target `t1'.", e else: raise AssertionError("did not catch expected StopError: %s" % r) diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py index 184f5ba..226a34e 100644 --- a/src/engine/SCons/Job.py +++ b/src/engine/SCons/Job.py @@ -278,14 +278,14 @@ else: try: prev_size = threading.stack_size(stack_size*1024) - except AttributeError, e: + except AttributeError as e: # Only print a warning if the stack size has been # explicitly set. if not explicit_stack_size is None: msg = "Setting stack size is unsupported by this version of Python:\n " + \ e.args[0] SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg) - except ValueError, e: + except ValueError as e: msg = "Setting stack size failed:\n " + str(e) SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg) diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index e77aacf..9fe6851 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -143,7 +143,7 @@ class Counter(object): CounterList.append(self) def display(self): fmt = " %7d hits %7d misses %s()" - print fmt % (self.hit, self.miss, self.name) + print(fmt % (self.hit, self.miss, self.name)) def __cmp__(self, other): try: return cmp(self.name, other.name) @@ -215,7 +215,7 @@ class Memoizer(object): def Dump(title=None): if title: - print title + print(title) CounterList.sort() for counter in CounterList: counter.display() diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py index 9876c27..b6750e0 100644 --- a/src/engine/SCons/MemoizeTests.py +++ b/src/engine/SCons/MemoizeTests.py @@ -30,9 +30,7 @@ import SCons.Memoize -class FakeObject(object): - - __metaclass__ = SCons.Memoize.Memoized_Metaclass +class FakeObject(object, metaclass=SCons.Memoize.Memoized_Metaclass): memoizer_counters = [] diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index f31ca83..22dca1f 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -54,6 +54,7 @@ import SCons.Util import SCons.Warnings from SCons.Debug import Trace +import collections do_store_info = True print_duplicate = 0 @@ -550,7 +551,7 @@ class EntryProxy(SCons.Util.Proxy): except KeyError: try: attr = SCons.Util.Proxy.__getattr__(self, name) - except AttributeError, e: + except AttributeError as e: # Raise our own AttributeError subclass with an # overridden __str__() method that identifies the # name of the entry that caused the exception. @@ -1508,7 +1509,7 @@ class Dir(Base): This clears any cached information that is invalidated by changing the repository.""" - for node in self.entries.values(): + for node in list(self.entries.values()): if node != self.dir: if node != self and isinstance(node, Dir): node.__clearRepositoryCache(duplicate) @@ -2055,7 +2056,7 @@ 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() + node_names = [ v.name for k, v in list(dir.entries.items()) if k not in ('.', '..') ] names.extend(node_names) if not strings: @@ -2420,7 +2421,7 @@ class File(Base): fname = self.rfile().abspath try: contents = open(fname, "rb").read() - except EnvironmentError, e: + except EnvironmentError as e: if not e.filename: e.filename = fname raise @@ -2455,7 +2456,7 @@ class File(Base): try: cs = SCons.Util.MD5filesignature(fname, chunksize=SCons.Node.FS.File.md5_chunksize*1024) - except EnvironmentError, e: + except EnvironmentError as e: if not e.filename: e.filename = fname raise @@ -2793,7 +2794,7 @@ class File(Base): def _rmv_existing(self): self.clear_memoized_values() if print_duplicate: - print "dup: removing existing target %s"%self + print("dup: removing existing target %s"%self) e = Unlink(self, [], None) if isinstance(e, SCons.Errors.BuildError): raise e @@ -2817,7 +2818,7 @@ class File(Base): else: try: self._createDir() - except SCons.Errors.StopError, drive: + except SCons.Errors.StopError as drive: desc = "No drive `%s' for target `%s'." % (drive, self) raise SCons.Errors.StopError(desc) @@ -2835,7 +2836,7 @@ class File(Base): def do_duplicate(self, src): self._createDir() if print_duplicate: - print "dup: relinking variant '%s' from '%s'"%(self, src) + print("dup: relinking variant '%s' from '%s'"%(self, src)) Unlink(self, None, None) e = Link(self, src, None) if isinstance(e, SCons.Errors.BuildError): @@ -2870,7 +2871,7 @@ class File(Base): # The source file does not exist. Make sure no old # copy remains in the variant directory. if print_duplicate: - print "dup: no src for %s, unlinking old variant copy"%self + print("dup: no src for %s, unlinking old variant copy"%self) if Base.exists(self) or self.islink(): self.fs.unlink(self.path) # Return None explicitly because the Base.exists() call @@ -3196,10 +3197,10 @@ class FileFinder(object): except KeyError: pass - if verbose and not callable(verbose): + if verbose and not isinstance(verbose, collections.Callable): if not SCons.Util.is_String(verbose): verbose = "find_file" - _verbose = u' %s: ' % verbose + _verbose = ' %s: ' % verbose verbose = lambda s: sys.stdout.write(_verbose + s) filedir, filename = os.path.split(filename) diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index a60b8a4..e8442e9 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -20,7 +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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -567,13 +567,13 @@ class VariantDirTestCase(unittest.TestCase): dp = dnode.srcnode().path expect = os.path.normpath(srcnode_map.get(dir, dir)) if dp != expect: - print "Dir `%s' srcnode() `%s' != expected `%s'" % (dir, dp, expect) + print("Dir `%s' srcnode() `%s' != expected `%s'" % (dir, dp, expect)) errors = errors + 1 fp = fnode.srcnode().path expect = os.path.normpath(srcnode_map.get(f, f)) if fp != expect: - print "File `%s' srcnode() `%s' != expected `%s'" % (f, fp, expect) + print("File `%s' srcnode() `%s' != expected `%s'" % (f, fp, expect)) errors = errors + 1 for dir in dir_list: @@ -585,14 +585,14 @@ class VariantDirTestCase(unittest.TestCase): tp = t[0].path expect = os.path.normpath(alter_map.get(dir, dir)) if tp != expect: - print "Dir `%s' alter_targets() `%s' != expected `%s'" % (dir, tp, expect) + print("Dir `%s' alter_targets() `%s' != expected `%s'" % (dir, tp, expect)) errors = errors + 1 t, m = fnode.alter_targets() tp = t[0].path expect = os.path.normpath(alter_map.get(f, f)) if tp != expect: - print "File `%s' alter_targets() `%s' != expected `%s'" % (f, tp, expect) + print("File `%s' alter_targets() `%s' != expected `%s'" % (f, tp, expect)) errors = errors + 1 self.failIf(errors) @@ -1088,7 +1088,7 @@ class FSTestCase(_tempdirTestCase): try: f2 = fs.File(sep.join(['f1', 'f2']), directory = d1) - except TypeError, x: + except TypeError as x: assert str(x) == ("Tried to lookup File '%s' as a Dir." % d1_f1), x except: @@ -1096,7 +1096,7 @@ class FSTestCase(_tempdirTestCase): try: dir = fs.Dir(sep.join(['d1', 'f1'])) - except TypeError, x: + except TypeError as x: assert str(x) == ("Tried to lookup File '%s' as a Dir." % d1_f1), x except: @@ -1104,7 +1104,7 @@ class FSTestCase(_tempdirTestCase): try: f2 = fs.File('d1') - except TypeError, x: + except TypeError as x: assert str(x) == ("Tried to lookup Dir '%s' as a File." % 'd1'), x except: @@ -1305,7 +1305,7 @@ class FSTestCase(_tempdirTestCase): assert f1.get_contents() == "Foo\x1aBar", f1.get_contents() # This tests to make sure we can decode UTF-8 text files. - test_string = u"Foo\x1aBar" + test_string = "Foo\x1aBar" test.write("utf8_file", test_string.encode('utf-8')) f1 = fs.File(test.workpath("utf8_file")) assert eval('f1.get_text_contents() == u"Foo\x1aBar"'), \ @@ -1645,7 +1645,7 @@ class FSTestCase(_tempdirTestCase): def unc_workpath(dirs, test=test): import ntpath - x = apply(test.workpath, dirs) + x = test.workpath(*dirs) drive, path = ntpath.splitdrive(x) unc, path = ntpath.splitunc(path) path = strip_slash(path) @@ -1911,9 +1911,9 @@ class FSTestCase(_tempdirTestCase): del cases[:3] result = dir.rel_path(other) if result != expect: - if failed == 0: print + if failed == 0: print() fmt = " dir_path(%(dir)s, %(other)s) => '%(result)s' did not match '%(expect)s'" - print fmt % locals() + print(fmt % locals()) failed = failed + 1 assert failed == 0, "%d rel_path() cases failed" % failed @@ -2520,9 +2520,9 @@ class GlobTestCase(_tempdirTestCase): fmt = lambda n: n if r != result: import pprint - print "Glob(%s) expected:" % repr(input) + print("Glob(%s) expected:" % repr(input)) pprint.pprint(list(map(fmt, result))) - print "Glob(%s) got:" % repr(input) + print("Glob(%s) got:" % repr(input)) pprint.pprint(list(map(fmt, r))) self.fail() @@ -3621,7 +3621,7 @@ class SpecialAttrTestCase(unittest.TestCase): caught = None try: fs.Dir('ddd').get_subst_proxy().no_such_attr - except AttributeError, e: + except AttributeError as e: assert str(e) == "Dir instance 'ddd' has no attribute 'no_such_attr'", e caught = 1 assert caught, "did not catch expected AttributeError" @@ -3629,7 +3629,7 @@ class SpecialAttrTestCase(unittest.TestCase): caught = None try: fs.Entry('eee').get_subst_proxy().no_such_attr - except AttributeError, e: + except AttributeError as e: # Gets disambiguated to File instance by get_subst_proxy(). assert str(e) == "File instance 'eee' has no attribute 'no_such_attr'", e caught = 1 @@ -3638,7 +3638,7 @@ class SpecialAttrTestCase(unittest.TestCase): caught = None try: fs.File('fff').get_subst_proxy().no_such_attr - except AttributeError, e: + except AttributeError as e: assert str(e) == "File instance 'fff' has no attribute 'no_such_attr'", e caught = 1 assert caught, "did not catch expected AttributeError" diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 992284d..8f48d86 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -371,7 +371,7 @@ class Node(object): """ try: self.get_executor()(self, **kw) - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: e.node = self raise @@ -827,7 +827,7 @@ class Node(object): """Adds dependencies.""" try: self._add_child(self.depends, self.depends_set, depend) - except TypeError, e: + except TypeError as e: e = e.args[0] if SCons.Util.is_List(e): s = list(map(str, e)) @@ -844,7 +844,7 @@ class Node(object): """Adds dependencies to ignore.""" try: self._add_child(self.ignore, self.ignore_set, depend) - except TypeError, e: + except TypeError as e: e = e.args[0] if SCons.Util.is_List(e): s = list(map(str, e)) @@ -858,7 +858,7 @@ class Node(object): return try: self._add_child(self.sources, self.sources_set, source) - except TypeError, e: + except TypeError as e: e = e.args[0] if SCons.Util.is_List(e): s = list(map(str, e)) @@ -1197,8 +1197,8 @@ class Node(object): new_bkids = new.bsources + new.bdepends + new.bimplicit new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - osig = dict(zip(old_bkids, old_bkidsigs)) - nsig = dict(zip(new_bkids, new_bkidsigs)) + osig = dict(list(zip(old_bkids, old_bkidsigs))) + nsig = dict(list(zip(new_bkids, new_bkidsigs))) # The sources and dependencies we'll want to report are all stored # as relative paths to this target's directory, but we want to diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py index f6c8483..2544aec 100644 --- a/src/engine/SCons/Options/__init__.py +++ b/src/engine/SCons/Options/__init__.py @@ -33,11 +33,11 @@ and will then be removed entirely (some day). import SCons.Variables import SCons.Warnings -from BoolOption import BoolOption # okay -from EnumOption import EnumOption # okay -from ListOption import ListOption # naja -from PackageOption import PackageOption # naja -from PathOption import PathOption # okay +from .BoolOption import BoolOption # okay +from .EnumOption import EnumOption # okay +from .ListOption import ListOption # naja +from .PackageOption import PackageOption # naja +from .PathOption import PathOption # okay warned = False diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 81a49e7..6ef8b05 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -223,8 +223,8 @@ class TempFileMunge(object): # purity get in the way of just being helpful, so we'll # reach into SCons.Action directly. if SCons.Action.print_actions: - print("Using tempfile "+native_tmp+" for command line:\n"+ - str(cmd[0]) + " " + " ".join(args)) + print(("Using tempfile "+native_tmp+" for command line:\n"+ + 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 0229112..f6853b5 100644 --- a/src/engine/SCons/Platform/aix.py +++ b/src/engine/SCons/Platform/aix.py @@ -34,7 +34,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os -import posix +from . import posix def get_xlc(env, xlc=None, xlc_r=None, packages=[]): # Use the AIX package installer tool lslpp to figure out where a diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py index a012682..e7c8b8a 100644 --- a/src/engine/SCons/Platform/cygwin.py +++ b/src/engine/SCons/Platform/cygwin.py @@ -32,7 +32,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import posix +from . import posix from SCons.Platform import TempFileMunge def generate(env): diff --git a/src/engine/SCons/Platform/darwin.py b/src/engine/SCons/Platform/darwin.py index 005673b..1cf4aeb 100644 --- a/src/engine/SCons/Platform/darwin.py +++ b/src/engine/SCons/Platform/darwin.py @@ -32,7 +32,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import posix +from . import posix import os def generate(env): diff --git a/src/engine/SCons/Platform/hpux.py b/src/engine/SCons/Platform/hpux.py index 43d284b..0e0bbcf 100644 --- a/src/engine/SCons/Platform/hpux.py +++ b/src/engine/SCons/Platform/hpux.py @@ -32,7 +32,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import posix +from . import posix def generate(env): posix.generate(env) diff --git a/src/engine/SCons/Platform/irix.py b/src/engine/SCons/Platform/irix.py index 2baee0b..2e5f217 100644 --- a/src/engine/SCons/Platform/irix.py +++ b/src/engine/SCons/Platform/irix.py @@ -32,7 +32,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import posix +from . import posix def generate(env): posix.generate(env) diff --git a/src/engine/SCons/Platform/os2.py b/src/engine/SCons/Platform/os2.py index 0fa4553..5ca26bc 100644 --- a/src/engine/SCons/Platform/os2.py +++ b/src/engine/SCons/Platform/os2.py @@ -31,7 +31,7 @@ selection method. # __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import win32 +from . import win32 def generate(env): if 'ENV' not in env: diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index ece48d7..d1f6c78 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -77,7 +77,7 @@ def exec_fork(l, env): exitval = 127 try: os.execvpe(l[0], l, env) - except OSError, e: + except OSError as e: exitval = exitvalmap.get(e[0], e[0]) sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) @@ -92,7 +92,7 @@ def _get_env_command(sh, escape, cmd, args, env): s = ' '.join(args) if env: l = ['env', '-'] + \ - [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \ + [escape(t[0])+'='+escape(t[1]) for t in list(env.items())] + \ [sh, '-c', escape(s)] s = ' '.join(l) return s @@ -125,7 +125,8 @@ def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr): else: #sys.__stderr__.write( "str(stderr) = %s\n" % str ) stderr.write(str) - except select.error, (_errno, _strerror): + except select.error as xxx_todo_changeme: + (_errno, _strerror) = xxx_todo_changeme.args if _errno != errno.EINTR: raise @@ -164,7 +165,7 @@ def exec_piped_fork(l, env, stdout, stderr): exitval = 127 try: os.execvpe(l[0], l, env) - except OSError, e: + except OSError as e: exitval = exitvalmap.get(e[0], e[0]) stderr.write("scons: %s: %s\n" % (l[0], e[1])) os._exit(exitval) diff --git a/src/engine/SCons/Platform/sunos.py b/src/engine/SCons/Platform/sunos.py index d23d65c..057fddf 100644 --- a/src/engine/SCons/Platform/sunos.py +++ b/src/engine/SCons/Platform/sunos.py @@ -32,7 +32,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import posix +from . import posix def generate(env): posix.generate(env) diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 5f20685..879817d 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -155,7 +155,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): try: args = [sh, '/C', escape(' '.join(args)) ] ret = spawnve(os.P_WAIT, sh, args, env) - except OSError, e: + except OSError as e: # catch any error try: ret = exitvalmap[e[0]] @@ -183,7 +183,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr): def exec_spawn(l, env): try: result = spawnve(os.P_WAIT, l[0], l, env) - except OSError, e: + except OSError as e: try: result = exitvalmap[e[0]] sys.stderr.write("scons: %s: %s\n" % (l[0], e[1])) diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index f3a3545..987f88d 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -118,7 +118,7 @@ def CreateConfigHBuilder(env): _stringConfigH) sconfigHBld = SCons.Builder.Builder(action=action) env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} ) - for k in _ac_config_hs.keys(): + for k in list(_ac_config_hs.keys()): env.SConfigHBuilder(k, env.Value(_ac_config_hs[k])) class SConfWarning(SCons.Warnings.Warning): @@ -239,7 +239,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): # Earlier versions of Python don't have sys.excepthook... def excepthook(type, value, tb): traceback.print_tb(tb) - print type, value + print(type, value) excepthook(*self.exc_info()) return SCons.Taskmaster.Task.failed(self) @@ -318,7 +318,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): env_decider=env.decide_source): env_decider(dependency, target, prev_ni) return True - if env.decide_source.func_code is not force_build.func_code: + if env.decide_source.__code__ is not force_build.__code__: env.Decider(force_build) env['PSTDOUT'] = env['PSTDERR'] = s try: @@ -332,7 +332,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): except SystemExit: exc_value = sys.exc_info()[1] raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code) - except Exception, e: + except Exception as e: for t in self.targets: binfo = t.get_binfo() binfo.__class__ = SConfBuildInfo @@ -652,7 +652,7 @@ class SConfBase(object): """Adds all the tests given in the tests dictionary to this SConf instance """ - for name in tests.keys(): + for name in list(tests.keys()): self.AddTest(name, tests[name]) def _createDir( self, node ): diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index e604886..ba524fd 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -60,7 +60,7 @@ class SConfTestCase(unittest.TestCase): # We try to reset scons' state (including all global variables) import SCons.SConsign SCons.SConsign.write() # simulate normal scons-finish - for n in sys.modules.keys(): + for n in list(sys.modules.keys()): if n.split('.')[0] == 'SCons' and n[:12] != 'SCons.compat': m = sys.modules[n] if isinstance(m, ModuleType): diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index 6555fcb..5ce61be 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -84,7 +84,7 @@ def Get_DataBase(dir): DB_sync_list.append(db) return db, "c" except TypeError: - print "DataBase =", DataBase + print("DataBase =", DataBase) raise def Reset(): @@ -172,7 +172,7 @@ class Base(object): pass def merge(self): - for key, node in self.to_be_merged.items(): + for key, node in list(self.to_be_merged.items()): entry = node.get_stored_info() try: ninfo = entry.ninfo @@ -215,10 +215,10 @@ class DB(Base): raise TypeError except KeyboardInterrupt: raise - except Exception, e: + except Exception as e: SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.tpath, e)) - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_from_sconsign(dir, key) if mode == "r": @@ -245,7 +245,7 @@ class DB(Base): # the Repository; we only write to our own .sconsign file, # not to .sconsign files in Repositories. path = normcase(self.dir.path) - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_to_sconsign() db[path] = pickle.dumps(self.entries, 1) @@ -274,7 +274,7 @@ class Dir(Base): raise TypeError if dir: - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_from_sconsign(dir, key) class DirFile(Dir): @@ -333,14 +333,14 @@ class DirFile(Dir): fname = self.sconsign except IOError: return - for key, entry in self.entries.items(): + for key, entry in list(self.entries.items()): entry.convert_to_sconsign() pickle.dump(self.entries, file, 1) file.close() if fname != self.sconsign: try: mode = os.stat(self.sconsign)[0] - os.chmod(self.sconsign, 0666) + os.chmod(self.sconsign, 0o666) os.unlink(self.sconsign) except (IOError, OSError): # Try to carry on in the face of either OSError diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index 3311a09..74b01a4 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -59,7 +59,7 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): def read_file(self, file): try: fp = open(str(file.rfile())) - except EnvironmentError, e: + except EnvironmentError as e: self.missing.append((file, self.current_file)) return '' else: diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py index 1b55130..5339ab2 100644 --- a/src/engine/SCons/Scanner/Fortran.py +++ b/src/engine/SCons/Scanner/Fortran.py @@ -35,6 +35,7 @@ import SCons.Node.FS import SCons.Scanner import SCons.Util import SCons.Warnings +import collections class F90Scanner(SCons.Scanner.Classic): """ @@ -109,7 +110,7 @@ class F90Scanner(SCons.Scanner.Classic): # is actually found in a Repository or locally. nodes = [] source_dir = node.get_dir() - if callable(path): + if isinstance(path, collections.Callable): path = path() for dep in mods_and_includes: n, i = self.find_include(dep, source_dir, path) diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py index 2cb1ed5..1e0fea1 100644 --- a/src/engine/SCons/Scanner/LaTeX.py +++ b/src/engine/SCons/Scanner/LaTeX.py @@ -200,14 +200,14 @@ class LaTeX(SCons.Scanner.Base): """ def __init__(self, dictionary): self.dictionary = {} - for k,n in dictionary.items(): + for k,n in list(dictionary.items()): self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n), FindENVPathDirs(n) ) def __call__(self, env, dir=None, target=None, source=None, argument=None): di = {} - for k,(c,cENV) in self.dictionary.items(): + for k,(c,cENV) in list(self.dictionary.items()): di[k] = ( c(env, dir=None, target=None, source=None, argument=None) , cENV(env, dir=None, target=None, source=None, diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 49e93a5..6e2da21 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -27,6 +27,7 @@ import SCons.Node import SCons.Node.FS import SCons.Scanner import SCons.Util +import collections # global, set by --debug=findlibs print_find_libs = None @@ -76,7 +77,7 @@ def scan(node, env, libpath = ()): result = [] - if callable(libpath): + if isinstance(libpath, collections.Callable): libpath = libpath() find_file = SCons.Node.FS.find_file diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py index 411e035..f564c91 100644 --- a/src/engine/SCons/Scanner/ProgTests.py +++ b/src/engine/SCons/Scanner/ProgTests.py @@ -230,7 +230,7 @@ def suite(): suite.addTest(ProgramScannerTestCase6()) suite.addTest(ProgramScannerTestCase7()) suite.addTest(ProgramScannerTestCase8()) - try: unicode + try: str except NameError: pass else: code = """if 1: @@ -245,7 +245,7 @@ def suite(): assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps) suite.addTest(ProgramScannerTestCase4()) \n""" - exec code + exec(code) return suite if __name__ == "__main__": diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py index ee26922..5a4639d 100644 --- a/src/engine/SCons/Scanner/ScannerTests.py +++ b/src/engine/SCons/Scanner/ScannerTests.py @@ -569,7 +569,7 @@ class ClassicCPPTestCase(unittest.TestCase): assert n == 'path/bbb', n assert i == 'bbb', i - n, i = s.find_include(('<', u'ccc'), 'foo', ('path',)) + n, i = s.find_include(('<', 'ccc'), 'foo', ('path',)) assert n == 'path/ccc', n assert i == 'ccc', i diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index 562a361..6ec8df9 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -33,6 +33,7 @@ import re import SCons.Node.FS import SCons.Util +import collections class _Null(object): @@ -178,7 +179,7 @@ class Base(object): self.node_class = node_class self.node_factory = node_factory self.scan_check = scan_check - if callable(recursive): + if isinstance(recursive, collections.Callable): self.recurse_nodes = recursive elif recursive: self.recurse_nodes = self._recurse_all_nodes @@ -369,7 +370,7 @@ class Classic(Current): # is actually found in a Repository or locally. nodes = [] source_dir = node.get_dir() - if callable(path): + if isinstance(path, collections.Callable): path = path() for include in includes: n, i = self.find_include(include, source_dir, path) diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index ffb5096..87fe1cf 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -120,7 +120,7 @@ class SConsInteractiveCmd(cmd.Cmd): def __init__(self, **kw): cmd.Cmd.__init__(self) - for key, val in kw.items(): + for key, val in list(kw.items()): setattr(self, key, val) if sys.platform == 'win32': @@ -129,12 +129,12 @@ class SConsInteractiveCmd(cmd.Cmd): self.shell_variable = 'SHELL' def default(self, argv): - print "*** Unknown command: %s" % argv[0] + print("*** Unknown command: %s" % argv[0]) def onecmd(self, line): line = line.strip() if not line: - print self.lastcmd + print(self.lastcmd) return self.emptyline() self.lastcmd = line if line[0] == '!': @@ -249,7 +249,7 @@ class SConsInteractiveCmd(cmd.Cmd): while n: n = walker.get_next() - for node in seen_nodes.keys(): + for node in list(seen_nodes.keys()): # Call node.clear() to clear most of the state node.clear() # node.clear() doesn't reset node.state, so call @@ -274,7 +274,7 @@ class SConsInteractiveCmd(cmd.Cmd): return self.do_build(['build', '--clean'] + argv[1:]) def do_EOF(self, argv): - print + print() self.do_exit(argv) def _do_one_help(self, arg): @@ -357,7 +357,7 @@ class SConsInteractiveCmd(cmd.Cmd): # Doing the right thing with an argument list currently # requires different shell= values on Windows and Linux. p = subprocess.Popen(argv, shell=(sys.platform=='win32')) - except EnvironmentError, e: + except EnvironmentError as e: sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror)) else: p.wait() diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 837c103..9a52937 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -68,6 +68,7 @@ import SCons.Util import SCons.Warnings import SCons.Script.Interactive +import collections def fetch_win32_parallel_msg(): # A subsidiary function that exists solely to isolate this import @@ -104,7 +105,7 @@ class Progressor(object): self.interval = interval self.overwrite = overwrite - if callable(obj): + if isinstance(obj, collections.Callable): self.func = obj elif SCons.Util.is_List(obj): self.func = self.spinner @@ -224,7 +225,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): self.exception_set() self.do_failed() else: - print "scons: Nothing to be done for `%s'." % t + print("scons: Nothing to be done for `%s'." % t) SCons.Taskmaster.OutOfDateTask.executed(self) else: SCons.Taskmaster.OutOfDateTask.executed(self) @@ -290,8 +291,8 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): if self.options.debug_includes: tree = t.render_include_tree() if tree: - print - print tree + print() + print(tree) SCons.Taskmaster.OutOfDateTask.postprocess(self) def make_ready(self): @@ -326,10 +327,10 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): else: errstr = "Path '%s' exists but isn't a file or directory." raise SCons.Errors.UserError(errstr % (pathstr)) - except SCons.Errors.UserError, e: - print e - except (IOError, OSError), e: - print "scons: Could not remove '%s':" % pathstr, e.strerror + except SCons.Errors.UserError as e: + print(e) + except (IOError, OSError) as e: + print("scons: Could not remove '%s':" % pathstr, e.strerror) def show(self): target = self.targets[0] @@ -348,13 +349,13 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): for t in self.targets: try: removed = t.remove() - except OSError, e: + except OSError as e: # An OSError may indicate something like a permissions # issue, an IOError would indicate something like # the file not existing. In either case, print a # message and keep going to try to remove as many # targets aa possible. - print "scons: Could not remove '%s':" % str(t), e.strerror + print("scons: Could not remove '%s':" % str(t), e.strerror) else: if removed: display("Removed " + str(t)) @@ -595,7 +596,7 @@ def _scons_internal_error(): """Handle all errors but user errors. Print out a message telling the user what to do in this case and print a normal trace. """ - print 'internal error' + print('internal error') traceback.print_exc() sys.exit(2) @@ -707,7 +708,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): # the error checking makes it longer. try: m = sys.modules['SCons.Script'] - except Exception, e: + except Exception as e: fmt = 'cannot import site_init.py: missing SCons.Script module %s' raise SCons.Errors.InternalError(fmt % repr(e)) try: @@ -715,15 +716,15 @@ def _load_site_scons_dir(topdir, site_dir_name=None): modname = os.path.basename(pathname)[:-len(sfx)] site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} re_special = re.compile("__[^_]+__") - for k in m.__dict__.keys(): + for k in list(m.__dict__.keys()): if not re_special.match(k): site_m[k] = m.__dict__[k] # This is the magic. - exec fp in site_m + exec(fp, site_m) except KeyboardInterrupt: raise - except Exception, e: + except Exception as e: fmt = '*** Error loading site_init file %s:\n' sys.stderr.write(fmt % repr(site_init_file)) raise @@ -733,7 +734,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): m.__dict__[k] = site_m[k] except KeyboardInterrupt: raise - except ImportError, e: + except ImportError as e: fmt = '*** cannot import site init file %s:\n' sys.stderr.write(fmt % repr(site_init_file)) raise @@ -785,7 +786,7 @@ def _load_all_site_scons_dirs(topdir, verbose=None): dirs=sysdirs + [topdir] for d in dirs: if verbose: # this is used by unit tests. - print "Loading site dir ", d + print("Loading site dir ", d) _load_site_scons_dir(d) def test_load_all_site_scons_dirs(d): @@ -977,7 +978,7 @@ def _main(parser): try: for script in scripts: SCons.Script._SConscript._SConscript(fs, script) - except SCons.Errors.StopError, e: + except SCons.Errors.StopError as e: # We had problems reading an SConscript file, such as it # couldn't be copied in to the VariantDir. Since we're just # reading SConscript files and haven't started building @@ -1034,8 +1035,8 @@ def _main(parser): # SConscript files. Give them the options usage. raise SConsPrintHelpException else: - print help_text - print "Use scons -H for help about command-line options." + print(help_text) + print("Use scons -H for help about command-line options.") exit_status = 0 return @@ -1298,7 +1299,7 @@ def _exec_main(parser, values): prof = Profile() try: prof.runcall(_main, parser) - except SConsPrintHelpException, e: + except SConsPrintHelpException as e: prof.dump_stats(options.profile_file) raise e except SystemExit: @@ -1334,7 +1335,7 @@ def main(): parts.append("__COPYRIGHT__") version = ''.join(parts) - import SConsOptions + from . import SConsOptions parser = SConsOptions.Parser(version) values = SConsOptions.SConsValues(parser.get_default_values()) @@ -1342,22 +1343,22 @@ def main(): try: _exec_main(parser, values) - except SystemExit, s: + except SystemExit as s: if s: exit_status = s except KeyboardInterrupt: print("scons: Build interrupted.") sys.exit(2) - except SyntaxError, e: + except SyntaxError as e: _scons_syntax_error(e) except SCons.Errors.InternalError: _scons_internal_error() - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: _scons_user_error(e) except SConsPrintHelpException: parser.print_help() exit_status = 0 - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: exit_status = e.exitstatus except: # An exception here is likely a builtin Python exception Python @@ -1393,10 +1394,10 @@ def main(): else: ct = last_command_end - first_command_start scons_time = total_time - sconscript_time - ct - print "Total build time: %f seconds"%total_time - print "Total SConscript file execution time: %f seconds"%sconscript_time - print "Total SCons execution time: %f seconds"%scons_time - print "Total command execution time: %f seconds"%ct + print("Total build time: %f seconds"%total_time) + print("Total SConscript file execution time: %f seconds"%sconscript_time) + print("Total SCons execution time: %f seconds"%scons_time) + print("Total command execution time: %f seconds"%ct) sys.exit(exit_status) diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 645ab11..559db97 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -161,7 +161,7 @@ class SConsValues(optparse.Values): elif name == 'diskcheck': try: value = diskcheck_convert(value) - except ValueError, v: + except ValueError as v: raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v) if 'diskcheck' not in self.__dict__: # No --diskcheck= option was specified on the command line. @@ -611,7 +611,7 @@ def Parser(version): deprecated_debug_options=deprecated_debug_options): if value in debug_options: parser.values.debug.append(value) - elif value in deprecated_debug_options.keys(): + elif value in list(deprecated_debug_options.keys()): parser.values.debug.append(value) try: parser.values.delayed_warnings @@ -635,7 +635,7 @@ def Parser(version): def opt_diskcheck(option, opt, value, parser): try: diskcheck_value = diskcheck_convert(value) - except ValueError, e: + except ValueError as e: raise OptionValueError("`%s' is not a valid diskcheck type" % e) setattr(parser.values, option.dest, diskcheck_value) @@ -802,7 +802,7 @@ def Parser(version): tree_options = ["all", "derived", "prune", "status"] def opt_tree(option, opt, value, parser, tree_options=tree_options): - import Main + from . import Main tp = Main.TreePrinter() for o in value.split(','): if o == 'all': diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index bd515d2..fefffef 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -26,7 +26,7 @@ files. # 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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -113,7 +113,7 @@ def compute_exports(exports): retval[export] = loc[export] except KeyError: retval[export] = glob[export] - except KeyError, x: + except KeyError as x: raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x) return retval @@ -145,7 +145,7 @@ def Return(*vars, **kw): for var in fvars: for v in var.split(): retval.append(call_stack[-1].globals[v]) - except KeyError, x: + except KeyError as x: raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x) if len(retval) == 1: @@ -174,7 +174,7 @@ def _SConscript(fs, *files, **kw): try: SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1 if fn == "-": - exec sys.stdin in call_stack[-1].globals + exec(sys.stdin, call_stack[-1].globals) else: if isinstance(fn, SCons.Node.Node): f = fn @@ -257,7 +257,7 @@ def _SConscript(fs, *files, **kw): pass try: try: - exec _file_ in call_stack[-1].globals + exec(_file_, call_stack[-1].globals) except SConscriptReturn: pass finally: @@ -282,7 +282,7 @@ def _SConscript(fs, *files, **kw): rdir._create() # Make sure there's a directory there. try: os.chdir(rdir.get_abspath()) - except OSError, e: + except OSError as e: # We still couldn't chdir there, so raise the error, # but only if actions are being executed. # @@ -467,15 +467,15 @@ class SConsEnvironment(SCons.Environment.Base): scons_ver_string = '%d.%d.%d' % (major, minor, revision) else: scons_ver_string = '%d.%d' % (major, minor) - print "SCons %s or greater required, but you have SCons %s" % \ - (scons_ver_string, SCons.__version__) + print("SCons %s or greater required, but you have SCons %s" % \ + (scons_ver_string, SCons.__version__)) sys.exit(2) def EnsurePythonVersion(self, major, minor): """Exit abnormally if the Python version is not late enough.""" if sys.version_info < (major, minor): v = sys.version.split()[0] - print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v) + print("Python %d.%d or greater required, but you have Python %s" %(major,minor,v)) sys.exit(2) def Exit(self, value=0): @@ -514,7 +514,7 @@ class SConsEnvironment(SCons.Environment.Base): globals[v] = exports[v] else: globals[v] = global_exports[v] - except KeyError,x: + except KeyError as x: raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x) def SConscript(self, *ls, **kw): @@ -529,7 +529,7 @@ class SConsEnvironment(SCons.Environment.Base): return x ls = list(map(subst_element, ls)) subst_kw = {} - for key, val in kw.items(): + for key, val in list(kw.items()): if SCons.Util.is_String(val): val = self.subst(val) elif SCons.Util.is_List(val): diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index bb7b632..9f2837c 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -66,7 +66,7 @@ if "--debug=memoizer" in _args: except SCons.Warnings.Warning: # Some warning was thrown. Arrange for it to be displayed # or not after warnings are configured. - import Main + from . import Main exc_type, exc_value, tb = sys.exc_info() Main.delayed_warnings.append((exc_type, exc_value)) del _args @@ -85,7 +85,7 @@ import SCons.Util import SCons.Variables import SCons.Defaults -import Main +from . import Main main = Main.main @@ -128,7 +128,7 @@ GetBuildFailures = Main.GetBuildFailures #repositories = Main.repositories # -import SConscript +from . import SConscript _SConscript = SConscript call_stack = _SConscript.call_stack @@ -364,7 +364,7 @@ GlobalDefaultBuilders = [ ] for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders: - exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name)) + exec("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))) del name # There are a handful of variables that used to live in the diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index 98097dc..cca9bbc 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -438,7 +438,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ s = eval(key, self.gvars, lvars) except KeyboardInterrupt: raise - except Exception, e: + except Exception as e: if e.__class__ in AllowableExceptions: return '' raise_exception(e, lvars['TARGETS'], s) @@ -472,7 +472,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): return conv(substitute(l, lvars)) return list(map(func, s)) - elif callable(s): + elif isinstance(s, collections.Callable): try: s = s(target=lvars['TARGETS'], source=lvars['SOURCES'], @@ -653,7 +653,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv s = eval(key, self.gvars, lvars) except KeyboardInterrupt: raise - except Exception, e: + except Exception as e: if e.__class__ in AllowableExceptions: return raise_exception(e, lvars['TARGETS'], s) @@ -681,7 +681,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv for a in s: self.substitute(a, lvars, 1) self.next_word() - elif callable(s): + elif isinstance(s, collections.Callable): try: s = s(target=lvars['TARGETS'], source=lvars['SOURCES'], diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py index 420fd73..da21020 100644 --- a/src/engine/SCons/SubstTests.py +++ b/src/engine/SCons/SubstTests.py @@ -241,14 +241,14 @@ class SubstTestCase(unittest.TestCase): expect = convert(expect) try: result = function(input, env, **kwargs) - except Exception, e: + except Exception as e: fmt = " input %s generated %s (%s)" - print fmt % (repr(input), e.__class__.__name__, repr(e)) + print(fmt % (repr(input), e.__class__.__name__, repr(e))) failed = failed + 1 else: if result != expect: - if failed == 0: print - print " input %s => %s did not match %s" % (repr(input), repr(result), repr(expect)) + if failed == 0: print() + print(" input %s => %s did not match %s" % (repr(input), repr(result), repr(expect))) failed = failed + 1 del cases[:2] fmt = "%d %s() cases failed" @@ -460,18 +460,18 @@ class scons_subst_TestCase(SubstTestCase): input, eraw, ecmd, esig = subst_cases[:4] result = scons_subst(input, env, mode=SUBST_RAW, gvars=gvars) if result != eraw: - if failed == 0: print - print " input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw)) + if failed == 0: print() + print(" input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw))) failed = failed + 1 result = scons_subst(input, env, mode=SUBST_CMD, gvars=gvars) if result != ecmd: - if failed == 0: print - print " input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd)) + if failed == 0: print() + print(" input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd))) failed = failed + 1 result = scons_subst(input, env, mode=SUBST_SIG, gvars=gvars) if result != esig: - if failed == 0: print - print " input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig)) + if failed == 0: print() + print(" input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig))) failed = failed + 1 del subst_cases[:4] assert failed == 0, "%d subst() mode cases failed" % failed @@ -514,7 +514,7 @@ class scons_subst_TestCase(SubstTestCase): class Foo(object): pass scons_subst('${foo.bar}', env, gvars={'foo':Foo()}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ "AttributeError `bar' trying to evaluate `${foo.bar}'", "AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'", @@ -530,7 +530,7 @@ class scons_subst_TestCase(SubstTestCase): env = DummyEnv(self.loc) try: scons_subst('$foo.bar.3.0', env) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ # Python 2.3, 2.4 "SyntaxError `invalid syntax (line 1)' trying to evaluate `$foo.bar.3.0'", @@ -546,7 +546,7 @@ class scons_subst_TestCase(SubstTestCase): env = DummyEnv(self.loc) try: scons_subst("${NONE[2]}", env, gvars={'NONE':None}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ # Python 2.3, 2.4 "TypeError `unsubscriptable object' trying to evaluate `${NONE[2]}'", @@ -565,7 +565,7 @@ class scons_subst_TestCase(SubstTestCase): def func(a, b, c): pass scons_subst("${func(1)}", env, gvars={'func':func}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ # Python 2.3, 2.4, 2.5 "TypeError `func() takes exactly 3 arguments (1 given)' trying to evaluate `${func(1)}'" @@ -946,18 +946,18 @@ class scons_subst_list_TestCase(SubstTestCase): input, eraw, ecmd, esig = subst_list_cases[:4] result = scons_subst_list(input, env, mode=SUBST_RAW, gvars=gvars) if result != eraw: - if failed == 0: print - print " input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw)) + if failed == 0: print() + print(" input %s => RAW %s did not match %s" % (repr(input), repr(result), repr(eraw))) failed = failed + 1 result = scons_subst_list(input, env, mode=SUBST_CMD, gvars=gvars) if result != ecmd: - if failed == 0: print - print " input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd)) + if failed == 0: print() + print(" input %s => CMD %s did not match %s" % (repr(input), repr(result), repr(ecmd))) failed = failed + 1 result = scons_subst_list(input, env, mode=SUBST_SIG, gvars=gvars) if result != esig: - if failed == 0: print - print " input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig)) + if failed == 0: print() + print(" input %s => SIG %s did not match %s" % (repr(input), repr(result), repr(esig))) failed = failed + 1 del subst_list_cases[:4] assert failed == 0, "%d subst() mode cases failed" % failed @@ -969,7 +969,7 @@ class scons_subst_list_TestCase(SubstTestCase): class Foo(object): pass scons_subst_list('${foo.bar}', env, gvars={'foo':Foo()}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ "AttributeError `bar' trying to evaluate `${foo.bar}'", "AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'", @@ -985,7 +985,7 @@ class scons_subst_list_TestCase(SubstTestCase): env = DummyEnv() try: scons_subst_list('$foo.bar.3.0', env) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = [ "SyntaxError `invalid syntax' trying to evaluate `$foo.bar.3.0'", "SyntaxError `invalid syntax (line 1)' trying to evaluate `$foo.bar.3.0'", @@ -1093,8 +1093,8 @@ class scons_subst_once_TestCase(unittest.TestCase): input, key, expect = cases[:3] result = scons_subst_once(input, env, key) if result != expect: - if failed == 0: print - print " input %s (%s) => %s did not match %s" % (repr(input), repr(key), repr(result), repr(expect)) + if failed == 0: print() + print(" input %s (%s) => %s did not match %s" % (repr(input), repr(key), repr(result), repr(expect))) failed = failed + 1 del cases[:3] assert failed == 0, "%d subst() cases failed" % failed diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 64ab84d..54d04a8 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -107,7 +107,7 @@ fmt = "%(considered)3d "\ def dump_stats(): for n in sorted(StatsNodes, key=lambda a: str(a)): - print (fmt % n.stats.__dict__) + str(n) + print((fmt % n.stats.__dict__) + str(n)) @@ -164,7 +164,7 @@ class Task(object): """ global print_prepare T = self.tm.trace - if T: T.write(self.trace_message(u'Task.prepare()', self.node)) + if T: T.write(self.trace_message('Task.prepare()', self.node)) # Now that it's the appropriate time, give the TaskMaster a # chance to raise any exceptions it encountered while preparing @@ -189,13 +189,13 @@ class Task(object): executor.prepare() for t in executor.get_action_targets(): if print_prepare: - print "Preparing target %s..."%t + print("Preparing target %s..."%t) for s in t.side_effects: - print "...with side-effect %s..."%s + print("...with side-effect %s..."%s) t.prepare() for s in t.side_effects: if print_prepare: - print "...Preparing side-effect %s..."%s + print("...Preparing side-effect %s..."%s) s.prepare() def get_target(self): @@ -224,7 +224,7 @@ class Task(object): prepare(), executed() or failed(). """ T = self.tm.trace - if T: T.write(self.trace_message(u'Task.execute()', self.node)) + if T: T.write(self.trace_message('Task.execute()', self.node)) try: cached_targets = [] @@ -254,7 +254,7 @@ class Task(object): raise except SCons.Errors.BuildError: raise - except Exception, e: + except Exception as e: buildError = SCons.Errors.convert_to_BuildError(e) buildError.node = self.targets[0] buildError.exc_info = sys.exc_info() @@ -383,7 +383,7 @@ class Task(object): This is the default behavior for building only what's necessary. """ T = self.tm.trace - if T: T.write(self.trace_message(u'Task.make_ready_current()', + if T: T.write(self.trace_message('Task.make_ready_current()', self.node)) self.out_of_date = [] @@ -393,7 +393,7 @@ class Task(object): t.disambiguate().make_ready() is_up_to_date = not t.has_builder() or \ (not t.always_build and t.is_up_to_date()) - except EnvironmentError, e: + except EnvironmentError as e: raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename) if not is_up_to_date: @@ -428,7 +428,7 @@ class Task(object): that can be put back on the candidates list. """ T = self.tm.trace - if T: T.write(self.trace_message(u'Task.postprocess()', self.node)) + if T: T.write(self.trace_message('Task.postprocess()', self.node)) # We may have built multiple targets, some of which may have # common parents waiting for this build. Count up how many @@ -445,7 +445,7 @@ class Task(object): # A node can only be in the pending_children set if it has # some waiting_parents. if t.waiting_parents: - if T: T.write(self.trace_message(u'Task.postprocess()', + if T: T.write(self.trace_message('Task.postprocess()', t, 'removing')) pending_children.discard(t) @@ -462,9 +462,9 @@ class Task(object): if p.ref_count == 0: self.tm.candidates.append(p) - for p, subtract in parents.items(): + for p, subtract in list(parents.items()): p.ref_count = p.ref_count - subtract - if T: T.write(self.trace_message(u'Task.postprocess()', + if T: T.write(self.trace_message('Task.postprocess()', p, 'adjusted parent ref count')) if p.ref_count == 0: @@ -524,7 +524,7 @@ class Task(object): except ValueError: exc_type, exc_value = exc exc_traceback = None - raise exc_type, exc_value, exc_traceback + raise exc_type(exc_value).with_traceback(exc_traceback) class AlwaysTask(Task): def needs_execute(self): @@ -748,12 +748,12 @@ class Taskmaster(object): self.ready_exc = None T = self.trace - if T: T.write(u'\n' + self.trace_message('Looking for a node to evaluate')) + if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) while True: node = self.next_candidate() if node is None: - if T: T.write(self.trace_message('No candidate anymore.') + u'\n') + if T: T.write(self.trace_message('No candidate anymore.') + '\n') return None node = node.disambiguate() @@ -776,7 +776,7 @@ class Taskmaster(object): else: S = None - if T: T.write(self.trace_message(u' Considering node %s and its children:' % self.trace_node(node))) + if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node))) if state == NODE_NO_STATE: # Mark this node as being on the execution stack: @@ -784,7 +784,7 @@ class Taskmaster(object): elif state > NODE_PENDING: # Skip this node if it has already been evaluated: if S: S.already_handled = S.already_handled + 1 - if T: T.write(self.trace_message(u' already handled (executed)')) + if T: T.write(self.trace_message(' already handled (executed)')) continue executor = node.get_executor() @@ -797,7 +797,7 @@ class Taskmaster(object): self.ready_exc = (SCons.Errors.ExplicitExit, e) if T: T.write(self.trace_message(' SystemExit')) return node - except Exception, e: + except Exception as e: # We had a problem just trying to figure out the # children (like a child couldn't be linked in to a # VariantDir, or a Scanner threw something). Arrange to @@ -815,7 +815,7 @@ class Taskmaster(object): for child in chain(executor.get_all_prerequisites(), children): childstate = child.get_state() - if T: T.write(self.trace_message(u' ' + self.trace_node(child))) + if T: T.write(self.trace_message(' ' + self.trace_node(child))) if childstate == NODE_NO_STATE: children_not_visited.append(child) @@ -874,7 +874,7 @@ class Taskmaster(object): # count so we can be put back on the list for # re-evaluation when they've all finished. node.ref_count = node.ref_count + child.add_to_waiting_parents(node) - if T: T.write(self.trace_message(u' adjusted ref count: %s, child %s' % + if T: T.write(self.trace_message(' adjusted ref count: %s, child %s' % (self.trace_node(node), repr(str(child))))) if T: @@ -900,7 +900,7 @@ class Taskmaster(object): # The default when we've gotten through all of the checks above: # this node is ready to be built. if S: S.build = S.build + 1 - if T: T.write(self.trace_message(u'Evaluating %s\n' % + if T: T.write(self.trace_message('Evaluating %s\n' % self.trace_node(node))) # For debugging only: diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 85ade8d..0140278 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -20,7 +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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -692,7 +692,7 @@ class TaskmasterTestCase(unittest.TestCase): tm = SCons.Taskmaster.Taskmaster([n3]) try: t = tm.next_task() - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == "Dependency cycle: n3 -> n1 -> n2 -> n3", str(e) else: assert 'Did not catch expected UserError' @@ -846,7 +846,7 @@ class TaskmasterTestCase(unittest.TestCase): exc_caught = None try: t.prepare() - except MyException, e: + except MyException as e: exc_caught = 1 except: pass @@ -899,7 +899,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() try: t.prepare() - except Exception, e: + except Exception as e: assert str(e) == "Executor.prepare() exception", e else: raise AssertionError("did not catch expected exception") @@ -953,7 +953,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() try: t.execute() - except SCons.Errors.BuildError, e: + except SCons.Errors.BuildError as e: assert e.node == n4, e.node assert e.errstr == "OtherError : ", e.errstr assert len(e.exc_info) == 3, e.exc_info diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py index 4c5730c..c21128e 100644 --- a/src/engine/SCons/Tool/FortranCommon.py +++ b/src/engine/SCons/Tool/FortranCommon.py @@ -61,7 +61,7 @@ def isfortran(env, source): def _fortranEmitter(target, source, env): node = source[0].rfile() if not node.exists() and not node.is_derived(): - print "Could not locate " + str(node.name) + print("Could not locate " + str(node.name)) return ([], []) mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)""" cre = re.compile(mod_regex,re.M) diff --git a/src/engine/SCons/Tool/GettextCommon.py b/src/engine/SCons/Tool/GettextCommon.py index cd2f306..ea81f0d 100644 --- a/src/engine/SCons/Tool/GettextCommon.py +++ b/src/engine/SCons/Tool/GettextCommon.py @@ -196,7 +196,7 @@ class _POFileBuilder(BuilderBase): import SCons.Util import SCons.Node linguas_files = None - if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE']: + if 'LINGUAS_FILE' in env and env['LINGUAS_FILE']: linguas_files = env['LINGUAS_FILE'] # This prevents endless recursion loop (we'll be invoked once for # each target appended here, we must not extend the list again). @@ -341,7 +341,7 @@ class RPaths(object): def _init_po_files(target, source, env): """ Action function for `POInit` builder. """ nop = lambda target, source, env : 0 - if env.has_key('POAUTOINIT'): + if 'POAUTOINIT' in env: autoinit = env['POAUTOINIT'] else: autoinit = False @@ -365,7 +365,7 @@ def _init_po_files(target, source, env): ############################################################################# def _detect_xgettext(env): """ Detects *xgettext(1)* binary """ - if env.has_key('XGETTEXT'): + if 'XGETTEXT' in env: return env['XGETTEXT'] xgettext = env.Detect('xgettext'); if xgettext: @@ -380,7 +380,7 @@ def _xgettext_exists(env): ############################################################################# def _detect_msginit(env): """ Detects *msginit(1)* program. """ - if env.has_key('MSGINIT'): + if 'MSGINIT' in env: return env['MSGINIT'] msginit = env.Detect('msginit'); if msginit: @@ -395,7 +395,7 @@ def _msginit_exists(env): ############################################################################# def _detect_msgmerge(env): """ Detects *msgmerge(1)* program. """ - if env.has_key('MSGMERGE'): + if 'MSGMERGE' in env: return env['MSGMERGE'] msgmerge = env.Detect('msgmerge'); if msgmerge: @@ -410,7 +410,7 @@ def _msgmerge_exists(env): ############################################################################# def _detect_msgfmt(env): """ Detects *msgmfmt(1)* program. """ - if env.has_key('MSGFMT'): + if 'MSGFMT' in env: return env['MSGFMT'] msgfmt = env.Detect('msgfmt'); if msgfmt: diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index caf2b37..dcf69c8 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -38,7 +38,7 @@ import SCons.Util logfile = os.environ.get('SCONS_MSCOMMON_DEBUG') if logfile == '-': def debug(x): - print x + print(x) elif logfile: try: import logging @@ -113,7 +113,7 @@ def normalize_env(env, keys, force=False): Note: the environment is copied.""" normenv = {} if env: - for k in env.keys(): + for k in list(env.keys()): normenv[k] = copy.deepcopy(env[k]).encode('mbcs') for k in keys: @@ -217,7 +217,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): dkeep[key].append(p) for line in output.splitlines(): - for k,v in rdk.items(): + for k,v in list(rdk.items()): m = v.match(line) if m: add_env(m, k) diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py index 6124e5b..1a6478f 100644 --- a/src/engine/SCons/Tool/MSCommon/netframework.py +++ b/src/engine/SCons/Tool/MSCommon/netframework.py @@ -28,7 +28,7 @@ __doc__ = """ import os import re -from common import read_reg, debug +from .common import read_reg, debug # Original value recorded by dcournapeau _FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot' @@ -40,7 +40,7 @@ def find_framework_root(): try: froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT) debug("Found framework install root in registry: %s" % froot) - except WindowsError, e: + except WindowsError as e: debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT) return None diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py index 2bf5eef..f71035b 100644 --- a/src/engine/SCons/Tool/MSCommon/sdk.py +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -33,7 +33,7 @@ import os import SCons.Errors import SCons.Util -import common +from . import common debug = common.debug @@ -80,7 +80,7 @@ class SDKDefinition(object): try: sdk_dir = common.read_reg(hkey) - except WindowsError, e: + except WindowsError as e: debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey)) return None @@ -299,7 +299,7 @@ def get_cur_sdk_dir_from_reg(): try: val = common.read_reg(_CURINSTALLED_SDK_HKEY_ROOT) debug("Found current sdk dir in registry: %s" % val) - except WindowsError, e: + except WindowsError as e: debug("Did not find current sdk in registry") return None @@ -350,7 +350,7 @@ def mssdk_setup_env(env): debug('sdk.py:mssdk_setup_env thinks msvs_version is None') return msvs_version = env.subst(msvs_version) - import vs + from . import vs msvs = vs.get_vs_by_version(msvs_version) debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs) if not msvs: diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 1266ee8..35b95d5 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -42,11 +42,11 @@ from string import digits as string_digits import SCons.Warnings -import common +from . import common debug = common.debug -import sdk +from . import sdk get_installed_sdks = sdk.get_installed_sdks @@ -119,14 +119,14 @@ def get_host_target(env): try: host = _ARCH_TO_CANONICAL[host_platform.lower()] - except KeyError, e: + except KeyError as e: msg = "Unrecognized host architecture %s" raise ValueError(msg % repr(host_platform)) try: target = _ARCH_TO_CANONICAL[target_platform.lower()] - except KeyError, e: - all_archs = str(_ARCH_TO_CANONICAL.keys()) + except KeyError as e: + all_archs = str(list(_ARCH_TO_CANONICAL.keys())) raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs)) return (host, target,req_target_platform) @@ -168,7 +168,7 @@ def msvc_version_to_maj_min(msvc_version): maj = int(t[0]) min = int(t[1]) return maj, min - except ValueError, e: + except ValueError as e: raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric)) def is_host_target_supported(host_target, msvc_version): @@ -217,7 +217,7 @@ def find_vc_pdir(msvc_version): key = root + key try: comps = common.read_reg(key) - except WindowsError, e: + except WindowsError as e: debug('find_vc_dir(): no VC registry key %s' % repr(key)) else: debug('find_vc_dir(): found VC in registry: %s' % comps) @@ -289,7 +289,7 @@ def get_installed_vcs(): installed_versions.append(ver) else: debug('find_vc_pdir return None for ver %s' % ver) - except VisualCException, e: + except VisualCException as e: debug('did not find VC %s: caught exception %s' % (ver, str(e))) return installed_versions @@ -393,7 +393,7 @@ def msvc_find_valid_batch_script(env,version): try: (vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp) debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script)) - except VisualCException, e: + except VisualCException as e: msg = str(e) debug('Caught exception while looking for batch file (%s)' % msg) warn_msg = "VC version %s not installed. " + \ @@ -408,7 +408,7 @@ def msvc_find_valid_batch_script(env,version): if vc_script: try: d = script_env(vc_script, args=arg) - except BatchFileExecutionError, e: + except BatchFileExecutionError as e: debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e)) vc_script=None continue @@ -416,7 +416,7 @@ def msvc_find_valid_batch_script(env,version): debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script)) try: d = script_env(sdk_script,args=[]) - except BatchFileExecutionError,e: + except BatchFileExecutionError as e: debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e)) continue elif not vc_script and not sdk_script: @@ -468,7 +468,7 @@ def msvc_setup_env(env): SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) return None - for k, v in d.items(): + for k, v in list(d.items()): debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v)) env.PrependENVPath(k, v, delete_existing=True) diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index d5bf2c3..3219719 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -31,7 +31,7 @@ import os import SCons.Errors import SCons.Util -from common import debug, \ +from .common import debug, \ get_output, \ is_win64, \ normalize_env, \ @@ -85,7 +85,7 @@ class VisualStudio(object): key = root + key try: comps = read_reg(key) - except WindowsError, e: + except WindowsError as e: debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key)) else: debug('find_vs_dir_by_reg(): found VS in registry: %s' % comps) @@ -536,7 +536,7 @@ def msvs_setup_env(env): env['ENV'] = save_ENV vars = parse_output(output, vars) - for k, v in vars.items(): + for k, v in list(vars.items()): env.PrependENVPath(k, v, delete_existing=1) def query_versions(): diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index b80d6e4..ac180a9 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -113,7 +113,7 @@ class Tool(object): finally: if file: file.close() - except ImportError, e: + except ImportError as e: if str(e)!="No module named %s"%self.name: raise SCons.Errors.EnvironmentError(e) try: @@ -125,7 +125,7 @@ class Tool(object): try: importer = zipimport.zipimporter(aPath) return importer.load_module(self.name) - except ImportError, e: + except ImportError as e: pass finally: sys.path = oldpythonpath @@ -143,7 +143,7 @@ class Tool(object): if file: file.close() return module - except ImportError, e: + except ImportError as e: if str(e)!="No module named %s"%self.name: raise SCons.Errors.EnvironmentError(e) try: @@ -152,10 +152,10 @@ class Tool(object): module = importer.load_module(full_name) setattr(SCons.Tool, self.name, module) return module - except ImportError, e: + except ImportError as e: m = "No tool named '%s': %s" % (self.name, e) raise SCons.Errors.EnvironmentError(m) - except ImportError, e: + except ImportError as e: m = "No tool named '%s': %s" % (self.name, e) raise SCons.Errors.EnvironmentError(m) @@ -254,7 +254,7 @@ def VersionShLibLinkNames(version, libname, env): suffix_re = re.escape('.' + version + shlib_suffix) linkname = re.sub(suffix_re, shlib_suffix, libname) if Verbose: - print "VersionShLibLinkNames: linkname = ",linkname + print("VersionShLibLinkNames: linkname = ",linkname) linknames.append(linkname) elif platform == 'posix': # For libfoo.so.x.y.z, linknames libfoo.so libfoo.so.x.y libfoo.so.x @@ -262,7 +262,7 @@ def VersionShLibLinkNames(version, libname, env): # First linkname has no version number linkname = re.sub(suffix_re, shlib_suffix, libname) if Verbose: - print "VersionShLibLinkNames: linkname = ",linkname + print("VersionShLibLinkNames: linkname = ",linkname) linknames.append(linkname) versionparts = version.split('.') major_name = linkname + "." + versionparts[0] @@ -271,7 +271,7 @@ def VersionShLibLinkNames(version, libname, env): #for linkname in [major_name, minor_name]: for linkname in [major_name, ]: if Verbose: - print "VersionShLibLinkNames: linkname ",linkname, ", target ",libname + print("VersionShLibLinkNames: linkname ",linkname, ", target ",libname) linknames.append(linkname) # note: no Windows case here (win32 or cygwin); # MSVC doesn't support this type of versioned shared libs. @@ -294,10 +294,10 @@ symlinks for the platform we are on""" shlib_suffix = env.subst('$SHLIBSUFFIX') shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS')) if Verbose: - print "VersionShLib: libname = ",libname - print "VersionShLib: platform = ",platform - print "VersionShLib: shlib_suffix = ",shlib_suffix - print "VersionShLib: target = ",str(target[0]) + print("VersionShLib: libname = ",libname) + print("VersionShLib: platform = ",platform) + print("VersionShLib: shlib_suffix = ",shlib_suffix) + print("VersionShLib: target = ",str(target[0])) if version: # set the shared library link flags @@ -308,7 +308,7 @@ symlinks for the platform we are on""" soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,-soname=%s' % soname ] if Verbose: - print " soname ",soname,", shlink_flags ",shlink_flags + print(" soname ",soname,", shlink_flags ",shlink_flags) elif platform == 'cygwin': shlink_flags += [ '-Wl,-Bsymbolic', '-Wl,--out-implib,${TARGET.base}.a' ] @@ -317,7 +317,7 @@ symlinks for the platform we are on""" '-compatibility_version', '%s' % version, '-undefined', 'dynamic_lookup' ] if Verbose: - print "VersionShLib: shlink_flags = ",shlink_flags + print("VersionShLib: shlink_flags = ",shlink_flags) envlink = env.Clone() envlink['SHLINKFLAGS'] = shlink_flags else: @@ -330,7 +330,7 @@ symlinks for the platform we are on""" libname = target[0].path linknames = VersionShLibLinkNames(version, libname, env) if Verbose: - print "VerShLib: linknames ",linknames + print("VerShLib: linknames ",linknames) # Here we just need the file name w/o path as the target of the link lib_ver = target[0].name # make symlink of adjacent names in linknames @@ -343,7 +343,7 @@ symlinks for the platform we are on""" pass os.symlink(os.path.basename(linkname),lastlinkname) if Verbose: - print "VerShLib: made sym link of %s -> %s" % (lastlinkname,linkname) + print("VerShLib: made sym link of %s -> %s" % (lastlinkname,linkname)) lastlinkname = linkname # finish chain of sym links with link to the actual library if len(linknames)>0: @@ -353,7 +353,7 @@ symlinks for the platform we are on""" pass os.symlink(lib_ver,lastlinkname) if Verbose: - print "VerShLib: made sym link of %s -> %s" % (linkname, lib_ver) + print("VerShLib: made sym link of %s -> %s" % (linkname, lib_ver)) return result ShLibAction = SCons.Action.Action(VersionedSharedLibrary, None) @@ -631,7 +631,7 @@ class ToolInitializer(object): so we no longer copy and re-bind them when the construction environment gets cloned. """ - for method in self.methods.values(): + for method in list(self.methods.values()): env.RemoveMethod(method) def apply_tools(self, env): diff --git a/src/engine/SCons/Tool/aixcc.py b/src/engine/SCons/Tool/aixcc.py index 9668f79..b1da31e 100644 --- a/src/engine/SCons/Tool/aixcc.py +++ b/src/engine/SCons/Tool/aixcc.py @@ -36,7 +36,7 @@ import os.path import SCons.Platform.aix -import cc +from . import cc packages = ['vac.C', 'ibmcxx.cmp'] diff --git a/src/engine/SCons/Tool/aixf77.py b/src/engine/SCons/Tool/aixf77.py index a667e84..21786ee 100644 --- a/src/engine/SCons/Tool/aixf77.py +++ b/src/engine/SCons/Tool/aixf77.py @@ -36,7 +36,7 @@ import os.path #import SCons.Platform.aix -import f77 +from . import f77 # It would be good to look for the AIX F77 package the same way we're now # looking for the C and C++ packages. This should be as easy as supplying diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py index 3512522..fc65afb 100644 --- a/src/engine/SCons/Tool/aixlink.py +++ b/src/engine/SCons/Tool/aixlink.py @@ -37,8 +37,8 @@ import os.path import SCons.Util -import aixcc -import link +from . import aixcc +from . import link cplusplus = __import__('c++', globals(), locals(), []) diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py index 1939098..ba955a4 100644 --- a/src/engine/SCons/Tool/applelink.py +++ b/src/engine/SCons/Tool/applelink.py @@ -37,7 +37,7 @@ import SCons.Util # Even though the Mac is based on the GNU toolchain, it doesn't understand # the -rpath option, so we use the "link" tool instead of "gnulink". -import link +from . import link def generate(env): """Add Builders and construction variables for applelink to an diff --git a/src/engine/SCons/Tool/cvf.py b/src/engine/SCons/Tool/cvf.py index 2a28e6a..da2c910 100644 --- a/src/engine/SCons/Tool/cvf.py +++ b/src/engine/SCons/Tool/cvf.py @@ -29,7 +29,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import fortran +from . import fortran compilers = ['f90'] diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 87716cf..1685d7f 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -11,7 +11,7 @@ selection method. import SCons.Action import SCons.Util -import gnulink +from . import gnulink def shlib_generator(target, source, env, for_signature): cmd = SCons.Util.CLVar(['$SHLINK']) diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py index c070602..ef03206 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py @@ -82,7 +82,7 @@ def adjustColumnWidths(ctx, nodeset): relParts.append(relPart) absParts.append(pixels) - col = col.next + col = col.__next__ # Ok, now we have the relative widths and absolute widths in # two parallel arrays. @@ -116,7 +116,7 @@ def adjustColumnWidths(ctx, nodeset): pixelWidth = convertLength(tableWidth) if pixelWidth <= absTotal: - print "Table is wider than table width" + print("Table is wider than table width") else: pixelWidth = pixelWidth - absTotal @@ -151,7 +151,7 @@ def adjustColumnWidths(ctx, nodeset): col.setProp("width", widths[count]) count = count+1 - col = col.next + col = col.__next__ return nodeset @@ -163,10 +163,10 @@ def convertLength(length): m = re.search('([+-]?[\d\.]+)(\S+)', length) if m != None and m.lastindex > 1: unit = pixelsPerInch - if unitHash.has_key(m.group(2)): + if m.group(2) in unitHash: unit = unitHash[m.group(2)] else: - print "Unrecognized length: " + m.group(2) + print("Unrecognized length: " + m.group(2)) pixels = unit * float(m.group(1)) else: diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py index c712f65..8554dd1 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py @@ -18,7 +18,7 @@ try: xmlfile = sys.argv[1] xslfile = sys.argv[2] except IndexError: - print usage + print(usage) sys.exit(1) def quote(astring): @@ -38,12 +38,12 @@ try: while (sys.argv[count]): try: name, value = sys.argv[count].split("=", 2) - if params.has_key(name): - print "Warning: '%s' re-specified; replacing value" % name + if name in params: + print("Warning: '%s' re-specified; replacing value" % name) params[name] = quote(value) except ValueError: - print "Invalid parameter specification: '" + sys.argv[count] + "'" - print usage + print("Invalid parameter specification: '" + sys.argv[count] + "'") + print(usage) sys.exit(1) count = count+1 except IndexError: @@ -70,7 +70,7 @@ result = style.applyStylesheet(doc, params) if outfile: style.saveResultToFilename(outfile, result, 0) else: - print result + print(result) # Free things up style.freeStylesheet() diff --git a/src/engine/SCons/Tool/dvipdf.py b/src/engine/SCons/Tool/dvipdf.py index 7c41e9c..374b9c5 100644 --- a/src/engine/SCons/Tool/dvipdf.py +++ b/src/engine/SCons/Tool/dvipdf.py @@ -100,7 +100,7 @@ def generate(env): if DVIPDFAction is None: DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction) - import pdf + from . import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] diff --git a/src/engine/SCons/Tool/f03.py b/src/engine/SCons/Tool/f03.py index 3aab1c0..6c30971 100644 --- a/src/engine/SCons/Tool/f03.py +++ b/src/engine/SCons/Tool/f03.py @@ -36,7 +36,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Defaults import SCons.Tool import SCons.Util -import fortran +from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env compilers = ['f03'] diff --git a/src/engine/SCons/Tool/f95.py b/src/engine/SCons/Tool/f95.py index 5ce5e57..5baa31e 100644 --- a/src/engine/SCons/Tool/f95.py +++ b/src/engine/SCons/Tool/f95.py @@ -36,7 +36,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Defaults import SCons.Tool import SCons.Util -import fortran +from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env compilers = ['f95'] diff --git a/src/engine/SCons/Tool/filesystem.py b/src/engine/SCons/Tool/filesystem.py index 31c8abc..3b8ee4c 100644 --- a/src/engine/SCons/Tool/filesystem.py +++ b/src/engine/SCons/Tool/filesystem.py @@ -66,7 +66,7 @@ def generate(env): try: env['BUILDERS']['CopyTo'] env['BUILDERS']['CopyAs'] - except KeyError, e: + except KeyError as e: global copyToBuilder if copyToBuilder is None: copyToBuilder = SCons.Builder.Builder( diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 71f60a3..4f87b24 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -33,7 +33,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cc +from . import cc import os import re import subprocess diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py index 4f3e7e4..7b05e68 100644 --- a/src/engine/SCons/Tool/gfortran.py +++ b/src/engine/SCons/Tool/gfortran.py @@ -36,7 +36,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import fortran +from . import fortran def generate(env): """Add Builders and construction variables for gfortran to an diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py index bf71270..ea8d7bd 100644 --- a/src/engine/SCons/Tool/gnulink.py +++ b/src/engine/SCons/Tool/gnulink.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import link +from . import link linkers = ['g++', 'gcc'] diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py index ada169a..c5506ce 100644 --- a/src/engine/SCons/Tool/gs.py +++ b/src/engine/SCons/Tool/gs.py @@ -57,7 +57,7 @@ def generate(env): if GhostscriptAction is None: GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR') - import pdf + from . import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] diff --git a/src/engine/SCons/Tool/hpcc.py b/src/engine/SCons/Tool/hpcc.py index 30f4964..51d2e38 100644 --- a/src/engine/SCons/Tool/hpcc.py +++ b/src/engine/SCons/Tool/hpcc.py @@ -34,7 +34,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import cc +from . import cc def generate(env): """Add Builders and construction variables for aCC & cc to an Environment.""" diff --git a/src/engine/SCons/Tool/hplink.py b/src/engine/SCons/Tool/hplink.py index 17dbe05..10ef30b 100644 --- a/src/engine/SCons/Tool/hplink.py +++ b/src/engine/SCons/Tool/hplink.py @@ -37,7 +37,7 @@ import os.path import SCons.Util -import link +from . import link ccLinker = None diff --git a/src/engine/SCons/Tool/icc.py b/src/engine/SCons/Tool/icc.py index db15642..11ea075 100644 --- a/src/engine/SCons/Tool/icc.py +++ b/src/engine/SCons/Tool/icc.py @@ -33,7 +33,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cc +from . import cc def generate(env): """Add Builders and construction variables for the OS/2 to an Environment.""" diff --git a/src/engine/SCons/Tool/ifl.py b/src/engine/SCons/Tool/ifl.py index 30b3672..865d2ba 100644 --- a/src/engine/SCons/Tool/ifl.py +++ b/src/engine/SCons/Tool/ifl.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Defaults from SCons.Scanner.Fortran import FortranScan -from FortranCommon import add_all_to_env +from .FortranCommon import add_all_to_env def generate(env): """Add Builders and construction variables for ifl to an Environment.""" diff --git a/src/engine/SCons/Tool/ifort.py b/src/engine/SCons/Tool/ifort.py index 4b2fd65..638bd12 100644 --- a/src/engine/SCons/Tool/ifort.py +++ b/src/engine/SCons/Tool/ifort.py @@ -36,7 +36,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Defaults from SCons.Scanner.Fortran import FortranScan -from FortranCommon import add_all_to_env +from .FortranCommon import add_all_to_env def generate(env): """Add Builders and construction variables for ifort to an Environment.""" diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 0c81d05..4236e81 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -82,21 +82,21 @@ def scons_copytree(src, dst, symlinks=False): else: shutil.copy2(srcname, dstname) # XXX What about devices, sockets etc.? - except (IOError, os.error), why: + except (IOError, os.error) as why: errors.append((srcname, dstname, str(why))) # catch the CopytreeError from the recursive copytree so that we can # continue with other files - except CopytreeError, err: + except CopytreeError as err: errors.extend(err.args[0]) try: shutil.copystat(src, dst) except WindowsError: # can't copy file access times on Windows pass - except OSError, why: + except OSError as why: errors.extend((src, dst, str(why))) if errors: - raise CopytreeError, errors + raise CopytreeError(errors) # @@ -174,7 +174,7 @@ def versionedLibVersion(dest, env): version_File = version_re.findall(versioned_re.findall(libname)[-1])[-1] if Verbose: - print "install: version_File ", version_File + print("install: version_File ", version_File) # result is False if we did not find a versioned shared library name, so return and empty list if not result: return (None, libname, install_dir) @@ -188,7 +188,7 @@ def versionedLibVersion(dest, env): if version != version_File: #raise SCons.Errors.UserError("SHLIBVERSION '%s' does not match the version # '%s' in the filename" % (version, version_File) ) - print "SHLIBVERSION '%s' does not match the version # '%s' in the filename, proceeding based on file name" % (version, version_File) + print("SHLIBVERSION '%s' does not match the version # '%s' in the filename, proceeding based on file name" % (version, version_File)) version = version_File return (version, libname, install_dir) @@ -202,7 +202,7 @@ def versionedLibLinks(dest, source, env): # libname includes the version number if one was given linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env) if Verbose: - print "versionedLibLinks: linknames ",linknames + print("versionedLibLinks: linknames ",linknames) # Here we just need the file name w/o path as the target of the link lib_ver = libname # make symlink of adjacent names in linknames @@ -210,7 +210,7 @@ def versionedLibLinks(dest, source, env): linkname = linknames[count] fulllinkname = os.path.join(install_dir, linkname) if Verbose: - print "full link name ",fulllinkname + print("full link name ",fulllinkname) if count > 0: try: os.remove(lastlinkname) @@ -218,7 +218,7 @@ def versionedLibLinks(dest, source, env): pass os.symlink(os.path.basename(fulllinkname),lastlinkname) if Verbose: - print "versionedLibLinks: made sym link of %s -> %s" % (lastlinkname,os.path.basename(fulllinkname)) + print("versionedLibLinks: made sym link of %s -> %s" % (lastlinkname,os.path.basename(fulllinkname))) lastlinkname = fulllinkname # finish chain of sym links with link to the actual library if len(linknames)>0: @@ -228,7 +228,7 @@ def versionedLibLinks(dest, source, env): pass os.symlink(lib_ver,lastlinkname) if Verbose: - print "versionedLibLinks: made sym link of %s -> %s" % (lib_ver,lastlinkname) + print("versionedLibLinks: made sym link of %s -> %s" % (lib_ver,lastlinkname)) return def installFunc(target, source, env): @@ -298,7 +298,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): Verbose = False _INSTALLED_FILES.extend(target) if Verbose: - print "ver lib emitter ",repr(target) + print("ver lib emitter ",repr(target)) # see if we have a versioned shared library, if so generate side effects version, libname, install_dir = versionedLibVersion(target[0].path, env) @@ -307,13 +307,13 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env): linknames = SCons.Tool.VersionShLibLinkNames(version,libname,env) for linkname in linknames: if Verbose: - print "make side effect of %s" % os.path.join(install_dir, linkname) + print("make side effect of %s" % os.path.join(install_dir, linkname)) fulllinkname = os.path.join(install_dir, linkname) env.SideEffect(fulllinkname,target[0]) env.Clean(target[0],fulllinkname) _INSTALLED_FILES.append(fulllinkname) if Verbose: - print "installed list ", _INSTALLED_FILES + print("installed list ", _INSTALLED_FILES) _UNIQUE_INSTALLED_FILES = None return (target, source) diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index 4201092..8b178a7 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -30,7 +30,7 @@ selection method. # 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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -206,17 +206,16 @@ def get_all_compiler_versions(): # Registry points to nonexistent dir. Ignore this # version. value = get_intel_registry_value('ProductDir', subkey, 'IA32') - except MissingRegistryError, e: + except MissingRegistryError as e: # Registry key is left dangling (potentially # after uninstalling). - print \ - "scons: *** Ignoring the registry key for the Intel compiler version %s.\n" \ + print("scons: *** Ignoring the registry key for the Intel compiler version %s.\n" \ "scons: *** It seems that the compiler was uninstalled and that the registry\n" \ - "scons: *** was not cleaned up properly.\n" % subkey + "scons: *** was not cleaned up properly.\n" % subkey) else: - print "scons: *** Ignoring "+str(value) + print("scons: *** Ignoring "+str(value)) i = i + 1 except EnvironmentError: @@ -424,8 +423,8 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): bindir="bin" libdir="lib" if verbose: - print "Intel C compiler: using version %s (%g), abi %s, in '%s/%s'"%\ - (repr(version), linux_ver_normalize(version),abi,topdir,bindir) + print("Intel C compiler: using version %s (%g), abi %s, in '%s/%s'"%\ + (repr(version), linux_ver_normalize(version),abi,topdir,bindir)) if is_linux: # Show the actual compiler version by running the compiler. os.system('%s/%s/icc --version'%(topdir,bindir)) @@ -439,14 +438,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in paths.keys(): + for p in list(paths.keys()): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_mac: paths={'INCLUDE' : 'include', 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in paths.keys(): + for p in list(paths.keys()): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_windows: # env key reg valname default subdir of top diff --git a/src/engine/SCons/Tool/latex.py b/src/engine/SCons/Tool/latex.py index 1c71743..f30356b 100644 --- a/src/engine/SCons/Tool/latex.py +++ b/src/engine/SCons/Tool/latex.py @@ -55,10 +55,10 @@ def generate(env): env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - import dvi + from . import dvi dvi.generate(env) - import pdf + from . import pdf pdf.generate(env) bld = env['BUILDERS']['DVI'] diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 3f20fe0..5539f62 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -81,7 +81,7 @@ def shlib_emitter(target, source, env): env.SideEffect(name, target[0]) env.Clean(target[0], name) if Verbose: - print "shlib_emitter: add side effect - ",name + print("shlib_emitter: add side effect - ",name) except KeyError: version = None return (target, source) @@ -104,16 +104,16 @@ def shlib_emitter_names(target, source, env): # generate library name with the version number version_name = target[0].name + '.' + version if Verbose: - print "shlib_emitter_names: target is ", version_name - print "shlib_emitter_names: side effect: ", name + print("shlib_emitter_names: target is ", version_name) + print("shlib_emitter_names: side effect: ", name) # add version_name to list of names to be a Side effect version_names.append(version_name) if Verbose: - print "shlib_emitter_names: versionparts ",versionparts + print("shlib_emitter_names: versionparts ",versionparts) for ver in versionparts[0:-1]: name = name + '.' + ver if Verbose: - print "shlib_emitter_names: side effect: ", name + print("shlib_emitter_names: side effect: ", name) # add name to list of names to be a Side effect version_names.append(name) elif platform == 'darwin': @@ -123,8 +123,8 @@ def shlib_emitter_names(target, source, env): suffix_re = re.escape(shlib_suffix) version_name = re.sub(suffix_re, '.' + version + shlib_suffix, name) if Verbose: - print "shlib_emitter_names: target is ", version_name - print "shlib_emitter_names: side effect: ", name + print("shlib_emitter_names: target is ", version_name) + print("shlib_emitter_names: side effect: ", name) # add version_name to list of names to be a Side effect version_names.append(version_name) elif platform == 'cygwin': @@ -134,8 +134,8 @@ def shlib_emitter_names(target, source, env): suffix_re = re.escape(shlib_suffix) version_name = re.sub(suffix_re, '-' + re.sub('\.', '-', version) + shlib_suffix, name) if Verbose: - print "shlib_emitter_names: target is ", version_name - print "shlib_emitter_names: side effect: ", name + print("shlib_emitter_names: target is ", version_name) + print("shlib_emitter_names: side effect: ", name) # add version_name to list of names to be a Side effect version_names.append(version_name) diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py index 64b927a..7a59e33 100644 --- a/src/engine/SCons/Tool/midl.py +++ b/src/engine/SCons/Tool/midl.py @@ -39,7 +39,7 @@ import SCons.Defaults import SCons.Scanner.IDL import SCons.Util -from MSCommon import msvc_exists +from .MSCommon import msvc_exists def midl_emitter(target, source, env): """Produces a list of outputs from the MIDL compiler""" diff --git a/src/engine/SCons/Tool/msgfmt.py b/src/engine/SCons/Tool/msgfmt.py index 352ba77..4fe6afd 100644 --- a/src/engine/SCons/Tool/msgfmt.py +++ b/src/engine/SCons/Tool/msgfmt.py @@ -41,7 +41,7 @@ class _MOFileBuilder(BuilderBase): import SCons.Util from SCons.Tool.GettextCommon import _read_linguas_from_files linguas_files = None - if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE'] is not None: + if 'LINGUAS_FILE' in env and env['LINGUAS_FILE'] is not None: linguas_files = env['LINGUAS_FILE'] # This should prevent from endless recursion. env['LINGUAS_FILE'] = None diff --git a/src/engine/SCons/Tool/msginit.py b/src/engine/SCons/Tool/msginit.py index 5e9c0e4..39f460d 100644 --- a/src/engine/SCons/Tool/msginit.py +++ b/src/engine/SCons/Tool/msginit.py @@ -35,7 +35,7 @@ def _optional_no_translator_flag(env): """ Return '--no-translator' flag if we run *msginit(1)* in non-interactive mode.""" import SCons.Util - if env.has_key('POAUTOINIT'): + if 'POAUTOINIT' in env: autoinit = env['POAUTOINIT'] else: autoinit = False @@ -66,7 +66,7 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **kw): if source is _null: if 'POTDOMAIN' in kw: domain = kw['POTDOMAIN'] - elif env.has_key('POTDOMAIN'): + elif 'POTDOMAIN' in env: domain = env['POTDOMAIN'] else: domain = 'messages' diff --git a/src/engine/SCons/Tool/msgmerge.py b/src/engine/SCons/Tool/msgmerge.py index f3710ab..11d7b48 100644 --- a/src/engine/SCons/Tool/msgmerge.py +++ b/src/engine/SCons/Tool/msgmerge.py @@ -58,7 +58,7 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): if source is _null: if 'POTDOMAIN' in kw: domain = kw['POTDOMAIN'] - elif env.has_key('POTDOMAIN') and env['POTDOMAIN']: + elif 'POTDOMAIN' in env and env['POTDOMAIN']: domain = env['POTDOMAIN'] else: domain = 'messages' diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py index 8a4af57..df8d877 100644 --- a/src/engine/SCons/Tool/mslib.py +++ b/src/engine/SCons/Tool/mslib.py @@ -39,7 +39,7 @@ import SCons.Tool.msvs import SCons.Tool.msvc import SCons.Util -from MSCommon import msvc_exists, msvc_setup_env_once +from .MSCommon import msvc_exists, msvc_setup_env_once def generate(env): """Add Builders and construction variables for lib to an Environment.""" diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 40f112b..b56d34a 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -44,7 +44,7 @@ import SCons.Tool.msvc import SCons.Tool.msvs import SCons.Util -from MSCommon import msvc_setup_env_once, msvc_exists +from .MSCommon import msvc_setup_env_once, msvc_exists def pdbGenerator(env, target, source, for_signature): try: @@ -195,7 +195,7 @@ def RegServerFunc(target, source, env): if ret: raise SCons.Errors.UserError("Unable to register %s" % target[0]) else: - print "Registered %s sucessfully" % target[0] + print("Registered %s sucessfully" % target[0]) return ret return 0 @@ -212,10 +212,10 @@ def embedManifestDllCheck(target, source, env): if os.path.exists(manifestSrc): ret = (embedManifestDllAction) ([target[0]],None,env) if ret: - raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0]) + raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) return ret else: - print '(embed: no %s.manifest found; not embedding.)'%str(target[0]) + print('(embed: no %s.manifest found; not embedding.)'%str(target[0])) return 0 def embedManifestExeCheck(target, source, env): @@ -226,10 +226,10 @@ def embedManifestExeCheck(target, source, env): if os.path.exists(manifestSrc): ret = (embedManifestExeAction) ([target[0]],None,env) if ret: - raise SCons.Errors.UserError, "Unable to embed manifest into %s" % (target[0]) + raise SCons.Errors.UserError("Unable to embed manifest into %s" % (target[0])) return ret else: - print '(embed: no %s.manifest found; not embedding.)'%str(target[0]) + print('(embed: no %s.manifest found; not embedding.)'%str(target[0])) return 0 embedManifestDllCheckAction = SCons.Action.Action(embedManifestDllCheck, None) diff --git a/src/engine/SCons/Tool/mssdk.py b/src/engine/SCons/Tool/mssdk.py index 6103f30..f373002 100644 --- a/src/engine/SCons/Tool/mssdk.py +++ b/src/engine/SCons/Tool/mssdk.py @@ -33,7 +33,7 @@ It will usually be imported through the generic SCons.Tool.Tool() selection method. """ -from MSCommon import mssdk_exists, \ +from .MSCommon import mssdk_exists, \ mssdk_setup_env def generate(env): diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index d42c257..0bc296f 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -47,7 +47,7 @@ import SCons.Util import SCons.Warnings import SCons.Scanner.RC -from MSCommon import msvc_exists, msvc_setup_env_once +from .MSCommon import msvc_exists, msvc_setup_env_once CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 06ce486..0879a28 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -51,7 +51,7 @@ import SCons.PathList import SCons.Util import SCons.Warnings -from MSCommon import msvc_exists, msvc_setup_env_once +from .MSCommon import msvc_exists, msvc_setup_env_once from SCons.Defaults import processDefines ############################################################################## @@ -351,13 +351,13 @@ class _DSPGenerator(object): config.platform = 'Win32' self.configs[variant] = config - print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'" + print("Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dspfile) + "'") for i in range(len(variants)): AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) self.platforms = [] - for key in self.configs.keys(): + for key in list(self.configs.keys()): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) @@ -480,7 +480,7 @@ class _GenerateV6DSP(_DSPGenerator): 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', 'Other Files': ''} - for kind in sorted(categories.keys(), key=lambda a: a.lower()): + for kind in sorted(list(categories.keys()), key=lambda a: a.lower()): if not self.sources[kind]: continue # skip empty groups @@ -551,7 +551,7 @@ class _GenerateV6DSP(_DSPGenerator): def Build(self): try: self.file = open(self.dspabs,'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail)) else: self.PrintHeader() @@ -744,7 +744,7 @@ class _GenerateV7DSP(_DSPGenerator): self.file.write(pdata + '-->\n') def printSources(self, hierarchy, commonprefix): - sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key=lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -774,7 +774,7 @@ class _GenerateV7DSP(_DSPGenerator): self.file.write('\t\n') - cats = sorted([k for k in categories.keys() if self.sources[k]], + cats = sorted([k for k in list(categories.keys()) if self.sources[k]], key=lambda a: a.lower()) for kind in cats: if len(cats) > 1: @@ -861,7 +861,7 @@ class _GenerateV7DSP(_DSPGenerator): def Build(self): try: self.file = open(self.dspabs,'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail)) else: self.PrintHeader() @@ -1029,7 +1029,7 @@ class _GenerateV10DSP(_DSPGenerator): self.filtersabs = self.dspabs + '.filters' try: self.filters_file = open(self.filtersabs, 'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.filtersabs + '" for writing:' + str(detail)) self.filters_file.write('\n' @@ -1055,7 +1055,7 @@ class _GenerateV10DSP(_DSPGenerator): self.file.write(pdata + '-->\n') def printFilters(self, hierarchy, name): - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) for key, value in sorteditems: if SCons.Util.is_Dict(value): @@ -1072,7 +1072,7 @@ class _GenerateV10DSP(_DSPGenerator): 'Resource Files': 'None', 'Other Files': 'None'} - sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) + sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -1098,7 +1098,7 @@ class _GenerateV10DSP(_DSPGenerator): 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', 'Other Files': ''} - cats = sorted([k for k in categories.keys() if self.sources[k]], + cats = sorted([k for k in list(categories.keys()) if self.sources[k]], key = lambda a: a.lower()) # print vcxproj.filters file first @@ -1158,12 +1158,12 @@ class _GenerateV10DSP(_DSPGenerator): '\t\n' % str(self.sconscript)) def Parse(self): - print "_GenerateV10DSP.Parse()" + print("_GenerateV10DSP.Parse()") def Build(self): try: self.file = open(self.dspabs, 'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail)) else: self.PrintHeader() @@ -1242,7 +1242,7 @@ class _GenerateV7DSW(_DSWGenerator): config.platform = 'Win32' self.configs[variant] = config - print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'" + print("Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'") if 'variant' not in env: raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ @@ -1254,7 +1254,7 @@ class _GenerateV7DSW(_DSWGenerator): AddConfig(self, variant) self.platforms = [] - for key in self.configs.keys(): + for key in list(self.configs.keys()): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) @@ -1424,7 +1424,7 @@ class _GenerateV7DSW(_DSWGenerator): def Build(self): try: self.file = open(self.dswfile,'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail)) else: self.PrintSolution() @@ -1473,7 +1473,7 @@ class _GenerateV6DSW(_DSWGenerator): def Build(self): try: self.file = open(self.dswfile,'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail)) else: self.PrintWorkspace() @@ -1530,8 +1530,8 @@ def GenerateProject(target, source, env): if not dspfile is builddspfile: try: bdsp = open(str(builddspfile), "w+") - except IOError, detail: - print 'Unable to open "' + str(dspfile) + '" for writing:',detail,'\n' + except IOError as detail: + print('Unable to open "' + str(dspfile) + '" for writing:',detail,'\n') raise bdsp.write("This is just a placeholder file.\nThe real project file is here:\n%s\n" % dspfile.get_abspath()) @@ -1546,8 +1546,8 @@ def GenerateProject(target, source, env): try: bdsw = open(str(builddswfile), "w+") - except IOError, detail: - print 'Unable to open "' + str(dspfile) + '" for writing:',detail,'\n' + except IOError as detail: + print('Unable to open "' + str(dspfile) + '" for writing:',detail,'\n') raise bdsw.write("This is just a placeholder file.\nThe real workspace file is here:\n%s\n" % dswfile.get_abspath()) diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 7d966c1..1466db6 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -743,7 +743,7 @@ if __name__ == "__main__": ] for test_class in test_classes: - print "TEST: ", test_class.__doc__ + print("TEST: ", test_class.__doc__) back_osenv = copy.deepcopy(os.environ) try: # XXX: overriding the os.environ is bad, but doing it diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py index 95311a2..c3de2aa 100644 --- a/src/engine/SCons/Tool/packaging/__init__.py +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -72,7 +72,7 @@ def Tag(env, target, source, *more_tags, **kw_tags): target=env.Flatten(target) for t in target: - for (k,v) in kw_tags.items(): + for (k,v) in list(kw_tags.items()): # all file tags have to start with PACKAGING_, so we can later # differentiate between "normal" object attributes and the # packaging attributes. As the user should not be bothered with @@ -120,7 +120,7 @@ def Package(env, target=None, source=None, **kw): try: file,path,desc=imp.find_module(type, __path__) return imp.load_module(type, file, path, desc) - except ImportError, e: + except ImportError as e: raise EnvironmentError("packager %s not available: %s"%(type,str(e))) packagers=list(map(load_packager, PACKAGETYPE)) @@ -141,7 +141,7 @@ def Package(env, target=None, source=None, **kw): if 'PACKAGEROOT' not in kw: kw['PACKAGEROOT'] = default_name%kw - except KeyError, e: + except KeyError as e: raise SCons.Errors.UserError( "Missing Packagetag '%s'"%e.args[0] ) # setup the source files @@ -157,10 +157,10 @@ def Package(env, target=None, source=None, **kw): assert( len(target) == 0 ) - except KeyError, e: + except KeyError as e: raise SCons.Errors.UserError( "Missing Packagetag '%s' for %s packager"\ % (e.args[0],packager.__name__) ) - except TypeError, e: + except TypeError as e: # this exception means that a needed argument for the packager is # missing. As our packagers get their "tags" as named function # arguments we need to find out which one is missing. diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index 6549445..ad27a62 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -169,7 +169,7 @@ Description: $X_IPK_DESCRIPTION # # close all opened files - for f in opened_files.values(): + for f in list(opened_files.values()): f.close() # call a user specified function diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index fe78c9c..70fdc48 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -172,7 +172,7 @@ def generate_guids(root): # find all XMl nodes matching the key, retrieve their attribute, hash their # subtree, convert hash to string and add as a attribute to the xml node. - for (key,value) in needs_id.items(): + for (key,value) in list(needs_id.items()): node_list = root.getElementsByTagName(key) attribute = value for node in node_list: @@ -216,7 +216,7 @@ def build_wxsfile(target, source, env): if 'CHANGE_SPECFILE' in env: env['CHANGE_SPECFILE'](target, source) - except KeyError, e: + except KeyError as e: raise SCons.Errors.UserError( '"%s" package field for MSI is missing.' % e.args[0] ) # @@ -335,7 +335,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, } # fill in the default tags given above. - for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]: + for k,v in [ (k, v) for (k,v) in list(h.items()) if not hasattr(file, k) ]: setattr( file, k, v ) File = factory.createElement( 'File' ) @@ -382,7 +382,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): Feature.attributes['Description'] = escape( SUMMARY ) Feature.attributes['Display'] = 'expand' - for (feature, files) in create_feature_dict(files).items(): + for (feature, files) in list(create_feature_dict(files).items()): SubFeature = factory.createElement('Feature') SubFeature.attributes['Level'] = '1' diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index 07857d1..4958065 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -107,7 +107,7 @@ def collectintargz(target, source, env): try: #tarball = env['SOURCE_URL'].split('/')[-1] tarball = env['SOURCE_URL'].split('/')[-1] - except KeyError, e: + except KeyError as e: raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] ) tarball = src_targz.package(env, source=sources, target=tarball, @@ -143,7 +143,7 @@ def build_specfile(target, source, env): if 'CHANGE_SPECFILE' in env: env['CHANGE_SPECFILE'](target, source) - except KeyError, e: + except KeyError as e: raise SCons.Errors.UserError( '"%s" package field for RPM is missing.' % e.args[0] ) @@ -277,7 +277,7 @@ def build_specfile_filesection(spec, files): for file in files: # build the tagset tags = {} - for k in supported_tags.keys(): + for k in list(supported_tags.keys()): try: tags[k]=getattr(file, k) except AttributeError: @@ -331,7 +331,7 @@ class SimpleTagCompiler(object): for key, replacement in domestic: try: str = str + replacement % values[key] - except KeyError, e: + except KeyError as e: if self.mandatory: raise e @@ -340,11 +340,11 @@ class SimpleTagCompiler(object): 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 = [t for t in values.items() if strip_country_code(t[0]) == key] + x = [t for t in list(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: + except KeyError as e: if self.mandatory: raise e diff --git a/src/engine/SCons/Tool/pdflatex.py b/src/engine/SCons/Tool/pdflatex.py index 922e718..fbffb23 100644 --- a/src/engine/SCons/Tool/pdflatex.py +++ b/src/engine/SCons/Tool/pdflatex.py @@ -62,7 +62,7 @@ def generate(env): env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - import pdf + from . import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] diff --git a/src/engine/SCons/Tool/pdftex.py b/src/engine/SCons/Tool/pdftex.py index 30c56af..e9a0bda 100644 --- a/src/engine/SCons/Tool/pdftex.py +++ b/src/engine/SCons/Tool/pdftex.py @@ -85,7 +85,7 @@ def generate(env): env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) - import pdf + from . import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py index 716c7d5..fdfdd26 100644 --- a/src/engine/SCons/Tool/qt.py +++ b/src/engine/SCons/Tool/qt.py @@ -130,12 +130,12 @@ class _Automoc(object): if not obj.has_builder(): # binary obj file provided if debug: - print "scons: qt: '%s' seems to be a binary. Discarded." % str(obj) + print("scons: qt: '%s' seems to be a binary. Discarded." % str(obj)) continue cpp = obj.sources[0] if not splitext(str(cpp))[1] in cxx_suffixes: if debug: - print "scons: qt: '%s' is no cxx file. Discarded." % str(cpp) + print("scons: qt: '%s' is no cxx file. Discarded." % str(cpp)) # c or fortran source continue #cpp_contents = comment.sub('', cpp.get_text_contents()) @@ -148,12 +148,12 @@ class _Automoc(object): h = find_file(hname, (cpp.get_dir(),), env.File) if h: if debug: - print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp)) + print("scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))) #h_contents = comment.sub('', h.get_text_contents()) h_contents = h.get_text_contents() break if not h and debug: - print "scons: qt: no header for '%s'." % (str(cpp)) + print("scons: qt: no header for '%s'." % (str(cpp))) if h and q_object_search.search(h_contents): # h file with the Q_OBJECT macro found -> add moc_cpp moc_cpp = env.Moc(h) @@ -161,14 +161,14 @@ class _Automoc(object): out_sources.append(moc_o) #moc_cpp.target_scanner = SCons.Defaults.CScan if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp)) + print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))) if cpp and q_object_search.search(cpp_contents): # cpp file with Q_OBJECT macro found -> add moc # (to be included in cpp) moc = env.Moc(cpp) env.Ignore(moc, moc) if debug: - print "scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc)) + print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))) #moc.source_scanner = SCons.Defaults.CScan # restore the original env attributes (FIXME) objBuilder.env = objBuilderEnv diff --git a/src/engine/SCons/Tool/rpmutils.py b/src/engine/SCons/Tool/rpmutils.py index 90e3d74..e96c54c 100644 --- a/src/engine/SCons/Tool/rpmutils.py +++ b/src/engine/SCons/Tool/rpmutils.py @@ -491,7 +491,7 @@ def updateRpmDicts(rpmrc, pyfile): key = tokens[0] if key in sections: # Have we met this section before? - if not data.has_key(tokens[0]): + if tokens[0] not in data: # No, so insert it data[key] = {} # Insert data @@ -509,7 +509,7 @@ def updateRpmDicts(rpmrc, pyfile): if l.startswith('# Start of rpmrc dictionaries'): pm = 1 # Write data sections to single dictionaries - for key, entries in data.iteritems(): + for key, entries in data.items(): out.write("%s = {\n" % key) for arch in sorted(entries.keys()): out.write(" '%s' : ['%s'],\n" % (arch, "','".join(entries[arch]))) @@ -519,7 +519,7 @@ def updateRpmDicts(rpmrc, pyfile): pass def usage(): - print "rpmutils.py rpmrc.in rpmutils.py" + print("rpmutils.py rpmrc.in rpmutils.py") def main(): import sys diff --git a/src/engine/SCons/Tool/sgicc.py b/src/engine/SCons/Tool/sgicc.py index 662eb7d..94a0497 100644 --- a/src/engine/SCons/Tool/sgicc.py +++ b/src/engine/SCons/Tool/sgicc.py @@ -33,7 +33,7 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import cc +from . import cc def generate(env): """Add Builders and construction variables for gcc to an Environment.""" diff --git a/src/engine/SCons/Tool/sgilink.py b/src/engine/SCons/Tool/sgilink.py index 6244141..b1e7921 100644 --- a/src/engine/SCons/Tool/sgilink.py +++ b/src/engine/SCons/Tool/sgilink.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import link +from . import link linkers = ['CC', 'cc'] diff --git a/src/engine/SCons/Tool/suncc.py b/src/engine/SCons/Tool/suncc.py index 458538b..4651219 100644 --- a/src/engine/SCons/Tool/suncc.py +++ b/src/engine/SCons/Tool/suncc.py @@ -34,7 +34,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import cc +from . import cc def generate(env): """ diff --git a/src/engine/SCons/Tool/sunf77.py b/src/engine/SCons/Tool/sunf77.py index d05ce54..20d1893 100644 --- a/src/engine/SCons/Tool/sunf77.py +++ b/src/engine/SCons/Tool/sunf77.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -from FortranCommon import add_all_to_env +from .FortranCommon import add_all_to_env compilers = ['sunf77', 'f77'] diff --git a/src/engine/SCons/Tool/sunf90.py b/src/engine/SCons/Tool/sunf90.py index 93b89c0..ce1697c 100644 --- a/src/engine/SCons/Tool/sunf90.py +++ b/src/engine/SCons/Tool/sunf90.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -from FortranCommon import add_all_to_env +from .FortranCommon import add_all_to_env compilers = ['sunf90', 'f90'] diff --git a/src/engine/SCons/Tool/sunf95.py b/src/engine/SCons/Tool/sunf95.py index c09026c..218569c 100644 --- a/src/engine/SCons/Tool/sunf95.py +++ b/src/engine/SCons/Tool/sunf95.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -from FortranCommon import add_all_to_env +from .FortranCommon import add_all_to_env compilers = ['sunf95', 'f95'] diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py index 5996a30..af13392 100644 --- a/src/engine/SCons/Tool/sunlink.py +++ b/src/engine/SCons/Tool/sunlink.py @@ -37,7 +37,7 @@ import os.path import SCons.Util -import link +from . import link ccLinker = None diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py index 5f24df0..febec35 100644 --- a/src/engine/SCons/Tool/tex.py +++ b/src/engine/SCons/Tool/tex.py @@ -163,15 +163,15 @@ def FindFile(name,suffixes,paths,env,requireExt=False): if ext: name = name + ext if Verbose: - print " searching for '%s' with extensions: " % name,suffixes + print(" searching for '%s' with extensions: " % name,suffixes) for path in paths: testName = os.path.join(path,name) if Verbose: - print " look for '%s'" % testName + print(" look for '%s'" % testName) if os.path.isfile(testName): if Verbose: - print " found '%s'" % testName + print(" found '%s'" % testName) return env.fs.File(testName) else: name_ext = SCons.Util.splitext(testName)[1] @@ -182,14 +182,14 @@ def FindFile(name,suffixes,paths,env,requireExt=False): for suffix in suffixes: testNameExt = testName + suffix if Verbose: - print " look for '%s'" % testNameExt + print(" look for '%s'" % testNameExt) if os.path.isfile(testNameExt): if Verbose: - print " found '%s'" % testNameExt + print(" found '%s'" % testNameExt) return env.fs.File(testNameExt) if Verbose: - print " did not find '%s'" % name + print(" did not find '%s'" % name) return None def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None): @@ -249,7 +249,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None saved_hashes[suffix] = theNode.get_csig() if Verbose: - print "hashes: ",saved_hashes + print("hashes: ",saved_hashes) must_rerun_latex = True @@ -268,12 +268,12 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if saved_hashes[suffix] == new_md5: if Verbose: - print "file %s not changed" % (targetbase+suffix) + print("file %s not changed" % (targetbase+suffix)) return False # unchanged saved_hashes[suffix] = new_md5 must_rerun_latex = True if Verbose: - print "file %s changed, rerunning Latex, new hash = " % (targetbase+suffix), new_md5 + print("file %s changed, rerunning Latex, new hash = " % (targetbase+suffix), new_md5) return True # changed # generate the file name that latex will generate @@ -322,8 +322,8 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None bcffiles = list(dups.keys()) if Verbose: - print "auxfiles ",auxfiles - print "bcffiles ",bcffiles + print("auxfiles ",auxfiles) + print("bcffiles ",bcffiles) # Now decide if bibtex will need to be run. # The information that bibtex reads from the .aux file is @@ -339,7 +339,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None content = open(target_aux, "rb").read() if content.find("bibdata") != -1: if Verbose: - print "Need to run bibtex on ",auxfilename + print("Need to run bibtex on ",auxfilename) bibfile = env.fs.File(SCons.Util.splitext(target_aux)[0]) result = BibTeXAction(bibfile, bibfile, env) if result != 0: @@ -362,7 +362,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None content = open(target_bcf, "rb").read() if content.find("bibdata") != -1: if Verbose: - print "Need to run biber on ",bcffilename + print("Need to run biber on ",bcffilename) bibfile = env.fs.File(SCons.Util.splitext(target_bcf)[0]) result = BiberAction(bibfile, bibfile, env) if result != 0: @@ -373,7 +373,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if check_MD5(suffix_nodes['.idx'],'.idx') or (count == 1 and run_makeindex): # We must run makeindex if Verbose: - print "Need to run makeindex" + print("Need to run makeindex") idxfile = suffix_nodes['.idx'] result = MakeIndexAction(idxfile, idxfile, env) if result != 0: @@ -391,7 +391,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if check_MD5(suffix_nodes['.nlo'],'.nlo') or (count == 1 and run_nomenclature): # We must run makeindex if Verbose: - print "Need to run makeindex for nomenclature" + print("Need to run makeindex for nomenclature") nclfile = suffix_nodes['.nlo'] result = MakeNclAction(nclfile, nclfile, env) if result != 0: @@ -403,7 +403,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if check_MD5(suffix_nodes['.glo'],'.glo') or (count == 1 and run_glossaries) or (count == 1 and run_glossary): # We must run makeindex if Verbose: - print "Need to run makeindex for glossary" + print("Need to run makeindex for glossary") glofile = suffix_nodes['.glo'] result = MakeGlossaryAction(glofile, glofile, env) if result != 0: @@ -415,7 +415,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if check_MD5(suffix_nodes['.acn'],'.acn') or (count == 1 and run_acronyms): # We must run makeindex if Verbose: - print "Need to run makeindex for acronyms" + print("Need to run makeindex for acronyms") acrfile = suffix_nodes['.acn'] result = MakeAcronymsAction(acrfile, acrfile, env) if result != 0: @@ -428,7 +428,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if check_MD5(suffix_nodes[newglossary_suffix[ig][2]],newglossary_suffix[ig][2]) or (count == 1): # We must run makeindex if Verbose: - print "Need to run makeindex for newglossary" + print("Need to run makeindex for newglossary") newglfile = suffix_nodes[newglossary_suffix[ig][2]] MakeNewGlossaryAction = SCons.Action.Action("$MAKENEWGLOSSARY ${SOURCE.filebase}%s -s ${SOURCE.filebase}.ist -t ${SOURCE.filebase}%s -o ${SOURCE.filebase}%s" % (newglossary_suffix[ig][2],newglossary_suffix[ig][0],newglossary_suffix[ig][1]), "$MAKENEWGLOSSARYCOMSTR") @@ -442,26 +442,26 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None if warning_rerun_re.search(logContent): must_rerun_latex = True if Verbose: - print "rerun Latex due to latex or package rerun warning" + print("rerun Latex due to latex or package rerun warning") if rerun_citations_re.search(logContent): must_rerun_latex = True if Verbose: - print "rerun Latex due to 'Rerun to get citations correct' warning" + print("rerun Latex due to 'Rerun to get citations correct' warning") if undefined_references_re.search(logContent): must_rerun_latex = True if Verbose: - print "rerun Latex due to undefined references or citations" + print("rerun Latex due to undefined references or citations") if (count >= int(env.subst('$LATEXRETRIES')) and must_rerun_latex): - print "reached max number of retries on Latex ,",int(env.subst('$LATEXRETRIES')) + print("reached max number of retries on Latex ,",int(env.subst('$LATEXRETRIES'))) # end of while loop # rename Latex's output to what the target name is if not (str(target[0]) == resultfilename and os.path.isfile(resultfilename)): if os.path.isfile(resultfilename): - print "move %s to %s" % (resultfilename, str(target[0]), ) + print("move %s to %s" % (resultfilename, str(target[0]), )) shutil.move(resultfilename,str(target[0])) # Original comment (when TEXPICTS was not restored): @@ -515,27 +515,27 @@ def is_LaTeX(flist,env,abspath): else: env['ENV']['TEXINPUTS'] = savedpath if Verbose: - print "is_LaTeX search path ",paths - print "files to search :",flist + print("is_LaTeX search path ",paths) + print("files to search :",flist) # Now that we have the search path and file list, check each one for f in flist: if Verbose: - print " checking for Latex source ",str(f) + print(" checking for Latex source ",str(f)) content = f.get_text_contents() if LaTeX_re.search(content): if Verbose: - print "file %s is a LaTeX file" % str(f) + print("file %s is a LaTeX file" % str(f)) return 1 if Verbose: - print "file %s is not a LaTeX file" % str(f) + print("file %s is not a LaTeX file" % str(f)) # now find included files inc_files = [ ] inc_files.extend( include_re.findall(content) ) if Verbose: - print "files included by '%s': "%str(f),inc_files + print("files included by '%s': "%str(f),inc_files) # inc_files is list of file names as given. need to find them # using TEXINPUTS paths. @@ -545,7 +545,7 @@ def is_LaTeX(flist,env,abspath): # make this a list since is_LaTeX takes a list. fileList = [srcNode,] if Verbose: - print "FindFile found ",srcNode + print("FindFile found ",srcNode) if srcNode is not None: file_test = is_LaTeX(fileList, env, abspath) @@ -554,7 +554,7 @@ def is_LaTeX(flist,env,abspath): return file_test if Verbose: - print " done scanning ",str(f) + print(" done scanning ",str(f)) return 0 @@ -619,15 +619,15 @@ def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphi content = theFile.get_text_contents() if Verbose: - print " scanning ",str(theFile) + print(" scanning ",str(theFile)) for i in range(len(file_tests_search)): if file_tests[i][0] is None: if Verbose: - print "scan i ",i," files_tests[i] ",file_tests[i], file_tests[i][1] + print("scan i ",i," files_tests[i] ",file_tests[i], file_tests[i][1]) file_tests[i][0] = file_tests_search[i].search(content) if Verbose and file_tests[i][0]: - print " found match for ",file_tests[i][1][-1] + print(" found match for ",file_tests[i][1][-1]) # for newglossary insert the suffixes in file_tests[i] if file_tests[i][0] and file_tests[i][1][-1] == 'newglossary': findresult = file_tests_search[i].findall(content) @@ -638,19 +638,19 @@ def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphi suffix_list = ['.'+findresult[l][0],'.'+findresult[l][2],'.'+findresult[l][3] ] newglossary_suffix.append(suffix_list) if Verbose: - print " new suffixes for newglossary ",newglossary_suffix + print(" new suffixes for newglossary ",newglossary_suffix) incResult = includeOnly_re.search(content) if incResult: aux_files.append(os.path.join(targetdir, incResult.group(1))) if Verbose: - print "\include file names : ", aux_files + print("\include file names : ", aux_files) # recursively call this on each of the included files inc_files = [ ] inc_files.extend( include_re.findall(content) ) if Verbose: - print "files included by '%s': "%str(theFile),inc_files + print("files included by '%s': "%str(theFile),inc_files) # inc_files is list of file names as given. need to find them # using TEXINPUTS paths. @@ -659,7 +659,7 @@ def ScanFiles(theFile, target, paths, file_tests, file_tests_search, env, graphi if srcNode is not None: file_tests = ScanFiles(srcNode, target, paths, file_tests, file_tests_search, env, graphics_extensions, targetdir, aux_files) if Verbose: - print " done scanning ",str(theFile) + print(" done scanning ",str(theFile)) return file_tests def tex_emitter_core(target, source, env, graphics_extensions): @@ -689,7 +689,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): env.SideEffect(logfilename,target[0]) env.SideEffect(flsfilename,target[0]) if Verbose: - print "side effect :",auxfilename,logfilename,flsfilename + print("side effect :",auxfilename,logfilename,flsfilename) env.Clean(target[0],auxfilename) env.Clean(target[0],logfilename) env.Clean(target[0],flsfilename) @@ -765,7 +765,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): else: env['ENV']['TEXINPUTS'] = savedpath if Verbose: - print "search path ",paths + print("search path ",paths) # scan all sources for side effect files aux_files = [] @@ -774,7 +774,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): for (theSearch,suffix_list) in file_tests: # add side effects if feature is present.If file is to be generated,add all side effects if Verbose and theSearch: - print "check side effects for ",suffix_list[-1] + print("check side effects for ",suffix_list[-1]) if (theSearch != None) or (not source[0].exists() ): file_list = [targetbase,] # for bibunit we need a list of files @@ -788,11 +788,11 @@ def tex_emitter_core(target, source, env, graphics_extensions): if suffix_list[-1] == 'multibib': for multibibmatch in multibib_re.finditer(content): if Verbose: - print "multibib match ",multibibmatch.group(1) + print("multibib match ",multibibmatch.group(1)) if multibibmatch != None: baselist = multibibmatch.group(1).split(',') if Verbose: - print "multibib list ", baselist + print("multibib list ", baselist) for i in range(len(baselist)): file_list.append(os.path.join(targetdir, baselist[i])) # now define the side effects @@ -800,14 +800,14 @@ def tex_emitter_core(target, source, env, graphics_extensions): for suffix in suffix_list[:-1]: env.SideEffect(file_name + suffix,target[0]) if Verbose: - print "side effect tst :",file_name + suffix, " target is ",str(target[0]) + print("side effect tst :",file_name + suffix, " target is ",str(target[0])) env.Clean(target[0],file_name + suffix) for aFile in aux_files: aFile_base = SCons.Util.splitext(aFile)[0] env.SideEffect(aFile_base + '.aux',target[0]) if Verbose: - print "side effect aux :",aFile_base + '.aux' + print("side effect aux :",aFile_base + '.aux') env.Clean(target[0],aFile_base + '.aux') # read fls file to get all other files that latex creates and will read on the next pass # remove files from list that we explicitly dealt with above @@ -820,7 +820,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): out_files.remove(filename) env.SideEffect(out_files,target[0]) if Verbose: - print "side effect fls :",out_files + print("side effect fls :",out_files) env.Clean(target[0],out_files) return (target, source) @@ -840,7 +840,7 @@ def generate(env): generate_common(env) - import dvi + from . import dvi dvi.generate(env) bld = env['BUILDERS']['DVI'] diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py index 8dc8f4b..4897113 100644 --- a/src/engine/SCons/Tool/textfile.py +++ b/src/engine/SCons/Tool/textfile.py @@ -54,6 +54,7 @@ import re from SCons.Node import Node from SCons.Node.Python import Value from SCons.Util import is_String, is_Sequence, is_Dict +import collections def _do_subst(node, subs): """ @@ -96,7 +97,7 @@ def _action(target, source, env): raise SCons.Errors.UserError('SUBST_DICT must be dict or sequence') subs = [] for (k,v) in d: - if callable(v): + if isinstance(v, collections.Callable): v = v() if is_String(v): v = env.subst(v) @@ -107,7 +108,7 @@ def _action(target, source, env): # write the file try: fd = open(target[0].get_path(), "wb") - except (OSError,IOError), e: + except (OSError,IOError) as e: raise SCons.Errors.UserError("Can't write target file %s" % target[0]) # separate lines by 'linesep' only if linesep is not empty lsep = None diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index 64436b8..489d4d7 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -55,7 +55,7 @@ class _CmdRunner(object): proc = SCons.Action._subproc(env, command, **kw) self.out, self.err = proc.communicate() self.status = proc.wait() - if self.err: sys.stderr.write(unicode(self.err)) + if self.err: sys.stderr.write(str(self.err)) return self.status def strfunction(self, target, source, env): @@ -153,7 +153,7 @@ from SCons.Builder import BuilderBase class _POTBuilder(BuilderBase): def _execute(self, env, target, source, *args): if not target: - if env.has_key('POTDOMAIN') and env['POTDOMAIN']: + if 'POTDOMAIN' in env and env['POTDOMAIN']: domain = env['POTDOMAIN'] else: domain = 'messages' @@ -175,7 +175,7 @@ def _scan_xgettext_from_files(target, source, env, files = None, path = None): files = [ files ] if path is None: - if env.has_key('XGETTEXTPATH'): + if 'XGETTEXTPATH' in env: path = env['XGETTEXTPATH'] else: path = [] @@ -222,7 +222,7 @@ def _pot_update_emitter(target, source, env): import SCons.Util import SCons.Node.FS - if env.has_key('XGETTEXTFROM'): + if 'XGETTEXTFROM' in env: xfrom = env['XGETTEXTFROM'] else: return target, source diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 822d524..f2e5325 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -33,15 +33,16 @@ import re import types from collections import UserDict, UserList, UserString +import collections # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. InstanceType = types.InstanceType MethodType = types.MethodType FunctionType = types.FunctionType -try: unicode +try: str except NameError: UnicodeType = None -else: UnicodeType = unicode +else: UnicodeType = str def dictify(keys, values, result={}): for k, v in zip(keys, values): @@ -111,7 +112,7 @@ class NodeList(UserList): >>> someList.strip() [ 'foo', 'bar' ] """ - def __nonzero__(self): + def __bool__(self): return len(self.data) != 0 def __str__(self): @@ -153,7 +154,7 @@ class DisplayEngine(object): return if append_newline: text = text + '\n' try: - sys.stdout.write(unicode(text)) + sys.stdout.write(str(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed @@ -239,7 +240,7 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): ' N = no clean\n' + ' H = no cache\n' + '\n') - sys.stdout.write(unicode(legend)) + sys.stdout.write(str(legend)) tags = ['['] tags.append(' E'[IDX(root.exists())]) @@ -264,10 +265,10 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): children = child_func(root) if prune and rname in visited and children: - sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + u'\n') + sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + '\n') return - sys.stdout.write(''.join(tags + margins + ['+-', rname]) + u'\n') + sys.stdout.write(''.join(tags + margins + ['+-', rname]) + '\n') visited[rname] = 1 @@ -303,11 +304,11 @@ SequenceTypes = (list, tuple, UserList) # Note that profiling data shows a speed-up when comparing # explicitely with str and unicode instead of simply comparing # with basestring. (at least on Python 2.5.1) -StringTypes = (str, unicode, UserString) +StringTypes = (str, str, UserString) # Empirically, it is faster to check explicitely for str and # unicode than for basestring. -BaseStringTypes = (str, unicode) +BaseStringTypes = (str, str) def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes): return isinstance(obj, DictTypes) @@ -440,7 +441,7 @@ _semi_deepcopy_dispatch = d = {} def semi_deepcopy_dict(x, exclude = [] ): copy = {} - for key, val in x.items(): + for key, val in list(x.items()): # The regular Python copy.deepcopy() also deepcopies the key, # as follows: # @@ -465,7 +466,7 @@ def semi_deepcopy(x): if copier: return copier(x) else: - if hasattr(x, '__semi_deepcopy__') and callable(x.__semi_deepcopy__): + if hasattr(x, '__semi_deepcopy__') and isinstance(x.__semi_deepcopy__, collections.Callable): return x.__semi_deepcopy__() elif isinstance(x, UserDict): return x.__class__(semi_deepcopy_dict(x)) @@ -718,7 +719,7 @@ else: # raised so as to not mask possibly serious disk or # network issues. continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: try: reject.index(f) except ValueError: @@ -979,7 +980,7 @@ class OrderedDict(UserDict): if key not in self._keys: self._keys.append(key) def update(self, dict): - for (key, val) in dict.items(): + for (key, val) in list(dict.items()): self.__setitem__(key, val) def values(self): @@ -1001,7 +1002,7 @@ class Selector(OrderedDict): # Try to perform Environment substitution on the keys of # the dictionary before giving up. s_dict = {} - for (k,v) in self.items(): + for (k,v) in list(self.items()): if k is not None: s_k = env.subst(k) if s_k in s_dict: @@ -1360,7 +1361,7 @@ def AddMethod(obj, function, name=None): print a.listIndex(5) """ if name is None: - name = function.func_name + name = function.__name__ else: function = RenameFunction(function, name) @@ -1376,10 +1377,10 @@ def RenameFunction(function, name): Returns a function identical to the specified function, but with the specified name. """ - return FunctionType(function.func_code, - function.func_globals, + return FunctionType(function.__code__, + function.__globals__, name, - function.func_defaults) + function.__defaults__) md5 = False @@ -1461,7 +1462,7 @@ class Null(object): return self def __repr__(self): return "Null(0x%08X)" % id(self) - def __nonzero__(self): + def __bool__(self): return False def __getattr__(self, name): return self diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index a1e6756..a30404c 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -219,7 +219,7 @@ class UtilTestCase(unittest.TestCase): assert not is_Dict(()) assert not is_Dict("") if HasUnicode: - exec "assert not is_Dict(u'')" + exec("assert not is_Dict(u'')") def test_is_List(self): assert is_List([]) @@ -235,12 +235,12 @@ class UtilTestCase(unittest.TestCase): assert not is_List({}) assert not is_List("") if HasUnicode: - exec "assert not is_List(u'')" + exec("assert not is_List(u'')") def test_is_String(self): assert is_String("") if HasUnicode: - exec "assert is_String(u'')" + exec("assert is_String(u'')") assert is_String(UserString('')) try: class mystr(str): @@ -266,7 +266,7 @@ class UtilTestCase(unittest.TestCase): assert not is_Tuple({}) assert not is_Tuple("") if HasUnicode: - exec "assert not is_Tuple(u'')" + exec("assert not is_Tuple(u'')") def test_to_String(self): """Test the to_String() method.""" @@ -285,16 +285,16 @@ class UtilTestCase(unittest.TestCase): assert to_String(s2) == 'foo', s2 if HasUnicode: - s3=UserString(unicode('bar')) + s3=UserString(str('bar')) assert to_String(s3) == s3, s3 - assert to_String(s3) == unicode('bar'), s3 - assert isinstance(to_String(s3), unicode), \ + assert to_String(s3) == str('bar'), s3 + assert isinstance(to_String(s3), str), \ type(to_String(s3)) if HasUnicode: - s4 = unicode('baz') - assert to_String(s4) == unicode('baz'), to_String(s4) - assert isinstance(to_String(s4), unicode), \ + s4 = str('baz') + assert to_String(s4) == str('baz'), to_String(s4) + assert isinstance(to_String(s4), str), \ type(to_String(s4)) def test_WhereIs(self): @@ -313,10 +313,10 @@ class UtilTestCase(unittest.TestCase): os.mkdir(sub2_xxx_exe) test.write(sub3_xxx_exe, "\n") - os.chmod(sub3_xxx_exe, 0777) + os.chmod(sub3_xxx_exe, 0o777) test.write(sub4_xxx_exe, "\n") - os.chmod(sub4_xxx_exe, 0777) + os.chmod(sub4_xxx_exe, 0o777) env_path = os.environ['PATH'] @@ -681,7 +681,7 @@ bling fobj = io.StringIO(content) except TypeError: # Python 2.7 and beyond require unicode strings. - fobj = io.StringIO(unicode(content)) + fobj = io.StringIO(str(content)) lines = LogicalLines(fobj).readlines() assert lines == [ @@ -696,7 +696,7 @@ bling s1 = silent_intern("spam") # Python 3.x does not have a unicode() global function if sys.version[0] == '2': - s2 = silent_intern(unicode("unicode spam")) + s2 = silent_intern(str("unicode spam")) s3 = silent_intern(42) s4 = silent_intern("spam") assert id(s1) == id(s4) diff --git a/src/engine/SCons/Variables/EnumVariableTests.py b/src/engine/SCons/Variables/EnumVariableTests.py index f4b600d..4feb712 100644 --- a/src/engine/SCons/Variables/EnumVariableTests.py +++ b/src/engine/SCons/Variables/EnumVariableTests.py @@ -122,7 +122,7 @@ class EnumVariableTestCase(unittest.TestCase): 'C' : ['C', 'three', 'three'], } - for k, l in table.items(): + for k, l in list(table.items()): x = o0.converter(k) assert x == l[0], "o0 got %s, expected %s" % (x, l[0]) x = o1.converter(k) @@ -186,7 +186,7 @@ class EnumVariableTestCase(unittest.TestCase): 'no_v' : [invalid, invalid, invalid], } - for v, l in table.items(): + for v, l in list(table.items()): l[0](o0, v) l[1](o1, v) l[2](o2, v) diff --git a/src/engine/SCons/Variables/PathVariableTests.py b/src/engine/SCons/Variables/PathVariableTests.py index 084154b..2fa46eb 100644 --- a/src/engine/SCons/Variables/PathVariableTests.py +++ b/src/engine/SCons/Variables/PathVariableTests.py @@ -65,7 +65,7 @@ class PathVariableTestCase(unittest.TestCase): dne = test.workpath('does_not_exist') try: o.validator('X', dne, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'Path for option X does not exist: %s' % dne, e except: raise Exception("did not catch expected UserError") @@ -89,7 +89,7 @@ class PathVariableTestCase(unittest.TestCase): f = test.workpath('file') try: o.validator('X', f, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'Directory path for option X is a file: %s' % f, e except: raise Exception("did not catch expected UserError") @@ -97,7 +97,7 @@ class PathVariableTestCase(unittest.TestCase): dne = test.workpath('does_not_exist') try: o.validator('X', dne, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'Directory path for option X does not exist: %s' % dne, e except: raise Exception("did not catch expected UserError") @@ -122,7 +122,7 @@ class PathVariableTestCase(unittest.TestCase): f = test.workpath('file') try: o.validator('X', f, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'Path for option X is a file, not a directory: %s' % f, e except: raise Exception("did not catch expected UserError") @@ -146,7 +146,7 @@ class PathVariableTestCase(unittest.TestCase): d = test.workpath('d') try: o.validator('X', d, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'File path for option X does not exist: %s' % d, e except: raise Exception("did not catch expected UserError") @@ -154,7 +154,7 @@ class PathVariableTestCase(unittest.TestCase): dne = test.workpath('does_not_exist') try: o.validator('X', dne, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: assert str(e) == 'File path for option X does not exist: %s' % dne, e except: raise Exception("did not catch expected UserError") @@ -198,7 +198,7 @@ class PathVariableTestCase(unittest.TestCase): dne = test.workpath('does_not_exist') try: o.validator('X', dne, {}) - except SCons.Errors.UserError, e: + except SCons.Errors.UserError as e: expect = 'Path for option X does not exist: %s' % dne assert str(e) == expect, e else: @@ -217,7 +217,7 @@ class PathVariableTestCase(unittest.TestCase): try: o.validator('Y', 'value', {}) - except Exception, e: + except Exception as e: assert str(e) == 'my_validator() got called for Y, value!', e else: raise Exception("did not catch expected exception from my_validator()") diff --git a/src/engine/SCons/Variables/VariablesTests.py b/src/engine/SCons/Variables/VariablesTests.py index ad46bd6..520c8e3 100644 --- a/src/engine/SCons/Variables/VariablesTests.py +++ b/src/engine/SCons/Variables/VariablesTests.py @@ -55,7 +55,7 @@ def check(key, value, env): def checkSave(file, expected): gdict = {} ldict = {} - exec open(file, 'rU').read() in gdict, ldict + exec(open(file, 'rU').read(), gdict, ldict) assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict) class VariablesTestCase(unittest.TestCase): diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py index ede7480..8d15b8d 100644 --- a/src/engine/SCons/Variables/__init__.py +++ b/src/engine/SCons/Variables/__init__.py @@ -36,11 +36,11 @@ import SCons.Errors import SCons.Util import SCons.Warnings -from BoolVariable import BoolVariable # okay -from EnumVariable import EnumVariable # okay -from ListVariable import ListVariable # naja -from PackageVariable import PackageVariable # naja -from PathVariable import PathVariable # okay +from .BoolVariable import BoolVariable # okay +from .EnumVariable import EnumVariable # okay +from .ListVariable import ListVariable # naja +from .PackageVariable import PackageVariable # naja +from .PathVariable import PathVariable # okay class Variables(object): @@ -170,7 +170,7 @@ class Variables(object): sys.path.insert(0, dir) try: values['__name__'] = filename - exec open(filename, 'rU').read() in {}, values + exec(open(filename, 'rU').read(), {}, values) finally: if dir: del sys.path[0] @@ -180,7 +180,7 @@ class Variables(object): if args is None: args = self.args - for arg, value in args.items(): + for arg, value in list(args.items()): added = False for option in self.options: if arg in list(option.aliases) + [ option.key ]: @@ -206,7 +206,7 @@ class Variables(object): env[option.key] = option.converter(value) except TypeError: env[option.key] = option.converter(value, env) - except ValueError, x: + except ValueError as x: raise SCons.Errors.UserError('Error converting option: %s\n%s'%(option.key, x)) @@ -268,7 +268,7 @@ class Variables(object): finally: fh.close() - except IOError, x: + except IOError as x: raise SCons.Errors.UserError('Error writing options to file: %s\n%s' % (filename, x)) def GenerateHelpText(self, env, sort=None): diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py index c870fbc..6f1a7ee 100644 --- a/src/engine/SCons/compat/__init__.py +++ b/src/engine/SCons/compat/__init__.py @@ -87,7 +87,7 @@ def rename_module(new, old): rename_module('builtins', '__builtin__') -import _scons_builtins +from . import _scons_builtins try: diff --git a/src/engine/SCons/compat/_scons_subprocess.py b/src/engine/SCons/compat/_scons_subprocess.py index eebe53d..72581f7 100644 --- a/src/engine/SCons/compat/_scons_subprocess.py +++ b/src/engine/SCons/compat/_scons_subprocess.py @@ -439,22 +439,22 @@ except TypeError: def is_int(obj): return isinstance(obj, type(1)) def is_int_or_long(obj): - return type(obj) in (type(1), type(1L)) + return type(obj) in (type(1), type(1)) else: def is_int(obj): return isinstance(obj, int) def is_int_or_long(obj): - return isinstance(obj, (int, long)) + return isinstance(obj, int) try: - types.StringTypes + str except AttributeError: try: - types.StringTypes = (str, unicode) + str = (str, str) except NameError: - types.StringTypes = (str,) + str = (str,) def is_string(obj): - return isinstance(obj, types.StringTypes) + return isinstance(obj, str) _active = [] @@ -785,7 +785,7 @@ class Popen(object): errread, errwrite): """Execute program (MS Windows version)""" - if not isinstance(args, types.StringTypes): + if not isinstance(args, str): args = list2cmdline(args) # Process startup details @@ -802,7 +802,7 @@ class Popen(object): startupinfo.wShowWindow = SW_HIDE comspec = os.environ.get("COMSPEC", "cmd.exe") args = comspec + " /c " + args - if (GetVersion() >= 0x80000000L or + if (GetVersion() >= 0x80000000 or os.path.basename(comspec).lower() == "command.com"): # Win9x, or using command.com on NT. We need to # use the w9xpopen intermediate program. For more @@ -830,7 +830,7 @@ class Popen(object): env, cwd, startupinfo) - except pywintypes.error, e: + except pywintypes.error as e: # Translate pywintypes.error to WindowsError, which is # a subclass of OSError. FIXME: We should really # translate errno using _sys_errlist (or simliar), but @@ -1215,8 +1215,8 @@ def _demo_posix(): # Example 1: Simple redirection: Get process list # plist = Popen(["ps"], stdout=PIPE).communicate()[0] - print "Process list:" - print plist + print("Process list:") + print(plist) # # Example 2: Change uid before executing child @@ -1228,25 +1228,25 @@ def _demo_posix(): # # Example 3: Connecting several subprocesses # - print "Looking for 'hda'..." + print("Looking for 'hda'...") p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) - print repr(p2.communicate()[0]) + print(repr(p2.communicate()[0])) # # Example 4: Catch execution error # - print - print "Trying a weird file..." + print() + print("Trying a weird file...") try: - print Popen(["/this/path/does/not/exist"]).communicate() - except OSError, e: + print(Popen(["/this/path/does/not/exist"]).communicate()) + except OSError as e: if e.errno == errno.ENOENT: - print "The file didn't exist. I thought so..." - print "Child traceback:" - print e.child_traceback + print("The file didn't exist. I thought so...") + print("Child traceback:") + print(e.child_traceback) else: - print "Error", e.errno + print("Error", e.errno) else: sys.stderr.write( "Gosh. No error.\n" ) @@ -1255,15 +1255,15 @@ def _demo_windows(): # # Example 1: Connecting several subprocesses # - print "Looking for 'PROMPT' in set output..." + print("Looking for 'PROMPT' in set output...") p1 = Popen("set", stdout=PIPE, shell=True) p2 = Popen('find "PROMPT"', stdin=p1.stdout, stdout=PIPE) - print repr(p2.communicate()[0]) + print(repr(p2.communicate()[0])) # # Example 2: Simple execution of program # - print "Executing calc..." + print("Executing calc...") p = Popen("calc") p.wait() diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index 0ba10f5..4cc771b 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -31,6 +31,7 @@ import SCons.compat import os import re +import collections # # First "subsystem" of regular expressions that we set up: @@ -72,7 +73,7 @@ cpp_lines_dict = { # the corresponding compiled regular expression that fetches the arguments # we care about. Table = {} -for op_list, expr in cpp_lines_dict.items(): +for op_list, expr in list(cpp_lines_dict.items()): e = re.compile(expr) for op in op_list: Table[op] = e @@ -87,7 +88,7 @@ del op_list override = { 'if' : 'if(?!def)', } -l = [override.get(x, x) for x in Table.keys()] +l = [override.get(x, x) for x in list(Table.keys())] # Turn the list of expressions into one big honkin' regular expression @@ -130,7 +131,7 @@ CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)] # re module, as late as version 2.2.2, empirically matches the # "!" in "!=" first, instead of finding the longest match. # What's up with that? -l = sorted(CPP_to_Python_Ops_Dict.keys(), key=lambda a: len(a), reverse=True) +l = sorted(list(CPP_to_Python_Ops_Dict.keys()), key=lambda a: len(a), reverse=True) # Turn the list of keys into one regular expression that will allow us # to substitute all of the operators at once. @@ -266,7 +267,7 @@ class PreProcessor(object): d = { 'scons_current_file' : self.scons_current_file } - for op in Table.keys(): + for op in list(Table.keys()): d[op] = getattr(self, 'do_' + op) self.default_table = d @@ -552,7 +553,7 @@ class PreProcessor(object): except KeyError: m = function_name.search(s) s = self.cpp_namespace[m.group(1)] - if callable(s): + if isinstance(s, collections.Callable): args = function_arg_separator.split(m.group(2)) s = s(*args) if not s: diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 2f2025b..5566e53 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -27,7 +27,7 @@ import atexit import sys import unittest -import cpp +from . import cpp diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index f4ba90a..89b9856 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -14,20 +14,20 @@ keep_all_files = 00000 ignore_corrupt_dbfiles = 0 def corruption_warning(filename): - print "Warning: Discarding corrupt database:", filename + print("Warning: Discarding corrupt database:", filename) -try: unicode +try: str except NameError: def is_string(s): return isinstance(s, str) else: def is_string(s): - return type(s) in (str, unicode) + return type(s) in (str, str) try: - unicode('a') + str('a') except NameError: - def unicode(s): return s + def str(s): return s dblite_suffix = '.dblite' tmp_suffix = '.tmp' @@ -77,7 +77,7 @@ class dblite(object): statinfo = os.stat(self._file_name) self._chown_to = statinfo.st_uid self._chgrp_to = statinfo.st_gid - except OSError, e: + except OSError as e: # db file doesn't exist yet. # Check os.environ for SUDO_UID, use if set self._chown_to = int(os.environ.get('SUDO_UID', -1)) @@ -90,7 +90,7 @@ class dblite(object): else: try: f = self._open(self._file_name, "rb") - except IOError, e: + except IOError as e: if (self._flag != "c"): raise e self._open(self._file_name, "wb", self._mode) @@ -122,7 +122,7 @@ class dblite(object): # (e.g. from a previous run as root). We should still be able to # unlink() the file if the directory's writable, though, so ignore # any OSError exception thrown by the chmod() call. - try: self._os_chmod(self._file_name, 0777) + try: self._os_chmod(self._file_name, 0o777) except OSError: pass self._os_unlink(self._file_name) self._os_rename(self._tmp_name, self._file_name) @@ -151,7 +151,7 @@ class dblite(object): if (not is_string(value)): raise TypeError("value `%s' must be a string but is %s" % (value, type(value))) self._dict[key] = value - self._needs_sync = 0001 + self._needs_sync = 0o001 def keys(self): return list(self._dict.keys()) @@ -171,7 +171,7 @@ class dblite(object): def __len__(self): return len(self._dict) -def open(file, flag=None, mode=0666): +def open(file, flag=None, mode=0o666): return dblite(file, flag, mode) def _exercise(): @@ -179,26 +179,26 @@ def _exercise(): assert len(db) == 0 db["foo"] = "bar" assert db["foo"] == "bar" - db[unicode("ufoo")] = unicode("ubar") - assert db[unicode("ufoo")] == unicode("ubar") + db[str("ufoo")] = str("ubar") + assert db[str("ufoo")] == str("ubar") db.sync() db = open("tmp", "c") assert len(db) == 2, len(db) assert db["foo"] == "bar" db["bar"] = "foo" assert db["bar"] == "foo" - db[unicode("ubar")] = unicode("ufoo") - assert db[unicode("ubar")] == unicode("ufoo") + db[str("ubar")] = str("ufoo") + assert db[str("ubar")] == str("ufoo") db.sync() db = open("tmp", "r") assert len(db) == 4, len(db) assert db["foo"] == "bar" assert db["bar"] == "foo" - assert db[unicode("ufoo")] == unicode("ubar") - assert db[unicode("ubar")] == unicode("ufoo") + assert db[str("ufoo")] == str("ubar") + assert db[str("ubar")] == str("ufoo") try: db.sync() - except IOError, e: + except IOError as e: assert str(e) == "Read-only database: tmp.dblite" else: raise RuntimeError("IOError expected.") @@ -208,13 +208,13 @@ def _exercise(): db.sync() try: db[(1,2)] = "tuple" - except TypeError, e: + except TypeError as e: assert str(e) == "key `(1, 2)' must be a string but is ", str(e) else: raise RuntimeError("TypeError exception expected") try: db["list"] = [1,2] - except TypeError, e: + except TypeError as e: assert str(e) == "value `[1, 2]' must be a string but is ", str(e) else: raise RuntimeError("TypeError exception expected") @@ -238,11 +238,11 @@ def _exercise(): os.unlink("tmp.dblite") try: db = open("tmp", "w") - except IOError, e: + except IOError as e: assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e) else: raise RuntimeError("IOError expected.") - print "OK" + print("OK") if (__name__ == "__main__"): _exercise() diff --git a/src/script/scons-time.py b/src/script/scons-time.py index 3b215f9..4296192 100644 --- a/src/script/scons-time.py +++ b/src/script/scons-time.py @@ -29,8 +29,8 @@ # 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 division -from __future__ import nested_scopes + + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -42,6 +42,7 @@ import shutil import sys import tempfile import time +import collections try: sorted @@ -109,8 +110,8 @@ def HACK_for_exec(cmd, *args): internal functions. ''' if not args: exec(cmd) - elif len(args) == 1: exec cmd in args[0] - else: exec cmd in args[0], args[1] + elif len(args) == 1: exec(cmd, args[0]) + else: exec(cmd, args[0], args[1]) class Plotter(object): def increment_size(self, largest): @@ -146,7 +147,7 @@ class Line(object): def print_label(self, inx, x, y): if self.label: - print 'set label %s "%s" at %s,%s right' % (inx, self.label, x, y) + print('set label %s "%s" at %s,%s right' % (inx, self.label, x, y)) def plot_string(self): if self.title: @@ -159,15 +160,15 @@ class Line(object): if fmt is None: fmt = self.fmt if self.comment: - print '# %s' % self.comment + print('# %s' % self.comment) for x, y in self.points: # If y is None, it usually represents some kind of break # in the line's index number. We might want to represent # this some way rather than just drawing the line straight # between the two points on either side. if not y is None: - print fmt % (x, y) - print 'e' + print(fmt % (x, y)) + print('e') def get_x_values(self): return [ p[0] for p in self.points ] @@ -253,8 +254,8 @@ class Gnuplotter(Plotter): return if self.title: - print 'set title "%s"' % self.title - print 'set key %s' % self.key_location + print('set title "%s"' % self.title) + print('set key %s' % self.key_location) min_y = self.get_min_y() max_y = self.max_graph_value(self.get_max_y()) @@ -269,7 +270,7 @@ class Gnuplotter(Plotter): inx += 1 plot_strings = [ self.plot_string(l) for l in self.lines ] - print 'plot ' + ', \\\n '.join(plot_strings) + print('plot ' + ', \\\n '.join(plot_strings)) for line in self.lines: line.print_points() @@ -455,7 +456,7 @@ class SConsTimer(object): Each message is prepended with a standard prefix of our name plus the time. """ - if callable(msg): + if isinstance(msg, collections.Callable): msg = msg(*args) else: msg = msg % args @@ -474,7 +475,7 @@ class SConsTimer(object): The action is called if it's a callable Python function, and otherwise passed to os.system(). """ - if callable(action): + if isinstance(action, collections.Callable): action(*args) else: os.system(action % args) @@ -540,7 +541,7 @@ class SConsTimer(object): header_fmt = ' '.join(['%12s'] * len(columns)) line_fmt = header_fmt + ' %s' - print header_fmt % columns + print(header_fmt % columns) for file in files: t = line_function(file, *args, **kw) @@ -550,7 +551,7 @@ class SConsTimer(object): if diff > 0: t += [''] * diff t.append(file_function(file)) - print line_fmt % tuple(t) + print(line_fmt % tuple(t)) def collect_results(self, files, function, *args, **kw): results = {} @@ -690,13 +691,13 @@ class SConsTimer(object): """ try: import pstats - except ImportError, e: + except ImportError as e: sys.stderr.write('%s: func: %s\n' % (self.name, e)) sys.stderr.write('%s This version of Python is missing the profiler.\n' % self.name_spaces) sys.stderr.write('%s Cannot use the "func" subcommand.\n' % self.name_spaces) sys.exit(1) statistics = pstats.Stats(file).stats - matches = [ e for e in statistics.items() if e[0][2] == function ] + matches = [ e for e in list(statistics.items()) if e[0][2] == function ] r = matches[0] return r[0][0], r[0][1], r[0][2], r[1][3] @@ -751,7 +752,7 @@ class SConsTimer(object): return self.default(argv) try: return func(argv) - except TypeError, e: + except TypeError as e: sys.stderr.write("%s %s: %s\n" % (self.name, cmdName, e)) import traceback traceback.print_exc(file=sys.stderr) @@ -856,7 +857,7 @@ class SConsTimer(object): self.title = a if self.config_file: - exec open(self.config_file, 'rU').read() in self.__dict__ + exec(open(self.config_file, 'rU').read(), self.__dict__) if self.chdir: os.chdir(self.chdir) @@ -889,13 +890,13 @@ class SConsTimer(object): try: f, line, func, time = \ self.get_function_profile(file, function_name) - except ValueError, e: + except ValueError as e: sys.stderr.write("%s: func: %s: %s\n" % (self.name, file, e)) else: if f.startswith(cwd_): f = f[len(cwd_):] - print "%.3f %s:%d(%s)" % (time, f, line, func) + print("%.3f %s:%d(%s)" % (time, f, line, func)) elif format == 'gnuplot': @@ -1233,7 +1234,7 @@ class SConsTimer(object): sys.exit(1) if self.config_file: - exec open(self.config_file, 'rU').read() in self.__dict__ + exec(open(self.config_file, 'rU').read(), self.__dict__) if args: self.archive_list = args @@ -1466,7 +1467,7 @@ class SConsTimer(object): elif o in ('--title',): self.title = a elif o in ('--which',): - if not a in self.time_strings.keys(): + if not a in list(self.time_strings.keys()): sys.stderr.write('%s: time: Unrecognized timer "%s".\n' % (self.name, a)) sys.stderr.write('%s Type "%s help time" for help.\n' % (self.name_spaces, self.name)) sys.exit(1) diff --git a/src/script/sconsign.py b/src/script/sconsign.py index e5e9d4f..323d1bf 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -171,7 +171,7 @@ sys.path = libs + sys.path import SCons.compat # so pickle will import cPickle instead -import whichdb +import dbm import time import pickle import imp @@ -189,8 +189,8 @@ def my_whichdb(filename): pass return _orig_whichdb(filename) -_orig_whichdb = whichdb.whichdb -whichdb.whichdb = my_whichdb +_orig_whichdb = dbm.whichdb +dbm.whichdb = my_whichdb def my_import(mname): if '.' in mname: @@ -310,14 +310,14 @@ def printfield(name, entry, prefix=""): outlist = field("implicit", entry, 0) if outlist: if Verbose: - print " implicit:" - print " " + outlist + print(" implicit:") + print(" " + outlist) outact = field("action", entry, 0) if outact: if Verbose: - print " action: " + outact + print(" action: " + outact) else: - print " " + outact + print(" " + outact) def printentries(entries, location): if Print_Entries: @@ -330,9 +330,9 @@ def printentries(entries, location): try: ninfo = entry.ninfo except AttributeError: - print name + ":" + print(name + ":") else: - print nodeinfo_string(name, entry.ninfo) + print(nodeinfo_string(name, entry.ninfo)) printfield(name, entry.binfo) else: for name in sorted(entries.keys()): @@ -340,9 +340,9 @@ def printentries(entries, location): try: ninfo = entry.ninfo except AttributeError: - print name + ":" + print(name + ":") else: - print nodeinfo_string(name, entry.ninfo) + print(nodeinfo_string(name, entry.ninfo)) printfield(name, entry.binfo) class Do_SConsignDB(object): @@ -361,7 +361,7 @@ class Do_SConsignDB(object): # .sconsign => .sconsign.dblite # .sconsign.dblite => .sconsign.dblite.dblite db = self.dbm.open(fname, "r") - except (IOError, OSError), e: + except (IOError, OSError) as e: print_e = e try: # That didn't work, so try opening the base name, @@ -375,7 +375,7 @@ class Do_SConsignDB(object): # suffix-mangling). try: open(fname, "r") - except (IOError, OSError), e: + except (IOError, OSError) as e: # Nope, that file doesn't even exist, so report that # fact back. print_e = e @@ -386,7 +386,7 @@ class Do_SConsignDB(object): except pickle.UnpicklingError: sys.stderr.write("sconsign: ignoring invalid `%s' file `%s'\n" % (self.dbm_name, fname)) return - except Exception, e: + except Exception as e: sys.stderr.write("sconsign: ignoring invalid `%s' file `%s': %s\n" % (self.dbm_name, fname, e)) return @@ -403,13 +403,13 @@ class Do_SConsignDB(object): self.printentries(dir, db[dir]) def printentries(self, dir, val): - print '=== ' + dir + ':' + print('=== ' + dir + ':') printentries(pickle.loads(val), dir) def Do_SConsignDir(name): try: fp = open(name, 'rb') - except (IOError, OSError), e: + except (IOError, OSError) as e: sys.stderr.write("sconsign: %s\n" % (e)) return try: @@ -419,7 +419,7 @@ def Do_SConsignDir(name): except pickle.UnpicklingError: sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s'\n" % (name)) return - except Exception, e: + except Exception as e: sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s': %s\n" % (name, e)) return printentries(sconsign.entries, args[0]) @@ -471,13 +471,13 @@ for o, a in opts: dbm = my_import(dbm_name) except: sys.stderr.write("sconsign: illegal file format `%s'\n" % a) - print helpstr + print(helpstr) sys.exit(2) Do_Call = Do_SConsignDB(a, dbm) else: Do_Call = Do_SConsignDir elif o in ('-h', '--help'): - print helpstr + print(helpstr) sys.exit(0) elif o in ('-i', '--implicit'): Print_Flags['implicit'] = 1 @@ -497,7 +497,7 @@ if Do_Call: Do_Call(a) else: for a in args: - dbm_name = whichdb.whichdb(a) + dbm_name = dbm.whichdb(a) if dbm_name: Map_Module = {'SCons.dblite' : 'dblite'} dbm = my_import(dbm_name) diff --git a/src/test_files.py b/src/test_files.py index 7d8e75e..d71329b 100644 --- a/src/test_files.py +++ b/src/test_files.py @@ -77,7 +77,7 @@ check = { missing = [] no_result = [] -for directory, check_list in check.items(): +for directory, check_list in list(check.items()): if os.path.exists(directory): for c in check_list: f = os.path.join(directory, c) @@ -87,13 +87,13 @@ for directory, check_list in check.items(): no_result.append(directory) if missing: - print "Missing the following files:\n" - print "\t" + "\n\t".join(missing) + print("Missing the following files:\n") + 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" + "\n\t".join(no_result) + print("Cannot check files, the following have apparently not been built:") + 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 fb12e2a..1e027a1 100644 --- a/src/test_interrupts.py +++ b/src/test_interrupts.py @@ -102,7 +102,7 @@ for f in files: indent_list.append( (line_num, match.group('try_or_except') ) ) try_except_lines[match.group('indent')] = indent_list uncaught_this_file = [] - for indent in try_except_lines.keys(): + for indent in list(try_except_lines.keys()): exc_keyboardint_seen = 0 exc_all_seen = 0 for (l,statement) in try_except_lines[indent] + [(-1,indent + 'try')]: @@ -129,9 +129,9 @@ for f in files: if expected_num != len(uncaught_this_file): uncaughtKeyboardInterrupt = 1 msg = "%s: expected %d uncaught interrupts, got %d:" - print msg % (f, expected_num, len(uncaught_this_file)) + print(msg % (f, expected_num, len(uncaught_this_file))) for line in uncaught_this_file: - print " File %s:%d: Uncaught KeyboardInterrupt!" % (f,line) + print(" File %s:%d: Uncaught KeyboardInterrupt!" % (f,line)) test.fail_test(uncaughtKeyboardInterrupt) diff --git a/src/test_pychecker.py b/src/test_pychecker.py index f87d303..24aa966 100644 --- a/src/test_pychecker.py +++ b/src/test_pychecker.py @@ -139,7 +139,7 @@ for file in files: mismatches.append(stderr) if mismatches: - print ''.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 29d36bf..731fbe7 100644 --- a/src/test_setup.py +++ b/src/test_setup.py @@ -197,9 +197,9 @@ if not os.path.isdir(scons_version) and os.path.isfile(tar_gz): os.system("gunzip -c %s | tar xf -" % tar_gz) if not os.path.isdir(scons_version): - print "Cannot test package installation, found none of the following packages:" - print "\t" + tar_gz - print "\t" + zip + print("Cannot test package installation, found none of the following packages:") + print("\t" + tar_gz) + print("\t" + zip) test.no_result(1) # Verify that a virgin installation installs the version library, diff --git a/src/test_strings.py b/src/test_strings.py index 3288d5f..b57c714 100644 --- a/src/test_strings.py +++ b/src/test_strings.py @@ -248,13 +248,13 @@ for collector in check_list: not_built.append(collector.directory) if missing_strings: - print "Found the following files with missing strings:" - print "\t" + "\n\t".join(missing_strings) + print("Found the following files with missing strings:") + 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" + "\n\t".join(not_built) + print("Cannot check all strings, the following have apparently not been built:") + print("\t" + "\n\t".join(not_built)) test.no_result(1) test.pass_test() diff --git a/test/AS/nasm.py b/test/AS/nasm.py index be7db3e..551a5ab 100644 --- a/test/AS/nasm.py +++ b/test/AS/nasm.py @@ -69,7 +69,7 @@ else: # anyway...). nasm_format = 'elf' format_map = {} -for k, v in format_map.items(): +for k, v in list(format_map.items()): if sys.platform.find(k) != -1: nasm_format = v break diff --git a/test/Actions/unicode-signature.py b/test/Actions/unicode-signature.py index 0d0c469..0ba50c3 100644 --- a/test/Actions/unicode-signature.py +++ b/test/Actions/unicode-signature.py @@ -36,7 +36,7 @@ import TestSCons test = TestSCons.TestSCons() try: - unicode + str except NameError: import sys msg = "Unicode not supported by Python version %s; skipping test\n" diff --git a/test/AddOption/help.py b/test/AddOption/help.py index d50e595..a3fd7be 100644 --- a/test/AddOption/help.py +++ b/test/AddOption/help.py @@ -57,10 +57,10 @@ 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 "\n".join(missing) + print("====== STDOUT:") + print(test.stdout()) + print("====== Missing the following lines in the above AddOption() help output:") + print("\n".join(missing)) test.fail_test() test.unlink('SConstruct') @@ -70,10 +70,10 @@ 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 "\n".join(unexpected) + print("====== STDOUT:") + print(test.stdout()) + print("====== Unexpected lines in the above non-AddOption() help output:") + print("\n".join(unexpected)) test.fail_test() test.pass_test() diff --git a/test/Batch/action-changed.py b/test/Batch/action-changed.py index dc2805a..d031432 100644 --- a/test/Batch/action-changed.py +++ b/test/Batch/action-changed.py @@ -54,7 +54,7 @@ sys.exit(0) """ test.write('build.py', build_py_contents % (python, 'one')) -os.chmod(test.workpath('build.py'), 0755) +os.chmod(test.workpath('build.py'), 0o755) test.write('SConstruct', """ env = Environment() @@ -81,7 +81,7 @@ test.must_match('f3.out', "one\nf3.in\n") test.up_to_date(arguments = '.') test.write('build.py', build_py_contents % (python, 'two')) -os.chmod(test.workpath('build.py'), 0755) +os.chmod(test.workpath('build.py'), 0o755) test.not_up_to_date(arguments = '.') diff --git a/test/Chmod.py b/test/Chmod.py index c00aea0..8b5fbe0 100644 --- a/test/Chmod.py +++ b/test/Chmod.py @@ -87,19 +87,19 @@ test.write('f10', "f10\n") test.subdir('d11') test.subdir('d12') -os.chmod(test.workpath('f1'), 0444) -os.chmod(test.workpath('f1-File'), 0444) -os.chmod(test.workpath('d2'), 0555) -os.chmod(test.workpath('d2-Dir'), 0555) -os.chmod(test.workpath('f3'), 0444) -os.chmod(test.workpath('d4'), 0555) -os.chmod(test.workpath('f5'), 0444) -os.chmod(test.workpath('Chmod-f7.in'), 0444) -os.chmod(test.workpath('f7.out-Chmod'), 0444) -os.chmod(test.workpath('f9'), 0444) -os.chmod(test.workpath('f10'), 0444) -os.chmod(test.workpath('d11'), 0555) -os.chmod(test.workpath('d12'), 0555) +os.chmod(test.workpath('f1'), 0o444) +os.chmod(test.workpath('f1-File'), 0o444) +os.chmod(test.workpath('d2'), 0o555) +os.chmod(test.workpath('d2-Dir'), 0o555) +os.chmod(test.workpath('f3'), 0o444) +os.chmod(test.workpath('d4'), 0o555) +os.chmod(test.workpath('f5'), 0o444) +os.chmod(test.workpath('Chmod-f7.in'), 0o444) +os.chmod(test.workpath('f7.out-Chmod'), 0o444) +os.chmod(test.workpath('f9'), 0o444) +os.chmod(test.workpath('f10'), 0o444) +os.chmod(test.workpath('d11'), 0o555) +os.chmod(test.workpath('d12'), 0o555) expect = test.wrap_stdout(read_str = """\ Chmod("f1", 0666) @@ -123,68 +123,68 @@ cat(["f8.out"], ["f8.in"]) test.run(options = '-n', arguments = '.', stdout = expect) s = stat.S_IMODE(os.stat(test.workpath('f1'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('f1-File'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('d2'))[stat.ST_MODE]) -test.fail_test(s != 0555) +test.fail_test(s != 0o555) s = stat.S_IMODE(os.stat(test.workpath('d2-Dir'))[stat.ST_MODE]) -test.fail_test(s != 0555) +test.fail_test(s != 0o555) test.must_not_exist('bar.out') s = stat.S_IMODE(os.stat(test.workpath('f3'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('d4'))[stat.ST_MODE]) -test.fail_test(s != 0555) +test.fail_test(s != 0o555) s = stat.S_IMODE(os.stat(test.workpath('f5'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) test.must_not_exist('f6.out') test.must_not_exist('f7.out') s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) test.must_not_exist('f8.out') s = stat.S_IMODE(os.stat(test.workpath('f9'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('f10'))[stat.ST_MODE]) -test.fail_test(s != 0444) +test.fail_test(s != 0o444) s = stat.S_IMODE(os.stat(test.workpath('d11'))[stat.ST_MODE]) -test.fail_test(s != 0555) +test.fail_test(s != 0o555) s = stat.S_IMODE(os.stat(test.workpath('d12'))[stat.ST_MODE]) -test.fail_test(s != 0555) +test.fail_test(s != 0o555) test.run() s = stat.S_IMODE(os.stat(test.workpath('f1'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('f1-File'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('d2'))[stat.ST_MODE]) -test.fail_test(s != 0777) +test.fail_test(s != 0o777) s = stat.S_IMODE(os.stat(test.workpath('d2-Dir'))[stat.ST_MODE]) -test.fail_test(s != 0777) +test.fail_test(s != 0o777) test.must_match('bar.out', "bar.in\n") s = stat.S_IMODE(os.stat(test.workpath('f3'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('d4'))[stat.ST_MODE]) -test.fail_test(s != 0777) +test.fail_test(s != 0o777) s = stat.S_IMODE(os.stat(test.workpath('f5'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) test.must_match('f6.out', "f6.in\n") test.must_match('f7.out', "f7.in\n") s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) test.must_match('f8.out', "f8.in\n") s = stat.S_IMODE(os.stat(test.workpath('f9'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('f10'))[stat.ST_MODE]) -test.fail_test(s != 0666) +test.fail_test(s != 0o666) s = stat.S_IMODE(os.stat(test.workpath('d11'))[stat.ST_MODE]) -test.fail_test(s != 0777) +test.fail_test(s != 0o777) s = stat.S_IMODE(os.stat(test.workpath('d12'))[stat.ST_MODE]) -test.fail_test(s != 0777) +test.fail_test(s != 0o777) test.pass_test() diff --git a/test/Configure/ConfigureDryRunError.py b/test/Configure/ConfigureDryRunError.py index b4be67e..a8c6309 100644 --- a/test/Configure/ConfigureDryRunError.py +++ b/test/Configure/ConfigureDryRunError.py @@ -97,7 +97,7 @@ test.checkLogAndStdout( ["Checking for C library %s... " % lib, newLog = test.read(test.workpath('config.log')) if newLog != oldLog: - print "Unexpected update of log file within a dry run" + print("Unexpected update of log file within a dry run") test.fail_test() test.pass_test() diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py index cda6c3b..6c70c9c 100644 --- a/test/Configure/config-h.py +++ b/test/Configure/config-h.py @@ -135,19 +135,19 @@ test.run(stdout=expected_stdout) config_h = test.read(test.workpath('config.h')) if expected_config_h != config_h: - print "Unexpected config.h" - print "Expected: " - print "---------------------------------------------------------" - print repr(expected_config_h) - print "---------------------------------------------------------" - print "Found: " - print "---------------------------------------------------------" - print repr(config_h) - print "---------------------------------------------------------" - print "Stdio: " - print "---------------------------------------------------------" - print test.stdout() - print "---------------------------------------------------------" + print("Unexpected config.h") + print("Expected: ") + print("---------------------------------------------------------") + print(repr(expected_config_h)) + print("---------------------------------------------------------") + print("Found: ") + print("---------------------------------------------------------") + print(repr(config_h)) + print("---------------------------------------------------------") + print("Stdio: ") + print("---------------------------------------------------------") + print(test.stdout()) + print("---------------------------------------------------------") test.fail_test() expected_read_str = re.sub(r'\b((yes)|(no))\b', @@ -162,19 +162,19 @@ test.run(stdout=expected_stdout) config_h = test.read(test.workpath('config.h')) if expected_config_h != config_h: - print "Unexpected config.h" - print "Expected: " - print "---------------------------------------------------------" - print repr(expected_config_h) - print "---------------------------------------------------------" - print "Found: " - print "---------------------------------------------------------" - print repr(config_h) - print "---------------------------------------------------------" - print "Stdio: " - print "---------------------------------------------------------" - print test.stdout() - print "---------------------------------------------------------" + print("Unexpected config.h") + print("Expected: ") + print("---------------------------------------------------------") + print(repr(expected_config_h)) + print("---------------------------------------------------------") + print("Found: ") + print("---------------------------------------------------------") + print(repr(config_h)) + print("---------------------------------------------------------") + print("Stdio: ") + print("---------------------------------------------------------") + print(test.stdout()) + print("---------------------------------------------------------") test.fail_test() test.pass_test() diff --git a/test/Configure/implicit-cache.py b/test/Configure/implicit-cache.py index 0f04b1e..059fd4c 100644 --- a/test/Configure/implicit-cache.py +++ b/test/Configure/implicit-cache.py @@ -93,11 +93,11 @@ test.run_sconsign('-d .sconf_temp -e conftest_0.c --raw .sconsign.dblite') new_sconsign_dblite = test.stdout() if old_sconsign_dblite != new_sconsign_dblite: - print ".sconsign.dblite did not match:" - print "FIRST RUN ==========" - print old_sconsign_dblite - print "SECOND RUN ==========" - print new_sconsign_dblite + print(".sconsign.dblite did not match:") + print("FIRST RUN ==========") + print(old_sconsign_dblite) + print("SECOND RUN ==========") + print(new_sconsign_dblite) test.fail_test() test.pass_test() diff --git a/test/Copy-Action.py b/test/Copy-Action.py index 51635c5..ded158a 100644 --- a/test/Copy-Action.py +++ b/test/Copy-Action.py @@ -84,8 +84,8 @@ test.subdir('d5') test.write(['d5', 'f12.in'], "f12.in\n") test.write('f 13.in', "f 13.in\n") -os.chmod('f1.in', 0646) -os.chmod('f4.in', 0644) +os.chmod('f1.in', 0o646) +os.chmod('f4.in', 0o644) test.sleep() diff --git a/test/Deprecated/Options/Options.py b/test/Deprecated/Options/Options.py index 8116a63..61a12f3 100644 --- a/test/Deprecated/Options/Options.py +++ b/test/Deprecated/Options/Options.py @@ -237,7 +237,7 @@ opts.Save('options.saved', env) def checkSave(file, expected): gdict = {} ldict = {} - exec open(file, 'rU').read() in gdict, ldict + exec(open(file, 'rU').read(), gdict, ldict) assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict) # First test with no command line options diff --git a/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py b/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py index 28b8761..9a36eac 100644 --- a/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py +++ b/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py @@ -67,7 +67,7 @@ test.subdir('BK', 'import', ['import', 'sub']) # Test using BitKeeper to fetch from SCCS/s.file files. sccs = test.where_is('sccs') if not sccs: - print "Could not find SCCS, skipping sub-test of BitKeeper using SCCS files." + print("Could not find SCCS, skipping sub-test of BitKeeper using SCCS files.") else: test.subdir('work1', ['work1', 'SCCS'], @@ -167,9 +167,9 @@ sub/fff.in 1.1 -> 1.2: 1 lines rcs = test.where_is('rcs') ci = test.where_is('ci') if not rcs: - print "Could not find RCS,\nskipping sub-test of BitKeeper using RCS files." + print("Could not find RCS,\nskipping sub-test of BitKeeper using RCS files.") elif not ci: - print "Could not find the RCS ci command,\nskipping sub-test of BitKeeper using RCS files." + print("Could not find the RCS ci command,\nskipping sub-test of BitKeeper using RCS files.") else: test.subdir('work2', ['work2', 'RCS'], diff --git a/test/Deprecated/SourceCode/Subversion.py b/test/Deprecated/SourceCode/Subversion.py index a97c86f..ac3eb57 100644 --- a/test/Deprecated/SourceCode/Subversion.py +++ b/test/Deprecated/SourceCode/Subversion.py @@ -50,7 +50,7 @@ svnadmin = test.where_is('svnadmin') if not svn: test.skip_test("Could not find 'svnadmin'; skipping test(s).\n") -print "Short-circuiting this test until we support Subversion" +print("Short-circuiting this test until we support Subversion") test.pass_test() test.subdir('Subversion', 'import', ['import', 'sub'], 'work1', 'work2') diff --git a/test/GetBuildFailures/parallel.py b/test/GetBuildFailures/parallel.py index b7576af..101c2e2 100644 --- a/test/GetBuildFailures/parallel.py +++ b/test/GetBuildFailures/parallel.py @@ -102,8 +102,8 @@ error_45 = f4_error + f5_error error_54 = f5_error + f4_error if test.stderr() not in [error_45, error_54]: - print "Did not find the following output in list of expected strings:" - print test.stderr(), + print("Did not find the following output in list of expected strings:") + print(test.stderr(), end=' ') test.fail_test() # We jump through hoops above to try to make sure that the individual @@ -121,8 +121,8 @@ failed_45 = f4_failed + f5_failed failed_54 = f5_failed + f4_failed if test.stdout() not in [failed_45, failed_54]: - print "Did not find the following output in list of expected strings:" - print test.stdout(), + print("Did not find the following output in list of expected strings:") + print(test.stdout(), end=' ') test.fail_test() test.must_match(test.workpath('f3'), 'f3.in\n') diff --git a/test/Glob/glob-libpath.py b/test/Glob/glob-libpath.py index b09aab9..6ee06e6 100644 --- a/test/Glob/glob-libpath.py +++ b/test/Glob/glob-libpath.py @@ -77,10 +77,10 @@ test.write(['src', 'util', 'util.cpp'], """int i=0; test.run(arguments = '-Q .') if not test.match_re_dotall(test.stdout(), r".*(-L|/LIBPATH:)build[/\\]util.*"): - print repr(test.stdout())+" should contain -Lbuild/util or /LIBPATH:build\\util" + print(repr(test.stdout())+" should contain -Lbuild/util or /LIBPATH:build\\util") test.fail_test() if test.match_re_dotall(test.stdout(), r".*(-L|/LIBPATH:)src[/\\]util.*"): - print repr(test.stdout())+" should not contain -Lsrc/util or /LIBPATH:src\\util" + print(repr(test.stdout())+" should not contain -Lsrc/util or /LIBPATH:src\\util") test.fail_test() test.pass_test() diff --git a/test/Install/Install.py b/test/Install/Install.py index adadfd9..d66660b 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -129,7 +129,7 @@ test.must_match(['work', 'f2.out'], "f2.in\n") # if a target can not be unlinked before building it: test.write(['work', 'f1.in'], "f1.in again again\n") -os.chmod(test.workpath('work', 'export'), 0555) +os.chmod(test.workpath('work', 'export'), 0o555) f = open(f1_out, 'rb') diff --git a/test/Interactive/version.py b/test/Interactive/version.py index bbca9ef..295b9d3 100644 --- a/test/Interactive/version.py +++ b/test/Interactive/version.py @@ -76,7 +76,7 @@ expect2 = r"""scons>>> SCons by Steven Knight et al\.: stdout = test.stdout() + '\n' if not test.match_re(stdout, expect1) and not test.match_re(stdout, expect2): - print repr(stdout) + print(repr(stdout)) test.fail_test() diff --git a/test/Java/multi-step.py b/test/Java/multi-step.py index a8efcd4..add4208 100644 --- a/test/Java/multi-step.py +++ b/test/Java/multi-step.py @@ -557,7 +557,7 @@ test.must_exist(['buildout', 'jni', 'SampleTest.java']) # it doesn't exist. p = test.workpath('buildout', 'jni', 'SampleTest.class') if not os.path.exists(p): - print 'Warning: %s does not exist' % p + print('Warning: %s does not exist' % p) test.up_to_date(arguments = '.') diff --git a/test/MSVC/batch-longlines.py b/test/MSVC/batch-longlines.py index ef7233b..c584aba 100644 --- a/test/MSVC/batch-longlines.py +++ b/test/MSVC/batch-longlines.py @@ -1,61 +1,61 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -""" -Verify operation of Visual C/C++ batch builds with long lines. - -Only runs on Windows. -""" - -import TestSCons - -test = TestSCons.TestSCons() - -test.skip_if_not_msvc() - -_python_ = TestSCons._python_ - -for i in xrange(1,200): - test.write('source-file-with-quite-a-long-name-maybe-unrealistic-but-who-cares-%05d.cxx'%i, - '/* source file %d */\nint var%d;\n'%(i,i)) - -test.write('SConstruct', """ -env = Environment(tools=['msvc', 'mslink'], - MSVC_BATCH=ARGUMENTS.get('MSVC_BATCH')) -env.SharedLibrary('mylib', Glob('source*.cxx')) -""" % locals()) - -test.run(arguments = 'MSVC_BATCH=1 .') - -test.must_exist('mylib.dll') - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +""" +Verify operation of Visual C/C++ batch builds with long lines. + +Only runs on Windows. +""" + +import TestSCons + +test = TestSCons.TestSCons() + +test.skip_if_not_msvc() + +_python_ = TestSCons._python_ + +for i in range(1,200): + test.write('source-file-with-quite-a-long-name-maybe-unrealistic-but-who-cares-%05d.cxx'%i, + '/* source file %d */\nint var%d;\n'%(i,i)) + +test.write('SConstruct', """ +env = Environment(tools=['msvc', 'mslink'], + MSVC_BATCH=ARGUMENTS.get('MSVC_BATCH')) +env.SharedLibrary('mylib', Glob('source*.cxx')) +""" % locals()) + +test.run(arguments = 'MSVC_BATCH=1 .') + +test.must_exist('mylib.dll') + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index c68fb45..6f5c8d6 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.py @@ -181,9 +181,9 @@ slow = time.time() - start # using precompiled headers should be faster limit = slow*0.90 if fast >= limit: - print "Using precompiled headers was not fast enough:" - print "slow.obj: %.3fs" % slow - print "fast.obj: %.3fs (expected less than %.3fs)" % (fast, limit) + print("Using precompiled headers was not fast enough:") + print("slow.obj: %.3fs" % slow) + print("fast.obj: %.3fs (expected less than %.3fs)" % (fast, limit)) test.fail_test() # Modifying resource.h should cause both the resource and precompiled header to be rebuilt: diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index 008397a..b7172fc 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -147,7 +147,7 @@ test.must_exist(['work1', 'mmmmocFromH.cxx'], ['work1', 'mmmanother_ui_file.cxx']) def _flagTest(test,fileToContentsStart): - for f,c in fileToContentsStart.items(): + for f,c in list(fileToContentsStart.items()): if test.read(test.workpath('work1', f)).find(c) != 0: return 1 return 0 diff --git a/test/QT/copied-env.py b/test/QT/copied-env.py index efa91be..59a344d 100644 --- a/test/QT/copied-env.py +++ b/test/QT/copied-env.py @@ -70,8 +70,8 @@ moc_MyForm = [x for x in test.stdout().split('\n') if x.find('moc_MyForm') != -1 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:" - print test.stdout() + print("Did not find MYLIB_IMPL on moc_MyForm compilation line:") + print(test.stdout()) test.fail_test() test.pass_test() diff --git a/test/QT/warnings.py b/test/QT/warnings.py index a861b24..5e680f6 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.py @@ -59,8 +59,8 @@ scons: warning: Generated moc file 'aaa.moc' is not included by 'aaa.cpp' """ + TestSCons.file_expr if not re.search(match12, test.stderr()): - print "Did not find expected regular expression in stderr:" - print test.stderr() + print("Did not find expected regular expression in stderr:") + print(test.stderr()) test.fail_test() os.environ['QTDIR'] = test.QT diff --git a/test/SConsignFile/use-dbhash.py b/test/SConsignFile/use-dbhash.py index 45e3e36..bd9b799 100644 --- a/test/SConsignFile/use-dbhash.py +++ b/test/SConsignFile/use-dbhash.py @@ -35,7 +35,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() try: - import dbhash + import dbm.bsd except ImportError: test.skip_test('No dbhash in this version of Python; skipping test.\n') diff --git a/test/SConsignFile/use-dbm.py b/test/SConsignFile/use-dbm.py index 75f088d..90983b3 100644 --- a/test/SConsignFile/use-dbm.py +++ b/test/SConsignFile/use-dbm.py @@ -35,7 +35,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() try: - import dbm + import dbm.ndbm except ImportError: test.skip_test('No dbm in this version of Python; skipping test.\n') diff --git a/test/SConsignFile/use-dumbdbm.py b/test/SConsignFile/use-dumbdbm.py index 9d48fe5..84f1dd4 100644 --- a/test/SConsignFile/use-dumbdbm.py +++ b/test/SConsignFile/use-dumbdbm.py @@ -35,7 +35,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() try: - import dumbdbm + import dbm.dumb except ImportError: test.skip_test('No dumbdbm in this version of Python; skipping test.\n') diff --git a/test/SConsignFile/use-gdbm.py b/test/SConsignFile/use-gdbm.py index 1eb3645..a7e4f59 100644 --- a/test/SConsignFile/use-gdbm.py +++ b/test/SConsignFile/use-gdbm.py @@ -35,7 +35,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() try: - import gdbm + import dbm.gnu except ImportError: test.skip_test('No gdbm in this version of Python; skipping test.\n') diff --git a/test/SHELL.py b/test/SHELL.py index 93ed0b1..faee27f 100644 --- a/test/SHELL.py +++ b/test/SHELL.py @@ -64,7 +64,7 @@ ofp.close() sys.exit(0) """ % locals()) -os.chmod(my_shell, 0755) +os.chmod(my_shell, 0o755) test.write('SConstruct', """\ env = Environment(SHELL = r'%(my_shell)s') diff --git a/test/Scanner/unicode.py b/test/Scanner/unicode.py index 55e22bd..7a72804 100644 --- a/test/Scanner/unicode.py +++ b/test/Scanner/unicode.py @@ -36,7 +36,7 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() try: - unicode + str except NameError: import sys msg = "Unicode not supported by Python version %s; skipping test\n" @@ -102,28 +102,28 @@ include utf16be.k foo.k 1 line 4 """) -contents = unicode("""\ +contents = str("""\ ascii.k 1 line 1 include ascii.inc ascii.k 1 line 3 """) test.write('ascii.k', contents.encode('ascii')) -contents = unicode("""\ +contents = str("""\ utf8.k 1 line 1 include utf8.inc utf8.k 1 line 3 """) test.write('utf8.k', codecs.BOM_UTF8 + contents.encode('utf-8')) -contents = unicode("""\ +contents = str("""\ utf16le.k 1 line 1 include utf16le.inc utf16le.k 1 line 3 """) test.write('utf16le.k', codecs.BOM_UTF16_LE + contents.encode('utf-16-le')) -contents = unicode("""\ +contents = str("""\ utf16be.k 1 line 1 include utf16be.inc utf16be.k 1 line 3 diff --git a/test/TEMPFILEPREFIX.py b/test/TEMPFILEPREFIX.py index f9b3240..8e756af 100644 --- a/test/TEMPFILEPREFIX.py +++ b/test/TEMPFILEPREFIX.py @@ -45,7 +45,7 @@ print sys.argv echo_py = test.workpath('echo.py') st = os.stat(echo_py) -os.chmod(echo_py, st[stat.ST_MODE]|0111) +os.chmod(echo_py, st[stat.ST_MODE]|0o111) test.write('SConstruct', """ import os diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 24d4bdd..863144d 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -173,14 +173,14 @@ Run \texttt{latex}, then \texttt{bibtex}, then \texttt{latex} twice again \cite{ 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 '\n'.join(reruns) + print("Expected 2 latex calls, got %s:" % len(reruns)) + print('\n'.join(reruns)) test.fail_test() 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 '\n'.join(bibtex) + print("Expected 1 bibtex call, got %s:" % len(bibtex)) + print('\n'.join(bibtex)) test.fail_test() test.pass_test() diff --git a/test/Value.py b/test/Value.py index f3ad458..025c6de 100644 --- a/test/Value.py +++ b/test/Value.py @@ -81,7 +81,7 @@ open(sys.argv[-1],'wb').write(" ".join(sys.argv[1:-2])) # to make sure there's no difference in behavior. for source_signature in ['MD5', 'timestamp-newer']: - print "Testing Value node with source signatures:", source_signature + print("Testing Value node with source signatures:", source_signature) test.write('SConstruct', SConstruct_content % locals()) diff --git a/test/Variables/Variables.py b/test/Variables/Variables.py index 454e32e..d0bf432 100644 --- a/test/Variables/Variables.py +++ b/test/Variables/Variables.py @@ -231,7 +231,7 @@ opts.Save('variables.saved', env) def checkSave(file, expected): gdict = {} ldict = {} - exec open(file, 'rU').read() in gdict, ldict + exec(open(file, 'rU').read(), gdict, ldict) assert expected == ldict, "%s\n...not equal to...\n%s" % (expected, ldict) # First test with no command line variables diff --git a/test/WhereIs.py b/test/WhereIs.py index dc127b6..07c3f6c 100644 --- a/test/WhereIs.py +++ b/test/WhereIs.py @@ -45,10 +45,10 @@ if sys.platform != 'win32': os.mkdir(sub2_xxx_exe) test.write(sub3_xxx_exe, "\n") -os.chmod(sub3_xxx_exe, 0777) +os.chmod(sub3_xxx_exe, 0o777) test.write(sub4_xxx_exe, "\n") -os.chmod(sub4_xxx_exe, 0777) +os.chmod(sub4_xxx_exe, 0o777) env_path = os.environ['PATH'] diff --git a/test/Win32/bad-drive.py b/test/Win32/bad-drive.py index f2a55b8..ff98b4e 100644 --- a/test/Win32/bad-drive.py +++ b/test/Win32/bad-drive.py @@ -50,8 +50,8 @@ for i in range(len(uppercase)-1, -1, -1): break if bad_drive is None: - print "All drive letters appear to be in use." - print "Cannot test SCons handling of invalid Windows drive letters." + print("All drive letters appear to be in use.") + print("Cannot test SCons handling of invalid Windows drive letters.") test.no_result(1); test.write('SConstruct', """ diff --git a/test/Win32/default-drive.py b/test/Win32/default-drive.py index f427a20..2bc14b1 100644 --- a/test/Win32/default-drive.py +++ b/test/Win32/default-drive.py @@ -59,7 +59,7 @@ test.write(['src', 'file.in'], "src/file.in\n") build_file_out = test.workpath('build', 'file.out') -print os.path.splitdrive(build_file_out)[1] +print(os.path.splitdrive(build_file_out)[1]) test.run(chdir = 'src', arguments = os.path.splitdrive(build_file_out)[1]) diff --git a/test/ZIP/ZIP.py b/test/ZIP/ZIP.py index af2450b..f2acad8 100644 --- a/test/ZIP/ZIP.py +++ b/test/ZIP/ZIP.py @@ -47,7 +47,7 @@ def zipfile_contains(zipfilename, names): for name in names: try: info=zf.getinfo(name) - except KeyError, e: # name not found + except KeyError as e: # name not found zf.close() return False return True diff --git a/test/ZIP/ZIPROOT.py b/test/ZIP/ZIPROOT.py index 96747a7..f3e4496 100644 --- a/test/ZIP/ZIPROOT.py +++ b/test/ZIP/ZIPROOT.py @@ -1,98 +1,98 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import stat - -import TestSCons - -_python_ = TestSCons._python_ - -test = TestSCons.TestSCons() - -import zipfile - -def zipfile_contains(zipfilename, names): - """Returns True if zipfilename contains all the names, False otherwise.""" - zf=zipfile.ZipFile(zipfilename, 'r') - if type(names)==type(''): - names=[names] - for name in names: - try: - info=zf.getinfo(name) - except KeyError, e: # name not found - zf.close() - return False - return True - -def zipfile_files(fname): - """Returns all the filenames in zip file fname.""" - zf = zipfile.ZipFile(fname, 'r') - return [x.filename for x in zf.infolist()] - -test.subdir('sub1') -test.subdir(['sub1', 'sub2']) - -test.write('SConstruct', """ -env = Environment(tools = ['zip']) -env.Zip(target = 'aaa.zip', source = ['sub1/file1'], ZIPROOT='sub1') -env.Zip(target = 'bbb.zip', source = ['sub1/file2', 'sub1/sub2/file2'], ZIPROOT='sub1') -""" % locals()) - -test.write(['sub1', 'file1'], "file1\n") -test.write(['sub1', 'file2'], "file2a\n") -test.write(['sub1', 'sub2', 'file2'], "file2b\n") - -test.run(arguments = 'aaa.zip', stderr = None) - -test.must_exist('aaa.zip') - -# TEST: Zip file should contain 'file1', not 'sub1/file1', because of ZIPROOT. -zf=zipfile.ZipFile('aaa.zip', 'r') -test.fail_test(zf.testzip() is not None) -zf.close() - -files=zipfile_files('aaa.zip') -test.fail_test(zipfile_files('aaa.zip') != ['file1'], - message='Zip file aaa.zip has wrong files: %s'%repr(files)) - -### - -test.run(arguments = 'bbb.zip', stderr = None) - -test.must_exist('bbb.zip') - -# TEST: Zip file should contain 'sub2/file2', not 'sub1/sub2/file2', because of ZIPROOT. -zf=zipfile.ZipFile('bbb.zip', 'r') -test.fail_test(zf.testzip() is not None) -zf.close() - -files=zipfile_files('bbb.zip') -test.fail_test(zipfile_files('bbb.zip') != ['file2', 'sub2/file2'], - message='Zip file bbb.zip has wrong files: %s'%repr(files)) - - -test.pass_test() +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import stat + +import TestSCons + +_python_ = TestSCons._python_ + +test = TestSCons.TestSCons() + +import zipfile + +def zipfile_contains(zipfilename, names): + """Returns True if zipfilename contains all the names, False otherwise.""" + zf=zipfile.ZipFile(zipfilename, 'r') + if type(names)==type(''): + names=[names] + for name in names: + try: + info=zf.getinfo(name) + except KeyError as e: # name not found + zf.close() + return False + return True + +def zipfile_files(fname): + """Returns all the filenames in zip file fname.""" + zf = zipfile.ZipFile(fname, 'r') + return [x.filename for x in zf.infolist()] + +test.subdir('sub1') +test.subdir(['sub1', 'sub2']) + +test.write('SConstruct', """ +env = Environment(tools = ['zip']) +env.Zip(target = 'aaa.zip', source = ['sub1/file1'], ZIPROOT='sub1') +env.Zip(target = 'bbb.zip', source = ['sub1/file2', 'sub1/sub2/file2'], ZIPROOT='sub1') +""" % locals()) + +test.write(['sub1', 'file1'], "file1\n") +test.write(['sub1', 'file2'], "file2a\n") +test.write(['sub1', 'sub2', 'file2'], "file2b\n") + +test.run(arguments = 'aaa.zip', stderr = None) + +test.must_exist('aaa.zip') + +# TEST: Zip file should contain 'file1', not 'sub1/file1', because of ZIPROOT. +zf=zipfile.ZipFile('aaa.zip', 'r') +test.fail_test(zf.testzip() is not None) +zf.close() + +files=zipfile_files('aaa.zip') +test.fail_test(zipfile_files('aaa.zip') != ['file1'], + message='Zip file aaa.zip has wrong files: %s'%repr(files)) + +### + +test.run(arguments = 'bbb.zip', stderr = None) + +test.must_exist('bbb.zip') + +# TEST: Zip file should contain 'sub2/file2', not 'sub1/sub2/file2', because of ZIPROOT. +zf=zipfile.ZipFile('bbb.zip', 'r') +test.fail_test(zf.testzip() is not None) +zf.close() + +files=zipfile_files('bbb.zip') +test.fail_test(zipfile_files('bbb.zip') != ['file2', 'sub2/file2'], + message='Zip file bbb.zip has wrong files: %s'%repr(files)) + + +test.pass_test() diff --git a/test/gnutools.py b/test/gnutools.py index e1b7e42..f79efe4 100644 --- a/test/gnutools.py +++ b/test/gnutools.py @@ -118,7 +118,7 @@ def testObject(test, obj, expect): line1 = contents.split('\n')[0] actual = ' '.join(line1.split()) if not expect == actual: - print "%s: %s != %s\n" % (obj, repr(expect), repr(actual)) + print("%s: %s != %s\n" % (obj, repr(expect), repr(actual))) test.fail_test() if sys.platform in ('win32', 'cygwin'): diff --git a/test/import.py b/test/import.py index ef5ee61..fb8a28c 100644 --- a/test/import.py +++ b/test/import.py @@ -185,8 +185,8 @@ for tool in tools: matched = 1 break if not matched: - print "Failed importing '%s', stderr:" % tool - print stderr + print("Failed importing '%s', stderr:" % tool) + print(stderr) failures.append(tool) test.fail_test(len(failures)) diff --git a/test/long-lines/signature.py b/test/long-lines/signature.py index bc5d11a..ce38bec 100644 --- a/test/long-lines/signature.py +++ b/test/long-lines/signature.py @@ -51,7 +51,7 @@ fp.write('FILEFLAG=%s\\n' % args[2]) fp.write('TIMESTAMP=%s\\n' % args[3]) """) -os.chmod(build_py, 0755) +os.chmod(build_py, 0o755) test.write('SConstruct', """\ arg = 'a_long_ignored_argument' diff --git a/test/option--random.py b/test/option--random.py index a9b9b9d..59592cb 100644 --- a/test/option--random.py +++ b/test/option--random.py @@ -66,7 +66,7 @@ tries = 0 max_tries = 10 while test.stdout() == non_random_output: if tries >= max_tries: - print "--random generated the non-random output %s times!" % max_tries + print("--random generated the non-random output %s times!" % max_tries) test.fail_test() tries = tries + 1 test.run(arguments = '-n -Q --random') @@ -84,7 +84,7 @@ tries = 0 max_tries = 10 while test.stdout() == non_random_output: if tries >= max_tries: - print "--random generated the non-random output %s times!" % max_tries + print("--random generated the non-random output %s times!" % max_tries) test.fail_test() tries = tries + 1 test.run(arguments = '-n -Q --random') diff --git a/test/option-v.py b/test/option-v.py index 680f541..8985db0 100644 --- a/test/option-v.py +++ b/test/option-v.py @@ -55,13 +55,13 @@ expect2 = r"""SCons by Steven Knight et al.: test.run(arguments = '-v') stdout = test.stdout() if not test.match_re(stdout, expect1) and not test.match_re(stdout, expect2): - print stdout + print(stdout) test.fail_test() test.run(arguments = '--version') stdout = test.stdout() if not test.match_re(stdout, expect1) and not test.match_re(stdout, expect2): - print stdout + print(stdout) test.fail_test() test.pass_test() diff --git a/test/option/debug-count.py b/test/option/debug-count.py index 3f8a23c..076d7fa 100644 --- a/test/option/debug-count.py +++ b/test/option/debug-count.py @@ -74,10 +74,10 @@ for args in ['-h --debug=count', '--debug=count']: 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", ' '.join(missing) - print "STDOUT ==========" - print stdout + print("Missing the following object lines from '%s' output:" % args) + print("\t", ' '.join(missing)) + print("STDOUT ==========") + print(stdout) test.fail_test(1) expect_warning = """ diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 198d71d..7448e1c 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -20,7 +20,7 @@ # 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 division + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -164,7 +164,7 @@ outside of the 15%% tolerance. """ % locals()) if failures or warnings: - print '\n'.join([test.stdout()] + failures + warnings) + print('\n'.join([test.stdout()] + failures + warnings)) if failures: test.fail_test(1) @@ -172,7 +172,7 @@ test.run(arguments = "--debug=time . SLEEP=0") command_time = get_command_time(test.stdout()) if command_time != 0.0: - print "Up-to-date run received non-zero command time of %s" % command_time + print("Up-to-date run received non-zero command time of %s" % command_time) test.fail_test() @@ -201,14 +201,14 @@ outside of the 1%% tolerance. """ % locals()) if failures: - print '\n'.join([test.stdout()] + failures) + print('\n'.join([test.stdout()] + failures)) test.fail_test(1) test.run(arguments = "-j4 --debug=time . SLEEP=1") command_time = get_command_time(test.stdout()) if command_time != 0.0: - print "Up-to-date run received non-zero command time of %s" % command_time + print("Up-to-date run received non-zero command time of %s" % command_time) test.fail_test() diff --git a/test/option/help-options.py b/test/option/help-options.py index 45bbfa0..1b23cb3 100644 --- a/test/option/help-options.py +++ b/test/option/help-options.py @@ -60,8 +60,8 @@ options = [x[-1] == ',' and x[:-1] or x for x in options] lowered = [x.lower() for x in options] ordered = sorted(lowered) if lowered != ordered: - print "lowered =", lowered - print "sorted =", ordered + print("lowered =", lowered) + print("sorted =", ordered) test.fail_test() test.pass_test() diff --git a/test/option/profile.py b/test/option/profile.py index d53c690..513da47 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -36,7 +36,7 @@ else: # when we drop support for Python 2.6. class StringIO(_StringIO): def write(self, s): - _StringIO.write(self, unicode(s)) + _StringIO.write(self, str(s)) import TestSCons diff --git a/test/scons-time/run/config/python.py b/test/scons-time/run/config/python.py index 6cf965b..57b732d 100644 --- a/test/scons-time/run/config/python.py +++ b/test/scons-time/run/config/python.py @@ -53,7 +53,7 @@ for arg in sys.argv[1:]: print 'my_python.py: %s' % profile """) -os.chmod(my_python_py, 0755) +os.chmod(my_python_py, 0o755) test.run(arguments = 'run -f config foo.tar.gz') diff --git a/test/scons-time/run/option/python.py b/test/scons-time/run/option/python.py index a28e23f..70feb70 100644 --- a/test/scons-time/run/option/python.py +++ b/test/scons-time/run/option/python.py @@ -49,7 +49,7 @@ for arg in sys.argv[1:]: sys.stdout.write('my_python.py: %s\\n' % profile) """) -os.chmod(my_python_py, 0755) +os.chmod(my_python_py, 0o755) test.run(arguments = 'run --python %s foo.tar.gz' % my_python_py) diff --git a/test/sconsign/nonwritable.py b/test/sconsign/nonwritable.py index 913dcf1..5ae55bb 100644 --- a/test/sconsign/nonwritable.py +++ b/test/sconsign/nonwritable.py @@ -78,7 +78,7 @@ test.write(['work1', 'foo.in'], "work1/foo.in\n") test.write(work1__sconsign_dblite, "") -os.chmod(work1__sconsign_dblite, 0444) +os.chmod(work1__sconsign_dblite, 0o444) test.run(chdir='work1', arguments='.') @@ -95,7 +95,7 @@ test.write(['work2', 'foo.in'], "work2/foo.in\n") pickle.dump({}, open(work2_sub1__sconsign, 'wb'), 1) pickle.dump({}, open(work2_sub2__sconsign, 'wb'), 1) -os.chmod(work2_sub1__sconsign, 0444) +os.chmod(work2_sub1__sconsign, 0o444) test.run(chdir='work2', arguments='.') diff --git a/test/sconsign/script/SConsignFile.py b/test/sconsign/script/SConsignFile.py index a9f79f4..71a7e6d 100644 --- a/test/sconsign/script/SConsignFile.py +++ b/test/sconsign/script/SConsignFile.py @@ -86,8 +86,8 @@ output.write(input.read()) sys.exit(0) """) -test.chmod(fake_cc_py, 0755) -test.chmod(fake_link_py, 0755) +test.chmod(fake_cc_py, 0o755) +test.chmod(fake_link_py, 0o755) # Note: We don't use os.path.join() representations of the file names # in the expected output because paths in the .sconsign files are diff --git a/test/sconsign/script/Signatures.py b/test/sconsign/script/Signatures.py index cfd2a7f..5babe67 100644 --- a/test/sconsign/script/Signatures.py +++ b/test/sconsign/script/Signatures.py @@ -105,8 +105,8 @@ output.write(input.read()) sys.exit(0) """) -test.chmod(fake_cc_py, 0755) -test.chmod(fake_link_py, 0755) +test.chmod(fake_cc_py, 0o755) +test.chmod(fake_link_py, 0o755) test.write('SConstruct', """ SConsignFile(None) diff --git a/test/sconsign/script/no-SConsignFile.py b/test/sconsign/script/no-SConsignFile.py index 829d650..70b18c8 100644 --- a/test/sconsign/script/no-SConsignFile.py +++ b/test/sconsign/script/no-SConsignFile.py @@ -94,8 +94,8 @@ output.write(input.read()) sys.exit(0) """) -test.chmod(fake_cc_py, 0755) -test.chmod(fake_link_py, 0755) +test.chmod(fake_cc_py, 0o755) +test.chmod(fake_link_py, 0o755) # Note: We don't use os.path.join() representations of the file names # in the expected output because paths in the .sconsign files are diff --git a/test/site_scons/sysdirs.py b/test/site_scons/sysdirs.py index c05ef67..d05f6a4 100644 --- a/test/site_scons/sysdirs.py +++ b/test/site_scons/sysdirs.py @@ -1,71 +1,71 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import TestSCons - -""" -Verify site_scons system dirs are getting loaded. -Uses an internal test fixture to get at the site_scons dirs. - -TODO: it would be great to test if it can actually load site_scons -files from the system dirs, but the test harness can't put files in -those dirs (which may not even exist on a build system). -""" - -test = TestSCons.TestSCons() - -test.write('SConstruct', """ -import SCons.Script -SCons.Script.Main.test_load_all_site_scons_dirs(Dir('.').path) -""") - -test.run(arguments = '-Q .') - -import SCons.Platform -platform = SCons.Platform.platform_default() -if platform in ('win32', 'cygwin'): - dir_to_check_for='Application Data' -elif platform in ('darwin'): - dir_to_check_for='Library' -else: - dir_to_check_for='.scons' - -if 'Loading site dir' not in test.stdout(): - print test.stdout() - test.fail_test() -if dir_to_check_for not in test.stdout(): - print test.stdout() - test.fail_test() - -test.pass_test() - -# end of file - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import TestSCons + +""" +Verify site_scons system dirs are getting loaded. +Uses an internal test fixture to get at the site_scons dirs. + +TODO: it would be great to test if it can actually load site_scons +files from the system dirs, but the test harness can't put files in +those dirs (which may not even exist on a build system). +""" + +test = TestSCons.TestSCons() + +test.write('SConstruct', """ +import SCons.Script +SCons.Script.Main.test_load_all_site_scons_dirs(Dir('.').path) +""") + +test.run(arguments = '-Q .') + +import SCons.Platform +platform = SCons.Platform.platform_default() +if platform in ('win32', 'cygwin'): + dir_to_check_for='Application Data' +elif platform in ('darwin'): + dir_to_check_for='Library' +else: + dir_to_check_for='.scons' + +if 'Loading site dir' not in test.stdout(): + print(test.stdout()) + test.fail_test() +if dir_to_check_for not in test.stdout(): + print(test.stdout()) + test.fail_test() + +test.pass_test() + +# end of file + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/spaces.py b/test/spaces.py index db1ae97..1309047 100644 --- a/test/spaces.py +++ b/test/spaces.py @@ -36,7 +36,7 @@ if sys.platform == 'win32': else: test.write('duplicate a file.sh', 'cp foo.in foo.out\n') copy = test.workpath('duplicate a file.sh') - os.chmod(test.workpath('duplicate a file.sh'), 0777) + os.chmod(test.workpath('duplicate a file.sh'), 0o777) test.write('SConstruct', r''' diff --git a/test/subdivide.py b/test/subdivide.py index 2978e08..44402c9 100644 --- a/test/subdivide.py +++ b/test/subdivide.py @@ -76,8 +76,8 @@ for s in sys.argv[2:]: ofp.write(open(s, 'rb').read()) """) -test.chmod(fake_cc_py, 0755) -test.chmod(fake_link_py, 0755) +test.chmod(fake_cc_py, 0o755) +test.chmod(fake_link_py, 0o755) test.write('SConstruct', """\ SConsignFile(None) diff --git a/test/update-release-info/update-release-info.py b/test/update-release-info/update-release-info.py index d3125c7..0db65ba 100644 --- a/test/update-release-info/update-release-info.py +++ b/test/update-release-info/update-release-info.py @@ -201,7 +201,7 @@ RELEASE 2.0.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE """, mode = 'r') -years = ', '.join(map(str, range(2001, this_year + 1))) +years = ', '.join(map(str, list(range(2001, this_year + 1)))) test.must_match(SConstruct, """ month_year = 'MONTH YEAR' copyright_years = %s diff --git a/timings/ElectricCloud/TimeSCons-run.py b/timings/ElectricCloud/TimeSCons-run.py index be75d12..fbe0028 100644 --- a/timings/ElectricCloud/TimeSCons-run.py +++ b/timings/ElectricCloud/TimeSCons-run.py @@ -87,7 +87,7 @@ test.run(program=test.workpath('genscons.pl'), arguments=' '.join(arguments)) # This print is nott for debugging, leave it alone! # We want to display the output from genscons.pl's generation the build # configuration, so the buildbot logs contain more info. -print test.stdout() +print(test.stdout()) test.main(chdir='sconsbld') diff --git a/www/gen_sched_table.py b/www/gen_sched_table.py index e67f0d7..9ac8acd 100755 --- a/www/gen_sched_table.py +++ b/www/gen_sched_table.py @@ -6,13 +6,13 @@ import datetime months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] -print '' +print('
') def row(*cells, **kw): td = kw.get('tr','td') - print ' ' + print(' ') for cell in cells: - print ' <%s>%s' % (td,cell,td) - print ' ' + print(' <%s>%s' % (td,cell,td)) + print(' ') row('Estimated date', 'Type', 'Comments', tr = 'th') if len(sys.argv) > 1: @@ -30,7 +30,7 @@ for line in f: incr,type,desc = line[1:].strip().split(None,2) now = now + datetime.timedelta(int(incr)) else: - print 'dunna understand code', line[0] + print('dunna understand code', line[0]) sys.exit(1) #name = current + '.d' + str(now).replace('-','') date = '%s-%s-%s' % (now.day,months[now.month-1],now.year) @@ -41,7 +41,7 @@ for line in f: else: category = current = type row(date, category, desc) -print '
' +print('') # Local Variables: # tab-width:4 -- cgit v0.12 From b554eb817c60f4e419bbc84efc02c7fbc62b7ced Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 22 Sep 2013 13:10:51 -0400 Subject: Manual python3 post-2to3 fixes from Neal Becker --- review.py | 2 +- src/engine/SCons/Action.py | 32 +++++++++++++++++++------------- src/engine/SCons/Conftest.py | 1 - src/engine/SCons/Errors.py | 4 +--- src/engine/SCons/Executor.py | 2 +- src/engine/SCons/SConf.py | 16 +++++++++++----- src/engine/SCons/Scanner/__init__.py | 2 +- src/engine/SCons/Script/SConscript.py | 2 +- src/engine/SCons/Script/__init__.py | 2 +- src/engine/SCons/Taskmaster.py | 10 +++------- src/engine/SCons/Tool/__init__.py | 4 ++-- src/engine/SCons/Tool/g++.py | 5 ++--- src/engine/SCons/Tool/gas.py | 5 ++++- src/engine/SCons/Tool/gcc.py | 2 +- src/engine/SCons/Tool/link.py | 2 +- src/engine/SCons/Tool/swig.py | 2 +- src/engine/SCons/Util.py | 19 +++++++++++++++---- src/engine/SCons/dblite.py | 16 ++++++---------- src/script/scons.py | 10 +++++----- 19 files changed, 76 insertions(+), 62 deletions(-) diff --git a/review.py b/review.py index 72e187e..8d033ed 100644 --- a/review.py +++ b/review.py @@ -1627,7 +1627,7 @@ def FormatSubversionPropertyChanges(filename, props): See the following doctest for example. - >>> print FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')]) + >>> print(FormatSubversionPropertyChanges('foo.cc', [('svn:eol-style', 'LF')])) Property changes on: foo.cc ___________________________________________________________________ Added: svn:eol-style diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index e8574cb..68c93b4 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -237,9 +237,9 @@ def _code_contents(code): # The code contents depends on the number of local variables # but not their actual names. - contents.append("%s,%s" % (code.co_argcount, len(code.co_varnames))) + contents.append(str.encode("%s,%s" % (code.co_argcount, len(code.co_varnames)))) try: - contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars))) + contents.append(str.encode(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars)))) except AttributeError: # Older versions of Python do not support closures. contents.append(",0,0") @@ -252,19 +252,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(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')') + contents.append(b',(' + b','.join(map(_object_contents,code.co_consts[1:])) + b')') # 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(',(' + ','.join(map(_object_contents,code.co_names)) + ')') + contents.append(b',(' + b','.join(map(_object_contents,code.co_names)) + b')') # The code contents depends on its actual code!!! - contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')') + contents.append(b',(' + remove_set_lineno_codes(code.co_code) + b')') - return ''.join(contents) + return b''.join(contents) def _function_contents(func): @@ -274,9 +274,9 @@ def _function_contents(func): # The function contents depends on the value of defaults arguments if func.__defaults__: - contents.append(',(' + ','.join(map(_object_contents,func.__defaults__)) + ')') + contents.append(b',(' + b','.join(map(_object_contents,func.__defaults__)) + b')') else: - contents.append(',()') + contents.append(b',()') # The function contents depends on the closure captured cell values. try: @@ -290,9 +290,9 @@ def _function_contents(func): xxx = [_object_contents(x.cell_contents) for x in closure] except AttributeError: xxx = [] - contents.append(',(' + ','.join(xxx) + ')') + contents.append(b',(' + b','.join(xxx) + b')') - return ''.join(contents) + return b''.join(contents) def _actionAppend(act1, act2): @@ -434,14 +434,20 @@ class ActionBase(object): def get_contents(self, target, source, env): result = [ self.get_presig(target, source, env) ] + def clean (u): + if isinstance (u, bytes): + return u + elif isinstance (u, str): + return bytes (u, 'utf-8') + result = [ clean(r) for r in result ] # This should never happen, as the Action() factory should wrap # the varlist, but just in case an action is created directly, # we duplicate this check here. vl = self.get_varlist(target, source, env) if is_String(vl): vl = (vl,) for v in vl: - result.append(env.subst('${'+v+'}')) - return ''.join(result) + result.append(bytes(env.subst('${'+v+'}'), 'utf-8')) + return b''.join(result) def __add__(self, other): return _actionAppend(self, other) @@ -1135,7 +1141,7 @@ class ListAction(ActionBase): Simple concatenation of the signatures of the elements. """ - return "".join([x.get_contents(target, source, env) for x in self.list]) + return b"".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): diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py index d466278..4e2a3e8 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 -from types import IntType # # PUBLIC VARIABLES diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py index 3b8c3f9..54e888c 100644 --- a/src/engine/SCons/Errors.py +++ b/src/engine/SCons/Errors.py @@ -32,8 +32,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Util -import exceptions - class BuildError(Exception): """ Errors occuring while building. @@ -163,7 +161,7 @@ def convert_to_BuildError(status, exc_info=None): status=2, exitstatus=2, exc_info=exc_info) - elif isinstance(status, exceptions.EnvironmentError): + elif isinstance(status, EnvironmentError): # If an IOError/OSError happens, raise a BuildError. # Report the name of the file or directory that caused the # error, which might be different from the target being built diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 6f2489b..68419b8 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -427,7 +427,7 @@ class Executor(object): except KeyError: pass env = self.get_build_env() - result = "".join([action.get_contents(self.get_all_targets(), + result = b"".join([action.get_contents(self.get_all_targets(), self.get_all_sources(), env) for action in self.get_action_list()]) diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index 987f88d..e14c5e0 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -175,13 +175,19 @@ class Streamer(object): """ def __init__(self, orig): self.orig = orig - self.s = io.StringIO() + try: + import StringIO + self.s = StringIO.StringIO() + except: + self.s = io.StringIO() def write(self, str): - if self.orig: - self.orig.write(str) - self.s.write(str) - + try: + if self.orig: + self.orig.write(str) + self.s.write(str) + except: + print ('oops') def writelines(self, lines): for l in lines: self.write(l + '\n') diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index 6ec8df9..8801094 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -325,7 +325,7 @@ class Classic(Current): def __init__(self, name, suffixes, path_variable, regex, *args, **kw): - self.cre = re.compile(regex, re.M) + self.cre = re.compile(SCons.Util.to_bytes(regex), re.M) def _scan(node, env, path=(), self=self): node = node.rfile() diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index fefffef..05cb6a6 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -257,7 +257,7 @@ def _SConscript(fs, *files, **kw): pass try: try: - exec(_file_, call_stack[-1].globals) + exec(_file_.read(), call_stack[-1].globals) except SConscriptReturn: pass finally: diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 9f2837c..e9e8b71 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -364,7 +364,7 @@ GlobalDefaultBuilders = [ ] for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders: - exec("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))) + exec ("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))) del name # There are a handful of variables that used to live in the diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 54d04a8..14ffe8c 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -518,13 +518,9 @@ class Task(object): Raises a pending exception that was recorded while getting a Task ready for execution. """ - exc = self.exc_info()[:] - try: - exc_type, exc_value, exc_traceback = exc - except ValueError: - exc_type, exc_value = exc - exc_traceback = None - raise exc_type(exc_value).with_traceback(exc_traceback) + + import six + six.reraise(*self.exc_info()) class AlwaysTask(Task): def needs_execute(self): diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index ac180a9..1d5b504 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -114,7 +114,7 @@ class Tool(object): if file: file.close() except ImportError as e: - if str(e)!="No module named %s"%self.name: + if not str(e).startswith ("No module"): raise SCons.Errors.EnvironmentError(e) try: import zipimport @@ -144,7 +144,7 @@ class Tool(object): file.close() return module except ImportError as e: - if str(e)!="No module named %s"%self.name: + if not str(e).startswith("No module"): raise SCons.Errors.EnvironmentError(e) try: import zipimport diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py index e4da5fe..0e1c181 100644 --- a/src/engine/SCons/Tool/g++.py +++ b/src/engine/SCons/Tool/g++.py @@ -40,8 +40,7 @@ import subprocess import SCons.Tool import SCons.Util -cplusplus = __import__('c++', globals(), locals(), []) - +cplusplus = __import__(__package__+'.c++', globals(), locals(), ['*']) compilers = ['g++'] def generate(env): @@ -75,7 +74,7 @@ def generate(env): #line = pipe.stdout.read().strip() #if line: # env['CXXVERSION'] = line - line = pipe.stdout.readline() + line = SCons.Util.to_str (pipe.stdout.readline()) match = re.search(r'[0-9]+(\.[0-9]+)+', line) if match: env['CXXVERSION'] = match.group(0) diff --git a/src/engine/SCons/Tool/gas.py b/src/engine/SCons/Tool/gas.py index 28f84db..d01bd60 100644 --- a/src/engine/SCons/Tool/gas.py +++ b/src/engine/SCons/Tool/gas.py @@ -33,7 +33,10 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -as_module = __import__('as', globals(), locals(), []) +try: + as_module = __import__('as', globals(), locals(), []) +except: + as_module = __import__(__package__+'.as', globals(), locals(), ['*']) assemblers = ['as', 'gas'] diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py index 4f87b24..72f9bfd 100644 --- a/src/engine/SCons/Tool/gcc.py +++ b/src/engine/SCons/Tool/gcc.py @@ -65,7 +65,7 @@ def generate(env): #line = pipe.stdout.read().strip() #if line: # env['CCVERSION'] = line - line = pipe.stdout.readline() + line = SCons.Util.to_str (pipe.stdout.readline()) match = re.search(r'[0-9]+(\.[0-9]+)+', line) if match: env['CCVERSION'] = match.group(0) diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 5539f62..864a018 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.py @@ -42,7 +42,7 @@ import SCons.Warnings from SCons.Tool.FortranCommon import isfortran -cplusplus = __import__('c++', globals(), locals(), []) +cplusplus = __import__(__package__+'.c++', globals(), locals(), ['*']) issued_mixed_link_warning = False diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index d51a386..5d2264c 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -131,7 +131,7 @@ def _get_swig_version(env): stdout = subprocess.PIPE) if pipe.wait() != 0: return - out = pipe.stdout.read() + out = SCons.Util.to_str (pipe.stdout.read()) match = re.search(r'SWIG Version\s+(\S+)$', out, re.MULTILINE) if match: return match.group(1) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index f2e5325..00fde6c 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -37,7 +37,6 @@ import collections # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. -InstanceType = types.InstanceType MethodType = types.MethodType FunctionType = types.FunctionType try: str @@ -1370,7 +1369,7 @@ def AddMethod(obj, function, name=None): setattr(obj, name, MethodType(function, obj, obj.__class__)) else: # "obj" is a class, so it gets an unbound method. - setattr(obj, name, MethodType(function, None, obj)) + setattr(obj, name, function) def RenameFunction(function, name): """ @@ -1402,7 +1401,7 @@ else: md5 = True def MD5signature(s): m = hashlib.md5() - m.update(str(s)) + m.update(to_bytes(str(s))) return m.hexdigest() def MD5filesignature(fname, chunksize=65536): @@ -1412,7 +1411,7 @@ else: blck = f.read(chunksize) if not blck: break - m.update(str(blck)) + m.update(to_bytes (str(blck))) f.close() return m.hexdigest() @@ -1486,6 +1485,18 @@ class NullSeq(Null): del __revision__ +def to_bytes (s): + if bytes is str: + return s + else: + return bytes (s, 'utf-8') + +def to_str (s): + if bytes is str: + return s + else: + return str (s, 'utf-8') + # Local Variables: # tab-width:4 # indent-tabs-mode:nil diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 89b9856..99af54a 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -16,14 +16,10 @@ ignore_corrupt_dbfiles = 0 def corruption_warning(filename): print("Warning: Discarding corrupt database:", filename) -try: str -except NameError: - def is_string(s): - return isinstance(s, str) -else: - def is_string(s): - return type(s) in (str, str) - +def is_string(s): + return isinstance(s, str) +def is_bytes(s): + return isinstance (s, bytes) try: str('a') except NameError: @@ -148,8 +144,8 @@ class dblite(object): self._check_writable() if (not is_string(key)): raise TypeError("key `%s' must be a string but is %s" % (key, type(key))) - if (not is_string(value)): - raise TypeError("value `%s' must be a string but is %s" % (value, type(value))) + if (not is_bytes(value)): + raise TypeError("value `%s' must be a bytes but is %s" % (value, type(value))) self._dict[key] = value self._needs_sync = 0o001 diff --git a/src/script/scons.py b/src/script/scons.py index 46e6d2b..89eef34 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -55,11 +55,11 @@ import sys # engine modules if they're in either directory. -if sys.version_info >= (3,0,0): - msg = "scons: *** SCons version %s does not run under Python version %s.\n\ -Python 3 is not yet supported.\n" - sys.stderr.write(msg % (__version__, sys.version.split()[0])) - sys.exit(1) +## if sys.version_info >= (3,0,0): +## msg = "scons: *** SCons version %s does not run under Python version %s.\n\ +## Python 3 is not yet supported.\n" +## sys.stderr.write(msg % (__version__, sys.version.split()[0])) +## sys.exit(1) script_dir = sys.path[0] -- cgit v0.12 From 0727ee61d6ec6eeb099b0d179fa77a1a86046ee8 Mon Sep 17 00:00:00 2001 From: ndbecker2 Date: Mon, 9 Sep 2013 10:14:53 -0400 Subject: 2 minor issues (transplanted from 6711a6b819f61764bb82c0f32a251b91ec66a0b2) --- QMTest/TestCmd.py | 3 ++- src/engine/SCons/Action.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 4f08d1f..26401ad 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1,3 +1,4 @@ +from __future__ import print_function """ TestCmd.py: a testing framework for commands and scripts. @@ -950,7 +951,7 @@ class TestCmd(object): condition = self.condition if self._preserve[condition]: for dir in self._dirlist: - print(str("Preserved directory " + dir + "\n"), end=' ') + print("Preserved directory " + dir + "\n", end=' ') else: list = self._dirlist[:] list.reverse() diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 68c93b4..7a97dae 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -446,7 +446,7 @@ class ActionBase(object): vl = self.get_varlist(target, source, env) if is_String(vl): vl = (vl,) for v in vl: - result.append(bytes(env.subst('${'+v+'}'), 'utf-8')) + result.append(SCons.Util.to_bytes(env.subst('${'+v+'}'))) return b''.join(result) def __add__(self, other): -- cgit v0.12 From 8473d8293b056663f8a3caf04550039b18690a70 Mon Sep 17 00:00:00 2001 From: ndbecker2 Date: Mon, 9 Sep 2013 10:39:46 -0400 Subject: minor cleanup (transplanted from 4feb1b15eb7a0c76cb020e09817c509a782d45b7) --- src/engine/SCons/Action.py | 7 +------ src/engine/SCons/Util.py | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 7a97dae..66757a4 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -434,12 +434,7 @@ class ActionBase(object): def get_contents(self, target, source, env): result = [ self.get_presig(target, source, env) ] - def clean (u): - if isinstance (u, bytes): - return u - elif isinstance (u, str): - return bytes (u, 'utf-8') - result = [ clean(r) for r in result ] + result = [ SCons.Util.to_bytes(r) for r in result ] # This should never happen, as the Action() factory should wrap # the varlist, but just in case an action is created directly, # we duplicate this check here. diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 00fde6c..0c4daff 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -1486,7 +1486,7 @@ class NullSeq(Null): del __revision__ def to_bytes (s): - if bytes is str: + if isinstance (s, bytes) or bytes is str: return s else: return bytes (s, 'utf-8') -- cgit v0.12 From 7dd07e75f428379c90eb9bb486b79ad103283bf6 Mon Sep 17 00:00:00 2001 From: ndbecker2 Date: Mon, 9 Sep 2013 12:03:44 -0400 Subject: fix for cpp scanner (maybe) (transplanted from c68b1a5da5ad47befc3a7e802d8ae23372f0e1a8) --- src/engine/SCons/Scanner/__init__.py | 3 ++- src/engine/SCons/dblite.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index 8801094..b947961 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -394,6 +394,7 @@ class ClassicCPP(Classic): the contained filename in group 1. """ def find_include(self, include, source_dir, path): + include = list (map (SCons.Util.to_str, include)) if include[0] == '"': paths = (source_dir,) + tuple(path) else: @@ -405,7 +406,7 @@ class ClassicCPP(Classic): return n, i def sort_key(self, include): - return SCons.Node.FS._my_normcase(' '.join(include)) + return SCons.Node.FS._my_normcase(b' '.join(include)) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 99af54a..4b02239 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -26,6 +26,8 @@ except NameError: def str(s): return s dblite_suffix = '.dblite' +if bytes is not str: + dblite_suffix += '.p3' tmp_suffix = '.tmp' class dblite(object): @@ -238,7 +240,6 @@ def _exercise(): assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e) else: raise RuntimeError("IOError expected.") - print("OK") if (__name__ == "__main__"): _exercise() -- cgit v0.12 From 9f36c5b899b8d2d54cae8d3da76b01308c144ed6 Mon Sep 17 00:00:00 2001 From: ndbecker2 Date: Tue, 10 Sep 2013 10:02:23 -0400 Subject: setup.py: don't error on py3 (transplanted from 16fc64cadd68f2f9032c14d04bc0bf94f99b71a4) --- src/setup.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/setup.py b/src/setup.py index a8b59a3..2c75c60 100644 --- a/src/setup.py +++ b/src/setup.py @@ -46,14 +46,6 @@ man_pages = [ 'scons-time.1', ] -# Exit with error if trying to install with Python >= 3.0 -if sys.version_info >= (3,0,0): - msg = "scons: *** SCons does not run under Python version %s.\n\ -Python 3 and above are not yet supported.\n" - sys.stderr.write(msg % (sys.version.split()[0])) - sys.exit(1) - - # change to setup.py directory if it was executed from other dir (head, tail) = os.path.split(sys.argv[0]) if head: -- cgit v0.12 From 1a1a11122ad28df19d305af879ba79a2b08ce7d4 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 15:13:02 +0000 Subject: Made former 2to3 changes Python 2.7 compatible (or removed unneeded changes). --- QMTest/TestCmd.py | 7 +- QMTest/TestCmdTests.py | 109 ++++++++-------- QMTest/TestCommon.py | 1 + QMTest/TestSCons.py | 12 +- QMTest/TestSConsign.py | 1 + QMTest/scons_tdb.py | 4 +- SConstruct | 15 +-- bench/bench.py | 4 +- bench/env.__setitem__.py | 4 +- bench/is_types.py | 12 +- bench/timeit.py | 4 +- bin/Command.py | 1 + bin/SConsDoc.py | 9 +- bin/calibrate.py | 2 +- bin/caller-tree.py | 3 +- bin/docs-create-example-outputs.py | 1 + bin/docs-update-generated.py | 1 + bin/docs-validate.py | 1 + bin/install_python.py | 1 + bin/install_scons.py | 8 +- bin/linecount.py | 2 +- bin/memlogs.py | 1 + bin/memoicmp.py | 9 +- bin/objcounts.py | 5 +- bin/scons-diff.py | 5 +- bin/scons-proc.py | 4 +- bin/scons-test.py | 5 +- bin/scons-unzip.py | 1 + bin/scons_dev_master.py | 1 + bin/sfsum | 11 +- bin/svn-bisect.py | 2 +- bin/update-release-info.py | 3 +- bin/xmlagenda.py | 1 + doc/SConscript | 25 ++-- review.py | 139 ++++++++++++--------- runtest.py | 8 +- src/engine/SCons/Action.py | 19 ++- src/engine/SCons/ActionTests.py | 8 +- src/engine/SCons/Builder.py | 21 ++-- src/engine/SCons/BuilderTests.py | 9 +- src/engine/SCons/Conftest.py | 2 +- src/engine/SCons/Debug.py | 4 +- src/engine/SCons/Defaults.py | 7 +- src/engine/SCons/Environment.py | 33 +++-- src/engine/SCons/EnvironmentTests.py | 17 +-- src/engine/SCons/Executor.py | 4 +- src/engine/SCons/Memoize.py | 1 + src/engine/SCons/MemoizeTests.py | 5 +- src/engine/SCons/Node/FS.py | 10 +- src/engine/SCons/Node/FSTests.py | 4 +- src/engine/SCons/Node/__init__.py | 4 +- src/engine/SCons/Platform/__init__.py | 1 + src/engine/SCons/Platform/posix.py | 2 +- src/engine/SCons/SConf.py | 21 ++-- src/engine/SCons/SConfTests.py | 2 +- src/engine/SCons/SConsign.py | 9 +- src/engine/SCons/Scanner/Fortran.py | 3 +- src/engine/SCons/Scanner/LaTeX.py | 4 +- src/engine/SCons/Scanner/Prog.py | 3 +- src/engine/SCons/Scanner/ProgTests.py | 2 +- src/engine/SCons/Scanner/ScannerTests.py | 2 +- src/engine/SCons/Scanner/__init__.py | 5 +- src/engine/SCons/Script/Interactive.py | 5 +- src/engine/SCons/Script/Main.py | 7 +- src/engine/SCons/Script/SConsOptions.py | 2 +- src/engine/SCons/Script/SConscript.py | 4 +- src/engine/SCons/Subst.py | 4 +- src/engine/SCons/SubstTests.py | 1 + src/engine/SCons/Taskmaster.py | 29 ++--- src/engine/SCons/TaskmasterTests.py | 2 +- src/engine/SCons/Tool/FortranCommon.py | 5 +- src/engine/SCons/Tool/MSCommon/common.py | 5 +- src/engine/SCons/Tool/MSCommon/vc.py | 2 +- src/engine/SCons/Tool/MSCommon/vs.py | 2 +- src/engine/SCons/Tool/__init__.py | 3 +- .../docbook-xsl-1.76.1/extensions/docbook.py | 1 + .../docbook/docbook-xsl-1.76.1/extensions/xslt.py | 1 + src/engine/SCons/Tool/install.py | 1 + src/engine/SCons/Tool/intelc.py | 6 +- src/engine/SCons/Tool/link.py | 1 + src/engine/SCons/Tool/mslink.py | 3 +- src/engine/SCons/Tool/msvs.py | 17 +-- src/engine/SCons/Tool/msvsTests.py | 1 + src/engine/SCons/Tool/packaging/__init__.py | 2 +- src/engine/SCons/Tool/packaging/ipk.py | 2 +- src/engine/SCons/Tool/packaging/msi.py | 6 +- src/engine/SCons/Tool/packaging/rpm.py | 4 +- src/engine/SCons/Tool/qt.py | 1 + src/engine/SCons/Tool/rpmutils.py | 1 + src/engine/SCons/Tool/tex.py | 1 + src/engine/SCons/Tool/textfile.py | 3 +- src/engine/SCons/Tool/xgettext.py | 3 +- src/engine/SCons/Util.py | 61 ++++++--- src/engine/SCons/UtilTests.py | 17 +-- src/engine/SCons/Variables/EnumVariableTests.py | 4 +- src/engine/SCons/Variables/__init__.py | 2 +- src/engine/SCons/compat/_scons_subprocess.py | 12 +- src/engine/SCons/cpp.py | 11 +- src/engine/SCons/cppTests.py | 2 +- src/engine/SCons/dblite.py | 26 ++-- src/script/scons-time.py | 12 +- src/script/sconsign.py | 10 +- src/test_files.py | 3 +- src/test_interrupts.py | 2 +- src/test_pychecker.py | 1 + src/test_setup.py | 1 + src/test_strings.py | 1 + test/AS/nasm.py | 2 +- test/Actions/unicode-signature.py | 12 +- test/AddOption/help.py | 1 + test/Configure/ConfigureDryRunError.py | 1 + test/Configure/config-h.py | 1 + test/Configure/implicit-cache.py | 1 + test/Deprecated/SourceCode/BitKeeper/BitKeeper.py | 1 + test/Deprecated/SourceCode/Subversion.py | 1 + test/GetBuildFailures/parallel.py | 1 + test/Glob/glob-libpath.py | 1 + test/Interactive/version.py | 1 + test/Java/multi-step.py | 1 + test/MSVC/msvc.py | 1 + test/QT/QTFLAGS.py | 2 +- test/QT/copied-env.py | 1 + test/QT/warnings.py | 1 + test/Scanner/unicode.py | 20 +-- test/TEX/TEX.py | 1 + test/Value.py | 1 + test/Win32/bad-drive.py | 1 + test/Win32/default-drive.py | 1 + test/gnutools.py | 1 + test/import.py | 1 + test/option--random.py | 1 + test/option-v.py | 1 + test/option/debug-count.py | 1 + test/option/debug-time.py | 2 +- test/option/help-options.py | 1 + test/option/profile.py | 4 +- test/site_scons/sysdirs.py | 1 + test/update-release-info/update-release-info.py | 2 +- timings/ElectricCloud/TimeSCons-run.py | 1 + www/gen_sched_table.py | 1 + 140 files changed, 566 insertions(+), 418 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 26401ad..488d940 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1,4 +1,3 @@ -from __future__ import print_function """ TestCmd.py: a testing framework for commands and scripts. @@ -286,7 +285,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 division, print_function __author__ = "Steven Knight " __revision__ = "TestCmd.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -356,7 +355,7 @@ except NameError: return isinstance(e, (str, UserString)) else: def is_String(e): - return isinstance(e, (str, UserString)) + return isinstance(e, (str, unicode, UserString)) tempfile.template = 'testcmd.' if os.name in ('posix', 'nt'): @@ -951,7 +950,7 @@ class TestCmd(object): condition = self.condition if self._preserve[condition]: for dir in self._dirlist: - print("Preserved directory " + dir + "\n", end=' ') + print("Preserved directory " + dir + "\n") else: list = self._dirlist[:] list.reverse() diff --git a/QMTest/TestCmdTests.py b/QMTest/TestCmdTests.py index 96e0cbf..6611590 100644 --- a/QMTest/TestCmdTests.py +++ b/QMTest/TestCmdTests.py @@ -19,6 +19,8 @@ AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ +from six import PY3 + __author__ = "Steven Knight " __revision__ = "TestCmdTests.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -26,13 +28,20 @@ import os import shutil import signal import stat -import io +if PY3: + from io import StringIO +else: + from StringIO import StringIO import sys import tempfile import time import types import unittest -import collections +if PY3: + from collections import UserList +else: + from UserList import UserList + # Strip the current directory so we get the right TestCmd.py module. sys.path = sys.path[1:] @@ -1032,14 +1041,14 @@ class match_exact_TestCase(TestCmdTestCase): assert test.match_exact("abcde\n", "abcde\n") assert not test.match_exact(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_exact(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) - assert not test.match_exact(collections.UserList(["12345\n", "abcde\n"]), + assert not test.match_exact(UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) - assert test.match_exact(collections.UserList(["12345\n", "abcde\n"]), + assert test.match_exact(UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert not test.match_exact(["12345\n", "abcde\n"], - collections.UserList(["1[0-9]*5\n", "a.*e\n"])) + UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_exact(["12345\n", "abcde\n"], - collections.UserList(["12345\n", "abcde\n"])) + UserList(["12345\n", "abcde\n"])) assert not test.match_exact("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_exact("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] @@ -1098,28 +1107,28 @@ sys.exit(0) ["1.*j\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], ["12345\n", "abcde\n", "fghij\n"]) - assert test.match_re_dotall(collections.UserList(["12345\n", - "abcde\n", - "fghij\n"]), + assert test.match_re_dotall(UserList(["12345\n", + "abcde\n", + "fghij\n"]), ["1[0-9]*5\n", "a.*e\n", "f.*j\n"]) - assert test.match_re_dotall(collections.UserList(["12345\n", - "abcde\n", - "fghij\n"]), + assert test.match_re_dotall(UserList(["12345\n", + "abcde\n", + "fghij\n"]), ["1.*j\n"]) - assert test.match_re_dotall(collections.UserList(["12345\n", - "abcde\n", - "fghij\n"]), + assert test.match_re_dotall(UserList(["12345\n", + "abcde\n", + "fghij\n"]), ["12345\n", "abcde\n", "fghij\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - collections.UserList(["1[0-9]*5\n", - "a.*e\n", - "f.*j\n"])) + UserList(["1[0-9]*5\n", + "a.*e\n", + "f.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - collections.UserList(["1.*j\n"])) + UserList(["1.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], - collections.UserList(["12345\n", - "abcde\n", - "fghij\n"])) + UserList(["12345\n", + "abcde\n", + "fghij\n"])) assert test.match_re_dotall("12345\nabcde\nfghij\n", "1[0-9]*5\na.*e\nf.*j\n") assert test.match_re_dotall("12345\nabcde\nfghij\n", "1.*j\n") @@ -1176,14 +1185,14 @@ sys.exit(0) assert test.match_re("abcde\n", "abcde\n") assert test.match_re(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_re(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) - assert test.match_re(collections.UserList(["12345\n", "abcde\n"]), + assert test.match_re(UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) - assert test.match_re(collections.UserList(["12345\n", "abcde\n"]), + assert test.match_re(UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert test.match_re(["12345\n", "abcde\n"], - collections.UserList(["1[0-9]*5\n", "a.*e\n"])) + UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_re(["12345\n", "abcde\n"], - collections.UserList(["12345\n", "abcde\n"])) + UserList(["12345\n", "abcde\n"])) assert test.match_re("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_re("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] @@ -1463,7 +1472,7 @@ class preserve_TestCase(TestCmdTestCase): def test_preserve(self): """Test preserve()""" def cleanup_test(test, cond=None, stdout=""): - io = io.StringIO() + io = StringIO() save = sys.stdout sys.stdout = io try: @@ -1603,7 +1612,7 @@ class read_TestCase(TestCmdTestCase): _file_matches(wdir_foo_file3, test.read(['foo', 'file3']), "Test\nfile\n#3.\n") _file_matches(wdir_foo_file3, - test.read(collections.UserList(['foo', 'file3'])), + test.read(UserList(['foo', 'file3'])), "Test\nfile\n#3.\n") _file_matches(wdir_file4, test.read('file4', mode = 'r'), "Test\nfile\n#4.\n") @@ -1862,8 +1871,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() @@ -1876,8 +1885,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path @@ -1913,8 +1922,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) @@ -1934,8 +1943,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) @@ -1958,8 +1967,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 2) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) @@ -1978,8 +1987,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 3) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) @@ -2002,8 +2011,8 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '') - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) @@ -2022,8 +2031,8 @@ class run_verbose_TestCase(TestCmdTestCase): testx = TestCmd.TestCmd(program = t.scriptx, workdir = '') - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) @@ -2048,8 +2057,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() @@ -2062,8 +2071,8 @@ class run_verbose_TestCase(TestCmdTestCase): workdir = '', verbose = 1) - sys.stdout = io.StringIO() - sys.stderr = io.StringIO() + sys.stdout = StringIO() + sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path @@ -2769,7 +2778,7 @@ class subdir_TestCase(TestCmdTestCase): assert test.subdir(['foo', 'fail']) == 0 assert test.subdir(['sub', 'dir', 'ectory'], 'sub') == 1 assert test.subdir('one', - collections.UserList(['one', 'two']), + UserList(['one', 'two']), ['one', 'two', 'three']) == 3 assert os.path.isdir(test.workpath('foo')) assert os.path.isdir(test.workpath('bar')) @@ -2962,7 +2971,7 @@ class unlink_TestCase(TestCmdTestCase): test.unlink(['foo', 'file3a']) assert not os.path.exists(wdir_foo_file3a) - test.unlink(collections.UserList(['foo', 'file3b'])) + test.unlink(UserList(['foo', 'file3b'])) assert not os.path.exists(wdir_foo_file3b) test.unlink([test.workdir, 'foo', 'file4']) diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index 5a397ff..f1a7407 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -90,6 +90,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 print_function __author__ = "Steven Knight " __revision__ = "TestCommon.py 1.3.D001 2010/06/03 12:58:27 knight" diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 72624e6..5d0b4c6 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -13,7 +13,7 @@ attributes defined in this subclass. """ # __COPYRIGHT__ - +from __future__ import division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -721,7 +721,7 @@ class TestSCons(TestCommon): home = os.path.normpath('%s/..'%jar) if os.path.isdir(home): return home - print(("Could not determine JAVA_HOME: %s is not a directory" % home)) + print("Could not determine JAVA_HOME: %s is not a directory" % home) self.fail_test() def java_where_jar(self, version=None): @@ -1013,7 +1013,7 @@ SConscript( sconscript ) raise NoMatch(lastEnd) return m.end() + lastEnd try: - #print len(os.linesep) + #print(len(os.linesep)) ls = os.linesep nols = "(" for i in range(len(ls)): @@ -1241,7 +1241,7 @@ class TimeSCons(TestSCons): self.variables = kw.get('variables') default_calibrate_variables = [] if self.variables is not None: - for variable, value in list(self.variables.items()): + for variable, value in self.variables.items(): value = os.environ.get(variable, value) try: value = int(value) @@ -1297,7 +1297,7 @@ class TimeSCons(TestSCons): """ if 'options' not in kw and self.variables: options = [] - for variable, value in list(self.variables.items()): + for variable, value in self.variables.items(): options.append('%s=%s' % (variable, value)) kw['options'] = ' '.join(options) if self.calibrate: @@ -1323,7 +1323,7 @@ class TimeSCons(TestSCons): self.elapsed_time(), "seconds", sort=0) - for name, args in list(stats.items()): + for name, args in stats.items(): self.trace(name, trace, **args) def uptime(self): diff --git a/QMTest/TestSConsign.py b/QMTest/TestSConsign.py index 665059c..a48b648 100644 --- a/QMTest/TestSConsign.py +++ b/QMTest/TestSConsign.py @@ -1,4 +1,5 @@ # __COPYRIGHT__ +from __future__ import print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py index 845e99c..76c7fe1 100644 --- a/QMTest/scons_tdb.py +++ b/QMTest/scons_tdb.py @@ -20,7 +20,7 @@ # 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 division, print_function """ QMTest classes to support SCons' testing and Aegis-inspired workflow. @@ -92,7 +92,7 @@ def get_explicit_arguments(e): # Determine which subset of the 'arguments' have been set # explicitly. explicit_arguments = {} - for name, field in list(arguments.items()): + for name, field in arguments.items(): # Do not record computed fields. if field.IsComputed(): continue diff --git a/SConstruct b/SConstruct index f289947..1a0aef0 100644 --- a/SConstruct +++ b/SConstruct @@ -2,6 +2,7 @@ # SConstruct file to build scons packages during development. # # See the README.rst file for an overview of how SCons is built and tested. +from __future__ import print_function # 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. @@ -327,7 +328,7 @@ try: import zipfile def zipit(env, target, source): - print "Zipping %s:" % str(target[0]) + print("Zipping %s:" % str(target[0])) def visit(arg, dirname, names): for name in names: path = os.path.join(dirname, name) @@ -341,7 +342,7 @@ try: zf.close() def unzipit(env, target, source): - print "Unzipping %s:" % str(source[0]) + print("Unzipping %s:" % str(source[0])) zf = zipfile.ZipFile(str(source[0]), 'r') for name in zf.namelist(): dest = os.path.join(env['UNPACK_ZIP_DIR'], name) @@ -350,7 +351,7 @@ try: os.makedirs(dir) except: pass - print dest,name + print(dest,name) # if the file exists, then delete it before writing # to it so that we don't end up trying to write to a symlink: if os.path.isfile(dest) or os.path.islink(dest): @@ -558,7 +559,7 @@ else: i = install_egg_info(dist) i.finalize_options() import os.path - print os.path.split(i.outputs[0])[1] + print(os.path.split(i.outputs[0])[1]) """ % version try: @@ -853,7 +854,7 @@ for p in [ scons ]: AddPostAction(dist_distutils_targets, Chmod(dist_distutils_targets, 0644)) if not gzip: - print "gzip not found in %s; skipping .tar.gz package for %s." % (os.environ['PATH'], pkg) + print("gzip not found in %s; skipping .tar.gz package for %s." % (os.environ['PATH'], pkg)) else: distutils_formats.append('gztar') @@ -928,7 +929,7 @@ for p in [ scons ]: env.Command(digest, tar_gz, Digestify) if not zipit: - print "zip not found; skipping .zip package for %s." % pkg + print("zip not found; skipping .zip package for %s." % pkg) else: distutils_formats.append('zip') @@ -1211,7 +1212,7 @@ elif svn_status_lines: sentries = [l.split()[-1] for l in slines] sfiles = list(filter(os.path.isfile, sentries)) else: - print "Not building in a Mercurial or Subversion tree; skipping building src package." + print("Not building in a Mercurial or Subversion tree; skipping building src package.") if sfiles: remove_patterns = [ diff --git a/bench/bench.py b/bench/bench.py index 1a98d8c..f1d18c6 100644 --- a/bench/bench.py +++ b/bench/bench.py @@ -23,7 +23,7 @@ # # This will allow (as much as possible) us to time just the code itself, # not Python function call overhead. - +from __future__ import division, print_function import getopt import sys @@ -94,7 +94,7 @@ exec(open(args[0], 'rU').read()) try: FunctionList except NameError: - function_names = sorted([x for x in list(locals().keys()) if x[:4] == FunctionPrefix]) + function_names = sorted([x for x in locals().keys() if x[:4] == FunctionPrefix]) l = [locals()[f] for f in function_names] FunctionList = [f for f in l if isinstance(f, types.FunctionType)] diff --git a/bench/env.__setitem__.py b/bench/env.__setitem__.py index 284653e..9c27b6d 100644 --- a/bench/env.__setitem__.py +++ b/bench/env.__setitem__.py @@ -33,7 +33,7 @@ class Timing(object): def times(num=1000000, init='', title='Results:', **statements): # time each statement timings = [] - for n, s in list(statements.items()): + for n, s in statements.items(): t = Timing(n, num, init, s) t.timeit() timings.append(t) @@ -287,7 +287,7 @@ else: # that the timer will use to get at these classes. class_names = [] -for n in list(locals().keys()): +for n in locals().keys(): #if n.startswith('env_'): if n[:4] == 'env_': class_names.append(n) diff --git a/bench/is_types.py b/bench/is_types.py index b6da0d2..69c029f 100644 --- a/bench/is_types.py +++ b/bench/is_types.py @@ -17,11 +17,11 @@ InstanceType = types.InstanceType DictType = dict ListType = list StringType = str -try: str +try: unicode except NameError: UnicodeType = None else: - UnicodeType = str + UnicodeType = unicode # The original implementations, pretty straightforward checks for the @@ -36,7 +36,7 @@ def original_is_List(e): if UnicodeType is not None: def original_is_String(e): - return isinstance(e, (str,UserString)) + return isinstance(e, (str,unicode,UserString)) else: def original_is_String(e): return isinstance(e, (str,UserString)) @@ -58,7 +58,7 @@ def checkInstanceType_is_List(e): if UnicodeType is not None: def checkInstanceType_is_String(e): return isinstance(e, str) \ - or isinstance(e, str) \ + or isinstance(e, unicode) \ or (isinstance(e, types.InstanceType) and isinstance(e, UserString)) else: def checkInstanceType_is_String(e): @@ -84,7 +84,7 @@ if UnicodeType is not None: def cache_type_e_is_String(e): t = type(e) return t is str \ - or t is str \ + or t is unicode \ or (t is types.InstanceType and isinstance(e, UserString)) else: def cache_type_e_is_String(e): @@ -136,7 +136,7 @@ if UnicodeType is not None: t = type(obj) if t is types.InstanceType: t = instanceTypeMap.get(obj.__class__, t) - elif t is str: + elif t is unicode: t = str return t else: diff --git a/bench/timeit.py b/bench/timeit.py index 2840010..7db0dd4 100644 --- a/bench/timeit.py +++ b/bench/timeit.py @@ -46,7 +46,7 @@ be aware of it. The baseline overhead can be measured by invoking the program without arguments. The baseline overhead differs between Python versions! """ - +from __future__ import division, print_function try: import gc @@ -245,7 +245,7 @@ def main(args=None): precision = precision + 1 verbose = precision + 1 if o in ("-h", "--help"): - print(__doc__, end=' ') + print(__doc__) return 0 setup = "\n".join(setup) or "pass" # Include the current directory, so that local imports work (sys.path diff --git a/bin/Command.py b/bin/Command.py index 768caed..dadd7a9 100644 --- a/bin/Command.py +++ b/bin/Command.py @@ -4,6 +4,7 @@ # # XXX Describe what the script does here. # +from __future__ import print_function import getopt import os diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py index 453e241..80f41a5 100644 --- a/bin/SConsDoc.py +++ b/bin/SConsDoc.py @@ -24,6 +24,7 @@ # # Module for handling SCons documentation processing. # +from __future__ import print_function __doc__ = """ This module parses home-brew XML files that document various things @@ -51,7 +52,7 @@ Builder example: to indicate a new paragraph. - print "this is example code, it will be offset and indented" + print("this is example code, it will be offset and indented") @@ -71,7 +72,7 @@ Function example: &f-FUNCTION; element. It need not be on a line by itself. - print "this is example code, it will be offset and indented" + print("this is example code, it will be offset and indented") @@ -88,7 +89,7 @@ Construction variable example: &t-VARIABLE; element. It need not be on a line by itself. - print "this is example code, it will be offset and indented" + print("this is example code, it will be offset and indented") @@ -105,7 +106,7 @@ Tool example: &t-TOOL; element. It need not be on a line by itself. - print "this is example code, it will be offset and indented" + print("this is example code, it will be offset and indented") diff --git a/bin/calibrate.py b/bin/calibrate.py index 31c04e8..3f9104e 100644 --- a/bin/calibrate.py +++ b/bin/calibrate.py @@ -20,7 +20,7 @@ # 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 division, print_function import optparse import os diff --git a/bin/caller-tree.py b/bin/caller-tree.py index 327e6a1..21cda4b 100644 --- a/bin/caller-tree.py +++ b/bin/caller-tree.py @@ -39,6 +39,7 @@ # function at the same time, for example, their counts will intermix. # So use this to get a *general* idea of who's calling what, not for # fine-grained performance tuning. +from __future__ import print_function import sys @@ -86,7 +87,7 @@ def print_entry(e, level, calls): else: print() -for e in [ e for e in list(AllCalls.values()) if not e.calls ]: +for e in [ e for e in AllCalls.values() if not e.calls ]: print_entry(e, 0, '') # Local Variables: diff --git a/bin/docs-create-example-outputs.py b/bin/docs-create-example-outputs.py index b2dfbea..64dcf2e 100644 --- a/bin/docs-create-example-outputs.py +++ b/bin/docs-create-example-outputs.py @@ -3,6 +3,7 @@ # Searches through the whole doc/user tree and creates # all output files for the single examples. # +from __future__ import print_function import os import sys diff --git a/bin/docs-update-generated.py b/bin/docs-update-generated.py index 2b419a4..d22cc32 100644 --- a/bin/docs-update-generated.py +++ b/bin/docs-update-generated.py @@ -6,6 +6,7 @@ # as well as the entity declarations for them. # Uses scons-proc.py under the hood... # +from __future__ import print_function import os import SConsDoc diff --git a/bin/docs-validate.py b/bin/docs-validate.py index e5d0659..e53a89d 100644 --- a/bin/docs-validate.py +++ b/bin/docs-validate.py @@ -3,6 +3,7 @@ # Searches through the whole source tree and validates all # documentation files against our own XSD in docs/xsd. # +from __future__ import print_function import sys,os import SConsDoc diff --git a/bin/install_python.py b/bin/install_python.py index dca37d0..5c947ac 100644 --- a/bin/install_python.py +++ b/bin/install_python.py @@ -6,6 +6,7 @@ # This was written for a Linux system (specifically Ubuntu) but should # be reasonably generic to any POSIX-style system with a /usr/local # hierarchy. +from __future__ import print_function import getopt import os diff --git a/bin/install_scons.py b/bin/install_scons.py index b732193..7a39e96 100644 --- a/bin/install_scons.py +++ b/bin/install_scons.py @@ -17,13 +17,17 @@ # This was written for a Linux system (specifically Ubuntu) but should # be reasonably generic to any POSIX-style system with a /usr/local # hierarchy. +from __future__ import print_function import getopt import os import shutil import sys import tarfile -import urllib.request, urllib.parse, urllib.error +try: + from urllib.request import urlretrieve +except ImportError: # Python < 3 + from urllib import urlretrieve from Command import CommandRunner, Usage @@ -171,7 +175,7 @@ Usage: install_scons.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...] if not os.path.exists(tar_gz): if not os.path.exists(downloads_dir): cmd.run('mkdir %(downloads_dir)s') - cmd.run((urllib.request.urlretrieve, tar_gz_url, tar_gz), + cmd.run((urlretrieve, tar_gz_url, tar_gz), 'wget -O %(tar_gz)s %(tar_gz_url)s') def extract(tar_gz): diff --git a/bin/linecount.py b/bin/linecount.py index 2d478f0..897f1e8 100644 --- a/bin/linecount.py +++ b/bin/linecount.py @@ -21,7 +21,7 @@ # in each category, the number of non-blank lines, and the number of # non-comment lines. The last figure (non-comment) lines is the most # interesting one for most purposes. - +from __future__ import division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/bin/memlogs.py b/bin/memlogs.py index 0409dfe..6e68ce0 100644 --- a/bin/memlogs.py +++ b/bin/memlogs.py @@ -20,6 +20,7 @@ # 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 print_function import getopt import sys diff --git a/bin/memoicmp.py b/bin/memoicmp.py index 5021c41..1106ac3 100644 --- a/bin/memoicmp.py +++ b/bin/memoicmp.py @@ -2,6 +2,7 @@ # # A script to compare the --debug=memoizer output found in # two different files. +from future import print_function import sys @@ -29,14 +30,14 @@ def memoize_cmp(filea, fileb): ma_o = [] mb_o = [] mab = [] - for k in list(ma.keys()): - if k in list(mb.keys()): + for k in ma.keys(): + if k in mb.keys(): if k not in mab: mab.append(k) else: ma_o.append(k) - for k in list(mb.keys()): - if k in list(ma.keys()): + for k in mb.keys(): + if k in ma.keys(): if k not in mab: mab.append(k) else: diff --git a/bin/objcounts.py b/bin/objcounts.py index 25b985b..2bd8923 100644 --- a/bin/objcounts.py +++ b/bin/objcounts.py @@ -20,6 +20,7 @@ # 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 print_function import re import sys @@ -47,7 +48,7 @@ c1 = fetch_counts(sys.argv[1]) c2 = fetch_counts(sys.argv[2]) common = {} -for k in list(c1.keys()): +for k in c1.keys(): try: common[k] = (c1[k], c2[k]) except KeyError: @@ -58,7 +59,7 @@ for k in list(c1.keys()): if not '.' in k: s = '.'+k l = len(s) - for k2 in list(c2.keys()): + for k2 in c2.keys(): if k2[-l:] == s: common[k2] = (c1[k], c2[k2]) del c1[k] diff --git a/bin/scons-diff.py b/bin/scons-diff.py index 5181fa1..8597501 100644 --- a/bin/scons-diff.py +++ b/bin/scons-diff.py @@ -8,6 +8,7 @@ # etc. so that you can diff trees without having to ignore changes in # version lines. # +from __future__ import print_function import difflib import getopt @@ -161,7 +162,7 @@ def diff_file(left, right): else: if text: diff_line(left, right) - print(text, end=' ') + print(text) elif report_same: print('Files %s and %s are identical' % (left, right)) @@ -173,7 +174,7 @@ def diff_dir(left, right): u[l] = 1 for r in rlist: u[r] = 1 - for x in sorted([ x for x in list(u.keys()) if x[-4:] != '.pyc' ]): + for x in sorted([ x for x in u.keys() if x[-4:] != '.pyc' ]): if x in llist: if x in rlist: do_diff(os.path.join(left, x), diff --git a/bin/scons-proc.py b/bin/scons-proc.py index 19be4c3..b93b25a 100644 --- a/bin/scons-proc.py +++ b/bin/scons-proc.py @@ -9,6 +9,8 @@ # DocBook-formatted generated XML files containing the summary text # and/or .mod files containing the ENTITY definitions for each item. # +from __future__ import print_function + import getopt import os import re @@ -106,7 +108,7 @@ Link_Entities_Header = """\ class SCons_XML(object): def __init__(self, entries, **kw): self.values = entries - for k, v in list(kw.items()): + for k, v in kw.items(): setattr(self, k, v) def fopen(self, name): diff --git a/bin/scons-test.py b/bin/scons-test.py index 788fc6d..dd54dd1 100644 --- a/bin/scons-test.py +++ b/bin/scons-test.py @@ -14,6 +14,7 @@ # relevant information about the system, the Python version, etc., # so that problems on different platforms can be identified sooner. # +from __future__ import print_function import atexit import getopt @@ -224,7 +225,7 @@ if format == '--xml': print(" ") command = '"%s" runtest.py -q -o - --xml %s' % (sys.executable, runtest_args) - #print command + #print(command) os.system(command) print("") @@ -243,7 +244,7 @@ else: print_version_info("engine", SCons) command = '"%s" runtest.py %s' % (sys.executable, runtest_args) - #print command + #print(command) os.system(command) # Local Variables: diff --git a/bin/scons-unzip.py b/bin/scons-unzip.py index 75d3281..a64179f 100644 --- a/bin/scons-unzip.py +++ b/bin/scons-unzip.py @@ -7,6 +7,7 @@ # I'm using this to make it more convenient to manage working on multiple # changes on Windows, where I don't have access to my Aegis tools. # +from __future__ import print_function import getopt import os.path diff --git a/bin/scons_dev_master.py b/bin/scons_dev_master.py index 71034ad..a8862ea 100644 --- a/bin/scons_dev_master.py +++ b/bin/scons_dev_master.py @@ -3,6 +3,7 @@ # A script for turning a generic Ubuntu system into a master for # SCons development. +from __future__ import print_function import getopt import sys diff --git a/bin/sfsum b/bin/sfsum index 2dfa422..142793a 100644 --- a/bin/sfsum +++ b/bin/sfsum @@ -22,6 +22,7 @@ # # https://sourceforge.net/projects/sitedocs/ # +from __future__ import print_function import xml.sax import xml.sax.saxutils @@ -121,9 +122,9 @@ if __name__ == '__main__': # generalized once we figure out other things for this script to do. bugs = [x for x in Artifacts['Bugs'] if x.status == 'Open'] - print list(Artifacts.keys()) + print(list(Artifacts.keys())) - print "%d open bugs" % len(bugs) + print("%d open bugs" % len(bugs)) # Sort them into a separate list for each assignee. Assigned = {} @@ -141,7 +142,7 @@ if __name__ == '__main__': except KeyError: pass else: - print " %s" % a - b.sort(lambda x, y: cmp(x.artifact_id, y.artifact_id)) + print(" %s" % a) + b.sort(key=lambda x, y: (x.artifact_id, y.artifact_id)) for bug in b: - print " %-6s %s" % (bug.artifact_id, bug.summary) + print(" %-6s %s" % (bug.artifact_id, bug.summary)) diff --git a/bin/svn-bisect.py b/bin/svn-bisect.py index f262366..dbf8dd9 100755 --- a/bin/svn-bisect.py +++ b/bin/svn-bisect.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- Python -*- - +from __future__ import division, print_function import sys from math import log, ceil diff --git a/bin/update-release-info.py b/bin/update-release-info.py index f60c187..b6cf942 100644 --- a/bin/update-release-info.py +++ b/bin/update-release-info.py @@ -56,6 +56,7 @@ In 'post' mode, files are prepared for the next release cycle: # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -332,7 +333,7 @@ t.replace_assign('deprecated_python_version', str(deprecated_version)) # Update doc/user/main.{in,xml} -docyears = ', '.join(map(str, iter(list(range(2004, release_date[0] + 1))))) +docyears = ', '.join(map(str, range(2004, release_date[0] + 1))) t = UpdateFile(os.path.join('doc', 'user', 'main.in')) if DEBUG: t.file = '/tmp/main.in' ## TODO debug these diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py index 40f5ca1..fcfe53e 100755 --- a/bin/xmlagenda.py +++ b/bin/xmlagenda.py @@ -18,6 +18,7 @@ # Grab the sort bar on the far left (just above the "1" for row one) # and move it down one row. (Row one becomes a floating header) # Voila! +from __future__ import print_function # The team members # FIXME: These names really should be external to this script diff --git a/doc/SConscript b/doc/SConscript index 8dcf697..c6b8f74 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -23,6 +23,7 @@ # 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 print_function import os.path import re @@ -84,16 +85,16 @@ except: try: import lxml except: - print "doc: Neither libxml2 nor lxml Python bindings found!" - print " Please install one of the packages python-libxml2 or python-lxml." + print("doc: Neither libxml2 nor lxml Python bindings found!") + print(" Please install one of the packages python-libxml2 or python-lxml.") skip_doc = True if not fop and not xep: - print "doc: No PDF renderer found (fop|xep)!" + print("doc: No PDF renderer found (fop|xep)!") skip_doc = True if skip_doc: - print "doc: ...skipping building User Guide." + print("doc: ...skipping building User Guide.") else: # # Always create a version.xml file containing the version information @@ -109,18 +110,18 @@ else: # Ensure that all XML files are valid against our XSD, and # that all example names and example output suffixes are unique # - print "Validating files against SCons XSD..." + print("Validating files against SCons XSD...") if SConsDoc.validate_all_xml(['src'], xsdfile='xsd/scons.xsd'): - print "OK" + print("OK") else: - print "Validation failed! Please correct the errors above and try again." + print("Validation failed! Please correct the errors above and try again.") sys.exit(0) - print "Checking whether all example names are unique..." + print("Checking whether all example names are unique...") if SConsExamples.exampleNamesAreUnique(os.path.join('doc','user')): - print "OK" + print("OK") else: - print "Not all example names and suffixes are unique! Please correct the errors listed above and try again." + print("Not all example names and suffixes are unique! Please correct the errors listed above and try again.") sys.exit(0) # @@ -358,7 +359,7 @@ else: # epydoc_cli is found if not epydoc_cli and not epydoc: - print "doc: epydoc not found, skipping building API documentation." + print("doc: epydoc not found, skipping building API documentation.") else: # XXX Should be in common with reading the same thing in # the SConstruct file. @@ -380,7 +381,7 @@ else: tar_list.append(htmldir) if not epydoc_cli: - print "doc: command line epydoc is not found, skipping PDF/PS/Tex output" + print("doc: command line epydoc is not found, skipping PDF/PS/Tex output") else: # PDF and PostScript and TeX are built from the # same invocation. diff --git a/review.py b/review.py index 8d033ed..c01472e 100644 --- a/review.py +++ b/review.py @@ -13,6 +13,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from __future__ import print_function """Tool for uploading diffs from a version control system to the codereview app. @@ -31,8 +32,16 @@ against by using the '--rev' option. # This code is derived from appcfg.py in the App Engine SDK (open source), # and from ASPN recipe #146306. -import configparser -import http.cookiejar +try: + from configparser import ConfigParser +except ImportError: # Python < 3 + from ConfigParser import ConfigParser +try: + from http.cookiejar import ( + CookieJar, MozillaCookieJar, LoadError as CookieLoadError) +except ImportError: # Python < 3 + from cookielib import ( + CookieJar, MozillaCookieJar, LoadError as CookieLoadError) import fnmatch import getpass import logging @@ -43,6 +52,24 @@ import re import socket import subprocess import sys +try: + from urllib.request import ( + Request, OpenerDirector, + ProxyHandler, UnknownHandler, HTTPHandler, HTTPSHandler, + HTTPDefaultErrorHandler, HTTPErrorProcessor, + HTTPCookieProcessor) + from urllib.error import HTTPError + from urllib.parse import ( + urlencode, urlparse, urlunparse, splituser as urlsplituser) +except ImportError: # Python < 3 + from urllib2 import ( + Request, OpenerDirector, + ProxyHandler, UnknownHandler, HTTPHandler, HTTPSHandler, + HTTPDefaultErrorHandler, HTTPErrorProcessor, HTTPError, + HTTPCookieProcessor, + urlparse) + from urllib import urlencode, splituser as urlsplituser + from urlparse import urlparse, urlunparse import urllib.request, urllib.parse, urllib.error import urllib.request, urllib.error, urllib.parse import urllib.parse @@ -155,11 +182,11 @@ def ErrorExit(msg): sys.exit(1) -class ClientLoginError(urllib.error.HTTPError): +class ClientLoginError(HTTPError): """Raised to indicate there was an error authenticating with ClientLogin.""" def __init__(self, url, code, msg, headers, args): - urllib.error.HTTPError.__init__(self, url, code, msg, headers, None) + HTTPError.__init__(self, url, code, msg, headers, None) self.args = args self.reason = args["Error"] self.info = args.get("Info", None) @@ -212,7 +239,7 @@ class AbstractRpcServer(object): def _CreateRequest(self, url, data=None): """Creates a new urllib request.""" logging.debug("Creating request for: '%s' with payload:\n%s", url, data) - req = urllib.request.Request(url, data=data) + req = Request(url, data=data) if self.host_override: req.add_header("Host", self.host_override) for key, value in self.extra_headers.items(): @@ -239,7 +266,7 @@ class AbstractRpcServer(object): account_type = "HOSTED" req = self._CreateRequest( url="https://www.google.com/accounts/ClientLogin", - data=urllib.parse.urlencode({ + data=urlencode({ "Email": email, "Passwd": password, "service": "ah", @@ -253,7 +280,7 @@ class AbstractRpcServer(object): response_dict = dict(x.split("=") for x in response_body.split("\n") if x) return response_dict["Auth"] - except urllib.error.HTTPError as e: + except HTTPError as e: if e.code == 403: body = e.read() response_dict = dict(x.split("=", 1) for x in body.split("\n") if x) @@ -275,15 +302,15 @@ class AbstractRpcServer(object): continue_location = "http://localhost/" args = {"continue": continue_location, "auth": auth_token} req = self._CreateRequest("%s/_ah/login?%s" % - (self.host, urllib.parse.urlencode(args))) + (self.host, urlencode(args))) try: response = self.opener.open(req) - except urllib.error.HTTPError as e: + except HTTPError as e: response = e if (response.code != 302 or response.info()["location"] != continue_location): - raise urllib.error.HTTPError(req.get_full_url(), response.code, response.msg, - response.headers, response.fp) + raise HTTPError(req.get_full_url(), response.code, response.msg, + response.headers, response.fp) self.authenticated = True def _Authenticate(self): @@ -306,23 +333,23 @@ class AbstractRpcServer(object): try: auth_token = self._GetAuthToken(credentials[0], credentials[1]) except ClientLoginError as e: - print('', file=sys.stderr) + print(file=sys.stderr) if e.reason == "BadAuthentication": if e.info == "InvalidSecondFactor": - print(( - "Use an application-specific password instead " - "of your regular account password.\n" - "See http://www.google.com/" - "support/accounts/bin/answer.py?answer=185833"), file=sys.stderr) + print("Use an application-specific password instead " + "of your regular account password.\n" + "See http://www.google.com/" + "support/accounts/bin/answer.py?answer=185833", + file=sys.stderr) else: print("Invalid username or password.", file=sys.stderr) elif e.reason == "CaptchaRequired": - print(( - "Please go to\n" - "https://www.google.com/accounts/DisplayUnlockCaptcha\n" - "and verify you are a human. Then try again.\n" - "If you are using a Google Apps account the URL is:\n" - "https://www.google.com/a/yourdomain.com/UnlockCaptcha"), file=sys.stderr) + print("Please go to\n" + "https://www.google.com/accounts/DisplayUnlockCaptcha\n" + "and verify you are a human. Then try again.\n" + "If you are using a Google Apps account the URL is:\n" + "https://www.google.com/a/yourdomain.com/UnlockCaptcha", + file=sys.stderr) elif e.reason == "NotVerified": print("Account not verified.", file=sys.stderr) elif e.reason == "TermsNotAgreed": @@ -333,14 +360,15 @@ class AbstractRpcServer(object): print("The user account has been disabled.", file=sys.stderr) break elif e.reason == "ServiceDisabled": - print(("The user's access to the service has been " - "disabled."), file=sys.stderr) + print("The user's access to the service has been disabled.", + file=sys.stderr) elif e.reason == "ServiceUnavailable": - print("The service is not available; try again later.", file=sys.stderr) + print("The service is not available; try again later.", + file=sys.stderr) else: # Unknown error. raise - print('', file=sys.stderr) + print(file=sys.stderr) continue self._GetAuthCookie(auth_token) return @@ -380,18 +408,18 @@ class AbstractRpcServer(object): args = dict(kwargs) url = "%s%s" % (self.host, request_path) if args: - url += "?" + urllib.parse.urlencode(args) + url += "?" + urlencode(args) req = self._CreateRequest(url=url, data=payload) req.add_header("Content-Type", content_type) if extra_headers: - for header, value in list(extra_headers.items()): + for header, value in extra_headers.items(): req.add_header(header, value) try: f = self.opener.open(req) response = f.read() f.close() return response - except urllib.error.HTTPError as e: + except HTTPError as e: if tries > 3: raise elif e.code == 401 or e.code == 302: @@ -402,7 +430,7 @@ class AbstractRpcServer(object): elif e.code == 301: # Handle permanent redirect manually. url = e.info()["location"] - url_loc = urllib.parse.urlparse(url) + url_loc = urlparse(url) self.host = '%s://%s' % (url_loc[0], url_loc[1]) else: raise @@ -426,23 +454,23 @@ class HttpRpcServer(AbstractRpcServer): Returns: A urllib2.OpenerDirector object. """ - opener = urllib.request.OpenerDirector() - opener.add_handler(urllib.request.ProxyHandler()) - opener.add_handler(urllib.request.UnknownHandler()) - opener.add_handler(urllib.request.HTTPHandler()) - opener.add_handler(urllib.request.HTTPDefaultErrorHandler()) - opener.add_handler(urllib.request.HTTPSHandler()) - opener.add_handler(urllib2.HTTPErrorProcessor()) + opener = OpenerDirector() + opener.add_handler(ProxyHandler()) + opener.add_handler(UnknownHandler()) + opener.add_handler(HTTPHandler()) + opener.add_handler(HTTPDefaultErrorHandler()) + opener.add_handler(HTTPSHandler()) + opener.add_handler(HTTPErrorProcessor()) if self.save_cookies: self.cookie_file = os.path.expanduser("~/.codereview_upload_cookies") - self.cookie_jar = http.cookiejar.MozillaCookieJar(self.cookie_file) + self.cookie_jar = MozillaCookieJar(self.cookie_file) if os.path.exists(self.cookie_file): try: self.cookie_jar.load() self.authenticated = True StatusUpdate("Loaded authentication cookies from %s" % self.cookie_file) - except (http.cookiejar.LoadError, IOError): + except (CookieLoadError, IOError): # Failed to load cookies - just ignore them. pass else: @@ -453,8 +481,8 @@ class HttpRpcServer(AbstractRpcServer): os.chmod(self.cookie_file, 0o600) else: # Don't save cookies across runs of update.py. - self.cookie_jar = http.cookiejar.CookieJar() - opener.add_handler(urllib.request.HTTPCookieProcessor(self.cookie_jar)) + self.cookie_jar = CookieJar() + opener.add_handler(HTTPCookieProcessor(self.cookie_jar)) return opener @@ -804,8 +832,8 @@ class VersionControlSystem(object): else: type = "current" if len(content) > MAX_UPLOAD_SIZE: - print(("Not uploading the %s file for %s because it's too large." % - (type, filename))) + print("Not uploading the %s file for %s because it's too large." % + (type, filename)) file_too_large = True content = "" checksum = md5(content).hexdigest() @@ -832,7 +860,7 @@ class VersionControlSystem(object): patches = dict() [patches.setdefault(v, k) for k, v in patch_list] - for filename in list(patches.keys()): + for filename in patches.keys(): base_content, new_content, is_binary, status = files[filename] file_id_str = patches.get(filename) if file_id_str.find("nobase") != -1: @@ -898,7 +926,7 @@ class SubversionVCS(VersionControlSystem): for line in info.splitlines(): if line.startswith("URL: "): url = line.split()[1] - scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url) + scheme, netloc, path, params, query, fragment = urlparse(url) guess = "" if netloc == "svn.python.org" and scheme == "svn+ssh": path = "projects" + path @@ -908,8 +936,7 @@ class SubversionVCS(VersionControlSystem): scheme = "http" guess = "Google Code " path = path + "/" - base = urllib.parse.urlunparse((scheme, netloc, path, params, - query, fragment)) + base = urlunparse((scheme, netloc, path, params, query, fragment)) logging.info("Guessed %sbase = %s", guess, base) return base if required: @@ -1412,8 +1439,8 @@ def UploadSeparatePatches(issue, rpc_server, patchset, data, options): rv = [] for patch in patches: if len(patch[1]) > MAX_UPLOAD_SIZE: - print(("Not uploading the patch for " + patch[0] + - " because the file is too large.")) + print("Not uploading the patch for " + patch[0] + + " because the file is too large.") continue form_fields = [("filename", patch[0])] if not options.download_base: @@ -1551,7 +1578,7 @@ def LoadSubversionAutoProperties(): subversion_config = os.path.expanduser("~/.subversion/config") if not os.path.exists(subversion_config): return {} - config = configparser.ConfigParser() + config = ConfigParser() config.read(subversion_config) if (config.has_section("miscellany") and config.has_option("miscellany", "enable-auto-props") and @@ -1606,7 +1633,7 @@ def GetSubversionPropertyChanges(filename): svn_auto_props_map = LoadSubversionAutoProperties() all_props = [] - for file_pattern, props in list(svn_auto_props_map.items()): + for file_pattern, props in svn_auto_props_map.items(): if fnmatch.fnmatch(filename, file_pattern): all_props.extend(props) if all_props: @@ -1703,12 +1730,12 @@ def RealMain(argv, data=None): options.account_type) form_fields = [("subject", message)] if base: - b = urllib.parse.urlparse(base) - username, netloc = urllib.parse.splituser(b.netloc) + b = urlparse(base) + username, netloc = urlsplituser(b.netloc) if username: logging.info("Removed username from base URL") - base = urllib.parse.urlunparse((b.scheme, netloc, b.path, b.params, - b.query, b.fragment)) + base = urlunparse((b.scheme, netloc, b.path, b.params, + b.query, b.fragment)) form_fields.append(("base", base)) if options.issue: form_fields.append(("issue", str(options.issue))) diff --git a/runtest.py b/runtest.py index 65d7851..0fad655 100755 --- a/runtest.py +++ b/runtest.py @@ -81,6 +81,7 @@ # library directory. If we ever resurrect that as the default, then # you can find the appropriate code in the 0.04 version of this script, # rather than reinventing that wheel.) +from __future__ import print_function import getopt import glob @@ -92,7 +93,10 @@ import time try: import threading - import queue # 2to3: rename to queue + try: + from queue import Queue + except ImportError: # Python < 3 + from Queue import Queue threading_ok = True except ImportError: print("Can't import threading or queue") @@ -865,7 +869,7 @@ class RunTest(threading.Thread): if jobs > 1 and threading_ok: print("Running tests using %d jobs"%jobs) # Start worker threads - queue = queue.Queue() + queue = Queue() io_lock = threading.Lock() for i in range(1, jobs): t = RunTest(queue, io_lock) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 66757a4..006e8f5 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -114,7 +114,6 @@ import SCons.Errors import SCons.Executor import SCons.Util import SCons.Subst -import collections # we use these a lot, so try to optimize them is_String = SCons.Util.is_String @@ -329,7 +328,7 @@ def _do_create_keywords(args, kw): cmdstrfunc = args[0] if cmdstrfunc is None or is_String(cmdstrfunc): kw['cmdstr'] = cmdstrfunc - elif isinstance(cmdstrfunc, collections.Callable): + elif callable(cmdstrfunc): kw['strfunction'] = cmdstrfunc else: raise SCons.Errors.UserError( @@ -360,7 +359,7 @@ def _do_create_action(act, kw): if is_List(act): return CommandAction(act, **kw) - if isinstance(act, collections.Callable): + if callable(act): try: gen = kw['generator'] del kw['generator'] @@ -494,7 +493,7 @@ class _ActionAction(ActionBase): self.targets = targets if batch_key: - if not isinstance(batch_key, collections.Callable): + if not callable(batch_key): # They have set batch_key, but not to their own # callable. The default behavior here will batch # *all* targets+sources using this action, separated @@ -514,7 +513,7 @@ class _ActionAction(ActionBase): # This code assumes s is a regular string, but should # work if it's unicode too. try: - sys.stdout.write(str(s + "\n")) + sys.stdout.write(s + u"\n") except UnicodeDecodeError: sys.stdout.write(s + "\n") @@ -555,7 +554,7 @@ class _ActionAction(ActionBase): source = executor.get_all_sources() t = ' and '.join(map(str, target)) l = '\n '.join(self.presub_lines(env)) - out = "Building %s with action:\n %s\n" % (t, l) + out = u"Building %s with action:\n %s\n" % (t, l) sys.stdout.write(out) cmd = None if show and self.strfunction: @@ -655,7 +654,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw): # Ensure that the ENV values are all strings: new_env = {} - for key, value in list(ENV.items()): + for key, value in ENV.items(): if is_List(value): # If the value is a list, then we assume it is a path list, # because that's a pretty common list-like value to stick @@ -781,7 +780,7 @@ class CommandAction(_ActionAction): ENV = get_default_ENV(env) # Ensure that the ENV values are all strings: - for key, value in list(ENV.items()): + for key, value in ENV.items(): if not is_String(value): if is_List(value): # If the value is a list, then we assume it is a @@ -1040,7 +1039,7 @@ class FunctionAction(_ActionAction): else: if strfunc is None: return None - if isinstance(strfunc, collections.Callable): + if callable(strfunc): return strfunc(target, source, env) name = self.function_name() tstr = array(target) @@ -1216,7 +1215,7 @@ class ActionCaller(object): def subst_kw(self, target, source, env): kw = {} - for key in list(self.kw.keys()): + for key in self.kw.keys(): kw[key] = self.subst(self.kw[key], target, source, env) return kw diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 6edf373..754c6e7 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -133,7 +133,7 @@ class Environment(object): self.d['SPAWN'] = scons_env['SPAWN'] self.d['PSPAWN'] = scons_env['PSPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in list(kw.items()): + for k, v in kw.items(): self.d[k] = v # Just use the underlying scons_subst*() utility methods. def subst(self, strSubst, raw=0, target=[], source=[], conv=None): @@ -158,12 +158,12 @@ class Environment(object): def Clone(self, **kw): res = Environment() res.d = SCons.Util.semi_deepcopy(self.d) - for k, v in list(kw.items()): + for k, v in kw.items(): res.d[k] = v return res def sig_dict(self): d = {} - for k,v in list(self.items()): d[k] = v + for k,v in self.items(): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] @@ -305,7 +305,7 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(cmd_action, ["string"]) - try: str + try: unicode except NameError: pass else: a2 = eval("SCons.Action.Action(u'string')") diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 6abcbcf..0f7aff4 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -179,7 +179,7 @@ class CallableSelector(SCons.Util.Selector): finds if it can.""" def __call__(self, env, source): value = SCons.Util.Selector.__call__(self, env, source) - if isinstance(value, collections.Callable): + if callable(value): value = value(env, source) return value @@ -230,7 +230,7 @@ class OverrideWarner(collections.UserDict): def warn(self): if self.already_warned: return - for k in list(self.keys()): + for k in self.keys(): if k in misleading_keywords: alt = misleading_keywords[k] msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k) @@ -336,7 +336,7 @@ class EmitterProxy(object): # in strings. Maybe we should change that? while SCons.Util.is_String(emitter) and emitter in env: emitter = env[emitter] - if isinstance(emitter, collections.Callable): + if callable(emitter): target, source = emitter(target, source, env) elif SCons.Util.is_List(emitter): for e in emitter: @@ -426,9 +426,12 @@ class BuilderBase(object): src_builder = [ src_builder ] self.src_builder = src_builder - def __bool__(self): + def __nonzero__(self): raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead") + def __bool__(self): + return self.__nonzero__() + def get_name(self, env): """Attempts to get the name of the Builder. @@ -638,18 +641,18 @@ class BuilderBase(object): def get_prefix(self, env, sources=[]): prefix = self.prefix - if isinstance(prefix, collections.Callable): + if callable(prefix): prefix = prefix(env, sources) return env.subst(prefix) def set_suffix(self, suffix): - if not isinstance(suffix, collections.Callable): + if not callable(suffix): suffix = self.adjust_suffix(suffix) self.suffix = suffix def get_suffix(self, env, sources=[]): suffix = self.suffix - if isinstance(suffix, collections.Callable): + if callable(suffix): suffix = suffix(env, sources) return env.subst(suffix) @@ -658,7 +661,7 @@ class BuilderBase(object): src_suffix = [] elif not SCons.Util.is_List(src_suffix): src_suffix = [ src_suffix ] - self.src_suffix = [isinstance(suf, collections.Callable) and suf or self.adjust_suffix(suf) for suf in 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.""" @@ -868,7 +871,7 @@ def is_a_Builder(obj): """ return (isinstance(obj, BuilderBase) or isinstance(obj, CompositeBuilder) - or isinstance(obj, collections.Callable)) + or callable(obj)) # Local Variables: # tab-width:4 diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index da03a3c..41b640b 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -77,7 +78,7 @@ class Environment(object): self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] self.d['ESCAPE'] = scons_env['ESCAPE'] - for k, v in list(kw.items()): + for k, v in kw.items(): self.d[k] = v global env_arg2nodes_called env_arg2nodes_called = None @@ -138,7 +139,7 @@ class Environment(object): return list(self.d.items()) def sig_dict(self): d = {} - for k,v in list(self.items()): d[k] = v + for k,v in self.items(): d[k] = v d['TARGETS'] = ['__t1__', '__t2__', '__t3__', '__t4__', '__t5__', '__t6__'] d['TARGET'] = d['TARGETS'][0] d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] @@ -305,11 +306,11 @@ class BuilderTestCase(unittest.TestCase): #be = target.get_build_env() #assert be['VAR'] == 'foo', be['VAR'] - try: str + try: unicode except NameError: uni = str else: - uni = str + uni = unicode target = builder(env, target = uni('n12 n13'), source = [uni('n14 n15')])[0] diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py index 4e2a3e8..6212a47 100644 --- a/src/engine/SCons/Conftest.py +++ b/src/engine/SCons/Conftest.py @@ -728,7 +728,7 @@ def _Have(context, key, have, comment = None): line = "#define %s 1\n" % key_up elif have == 0: line = "/* #undef %s */\n" % key_up - elif isinstance(have, IntType): + elif isinstance(have, int): line = "#define %s %d\n" % (key_up, have) else: line = "#define %s %s\n" % (key_up, str(have)) diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 363c8b7..1c0c638 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -73,7 +73,7 @@ def dumpLoggedInstances(classes, file=sys.stdout): obj = ref() if obj is not None: file.write(' %s:\n' % obj) - for key, value in list(obj.__dict__.items()): + for key, value in obj.__dict__.items(): file.write(' %20s : %s\n' % (key, value)) @@ -143,7 +143,7 @@ def caller_trace(back=0): # print a single caller and its callers, if any def _dump_one_caller(key, file, level=0): leader = ' '*level - for v,c in sorted([(-v,c) for c,v in list(caller_dicts[key].items())]): + for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) if c in caller_dicts: _dump_one_caller(c, file, level+1) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index fe1f87b..491b9f2 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -31,7 +31,7 @@ from distutils.msvccompiler. # 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 division __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -50,7 +50,6 @@ import SCons.Environment import SCons.PathList import SCons.Subst import SCons.Tool -import collections # A placeholder for a default Environment (for fetching source files # from source code management systems and the like). This must be @@ -326,9 +325,9 @@ def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None): if not itms: return itms - if not isinstance(c, collections.Callable): + if not callable(c): env_c = env['_concat'] - if env_c != _concat and isinstance(env_c, collections.Callable): + if env_c != _concat and callable(env_c): # There's a custom _concat() method in the construction # environment, and we've allowed people to set that in # the past (see test/custom-concat.py), so preserve the diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 88b0553..b5bd620 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -58,7 +58,6 @@ import SCons.Subst import SCons.Tool import SCons.Util import SCons.Warnings -import collections class _Null(object): pass @@ -128,7 +127,7 @@ future_reserved_construction_var_names = [ def copy_non_reserved_keywords(dict): result = semi_deepcopy(dict) - for k in list(result.keys()): + for k in result.keys(): if k in reserved_construction_var_names: msg = "Ignoring attempt to set reserved variable `$%s'" SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) @@ -152,7 +151,7 @@ def _set_BUILDERS(env, key, value): except KeyError: bd = BuilderDict(kwbd, env) env._dict[key] = bd - for k, v in list(value.items()): + for k, v in value.items(): if not SCons.Builder.is_a_Builder(v): raise SCons.Errors.UserError('%s is not a Builder.' % repr(v)) bd.update(value) @@ -324,7 +323,7 @@ class BuilderDict(UserDict): delattr(self.env, item) def update(self, dict): - for i, v in list(dict.items()): + for i, v in dict.items(): self.__setitem__(i, v) @@ -518,7 +517,7 @@ class SubstitutionEnvironment(object): def subst_kw(self, kw, raw=0, target=None, source=None): nkw = {} - for k, v in list(kw.items()): + for k, v in kw.items(): k = self.subst(k, raw, target, source) if SCons.Util.is_String(v): v = self.subst(v, raw, target, source) @@ -592,7 +591,7 @@ class SubstitutionEnvironment(object): out,err = p.communicate() status = p.wait() if err: - sys.stderr.write(str(err)) + sys.stderr.write(u"" + err) if status: raise OSError("'%s' exited %d" % (command, status)) return out @@ -630,7 +629,7 @@ class SubstitutionEnvironment(object): if not o: return self overrides = {} merges = None - for key, value in list(o.items()): + for key, value in o.items(): if key == 'parse_flags': merges = value else: @@ -815,7 +814,7 @@ class SubstitutionEnvironment(object): if not unique: self.Append(**args) return self - for key, value in list(args.items()): + for key, value in args.items(): if not value: continue try: @@ -1005,7 +1004,7 @@ class Base(SubstitutionEnvironment): # Now restore the passed-in and customized variables # to the environment, since the values the user set explicitly # should override any values set by the tools. - for key, val in list(save.items()): + for key, val in save.items(): self._dict[key] = val # Finally, apply any flags to be merged in @@ -1263,7 +1262,7 @@ class Base(SubstitutionEnvironment): values move to end. """ kw = copy_non_reserved_keywords(kw) - for key, val in list(kw.items()): + for key, val in kw.items(): if SCons.Util.is_List(val): val = _delete_duplicates(val, delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1403,7 +1402,7 @@ class Base(SubstitutionEnvironment): # so the tools can use the new variables kw = copy_non_reserved_keywords(kw) new = {} - for key, value in list(kw.items()): + for key, value in kw.items(): new[key] = SCons.Subst.scons_subst_once(value, self, key) clone.Replace(**new) @@ -1470,7 +1469,7 @@ class Base(SubstitutionEnvironment): copy_function = self._copy_from_cache elif function == 'timestamp-match': function = self._changed_timestamp_match - elif not isinstance(function, collections.Callable): + elif not callable(function): raise UserError("Unknown Decider value %s" % repr(function)) # We don't use AddMethod because we don't want to turn the @@ -1603,7 +1602,7 @@ class Base(SubstitutionEnvironment): in an Environment. """ kw = copy_non_reserved_keywords(kw) - for key, val in list(kw.items()): + for key, val in kw.items(): # It would be easier on the eyes to write this using # "continue" statements whenever we finish processing an item, # but Python 1.5.2 apparently doesn't let you use "continue" @@ -1694,7 +1693,7 @@ class Base(SubstitutionEnvironment): values move to front. """ kw = copy_non_reserved_keywords(kw) - for key, val in list(kw.items()): + for key, val in kw.items(): if SCons.Util.is_List(val): val = _delete_duplicates(val, not delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1769,7 +1768,7 @@ class Base(SubstitutionEnvironment): return os.path.join(dir, new_prefix+name+new_suffix) def SetDefault(self, **kw): - for k in list(kw.keys()): + for k in kw.keys(): if k in self._dict: del kw[k] self.Replace(**kw) @@ -1831,7 +1830,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in list(uniq.keys()): + for executor in uniq.keys(): executor.add_pre_action(action) return nodes @@ -1841,7 +1840,7 @@ class Base(SubstitutionEnvironment): uniq = {} for executor in [n.get_executor() for n in nodes]: uniq[executor] = 1 - for executor in list(uniq.keys()): + for executor in uniq.keys(): executor.add_post_action(action) return nodes diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 3af879a..22552b3 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -160,7 +161,7 @@ class TestEnvironmentFixture(object): default_keys = { 'CC' : 'cc', 'CCFLAGS' : '-DNDEBUG', 'ENV' : { 'TMP' : '/tmp' } } - for key, value in list(default_keys.items()): + for key, value in default_keys.items(): if key not in kw: kw[key] = value if 'BUILDERS' not in kw: @@ -263,16 +264,10 @@ class SubstitutionTestCase(unittest.TestCase): assert isinstance(nodes[0], X) assert nodes[0].name == "Util.py UtilTests.py" - try: str - except NameError: pass - else: - code = """if 1: - nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory) - assert len(nodes) == 1, nodes - assert isinstance(nodes[0], X) - assert nodes[0].name == u"Util.py UtilTests.py" - \n""" - exec(code, globals(), locals()) + nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory) + assert len(nodes) == 1, nodes + assert isinstance(nodes[0], X) + assert nodes[0].name == u"Util.py UtilTests.py" nodes = env.arg2nodes(["Util.py", "UtilTests.py"], Factory) assert len(nodes) == 2, nodes diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py index 68419b8..6248cf1 100644 --- a/src/engine/SCons/Executor.py +++ b/src/engine/SCons/Executor.py @@ -428,8 +428,8 @@ class Executor(object): pass env = self.get_build_env() result = b"".join([action.get_contents(self.get_all_targets(), - self.get_all_sources(), - env) + self.get_all_sources(), + env) for action in self.get_action_list()]) self._memo['get_contents'] = result return result diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index 9fe6851..ac728c9 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py index b6750e0..06b4235 100644 --- a/src/engine/SCons/MemoizeTests.py +++ b/src/engine/SCons/MemoizeTests.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 six import add_metaclass __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -29,8 +30,8 @@ import unittest import SCons.Memoize - -class FakeObject(object, metaclass=SCons.Memoize.Memoized_Metaclass): +@add_metaclass(SCons.Memoize.Memoized_Metaclass) +class FakeObject(object): memoizer_counters = [] diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 22dca1f..91c6893 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -31,6 +31,7 @@ that can be used by scripts or modules looking for the canonical default. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -54,7 +55,6 @@ import SCons.Util import SCons.Warnings from SCons.Debug import Trace -import collections do_store_info = True print_duplicate = 0 @@ -1509,7 +1509,7 @@ class Dir(Base): This clears any cached information that is invalidated by changing the repository.""" - for node in list(self.entries.values()): + for node in self.entries.values(): if node != self.dir: if node != self and isinstance(node, Dir): node.__clearRepositoryCache(duplicate) @@ -2056,7 +2056,7 @@ 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 list(dir.entries.items()) + node_names = [ v.name for k, v in dir.entries.items() if k not in ('.', '..') ] names.extend(node_names) if not strings: @@ -3197,10 +3197,10 @@ class FileFinder(object): except KeyError: pass - if verbose and not isinstance(verbose, collections.Callable): + if verbose and not callable(verbose): if not SCons.Util.is_String(verbose): verbose = "find_file" - _verbose = ' %s: ' % verbose + _verbose = u' %s: ' % verbose verbose = lambda s: sys.stdout.write(_verbose + s) filedir, filename = os.path.split(filename) diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index e8442e9..66803f9 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -20,7 +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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -1305,7 +1305,7 @@ class FSTestCase(_tempdirTestCase): assert f1.get_contents() == "Foo\x1aBar", f1.get_contents() # This tests to make sure we can decode UTF-8 text files. - test_string = "Foo\x1aBar" + test_string = u"Foo\x1aBar" test.write("utf8_file", test_string.encode('utf-8')) f1 = fs.File(test.workpath("utf8_file")) assert eval('f1.get_text_contents() == u"Foo\x1aBar"'), \ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 8f48d86..7f5d7ff 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -1197,8 +1197,8 @@ class Node(object): new_bkids = new.bsources + new.bdepends + new.bimplicit new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs - osig = dict(list(zip(old_bkids, old_bkidsigs))) - nsig = dict(list(zip(new_bkids, new_bkidsigs))) + osig = dict(zip(old_bkids, old_bkidsigs)) + nsig = dict(zip(new_bkids, new_bkidsigs)) # The sources and dependencies we'll want to report are all stored # as relative paths to this target's directory, but we want to diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index 6ef8b05..dba3606 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -41,6 +41,7 @@ their own platform 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index d1f6c78..908be4d 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -92,7 +92,7 @@ def _get_env_command(sh, escape, cmd, args, env): s = ' '.join(args) if env: l = ['env', '-'] + \ - [escape(t[0])+'='+escape(t[1]) for t in list(env.items())] + \ + [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \ [sh, '-c', escape(s)] s = ' '.join(l) return s diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py index e14c5e0..62f2671 100644 --- a/src/engine/SCons/SConf.py +++ b/src/engine/SCons/SConf.py @@ -25,6 +25,7 @@ Autoconf-like configuration support. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -118,7 +119,7 @@ def CreateConfigHBuilder(env): _stringConfigH) sconfigHBld = SCons.Builder.Builder(action=action) env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} ) - for k in list(_ac_config_hs.keys()): + for k in _ac_config_hs.keys(): env.SConfigHBuilder(k, env.Value(_ac_config_hs[k])) class SConfWarning(SCons.Warnings.Warning): @@ -175,19 +176,13 @@ class Streamer(object): """ def __init__(self, orig): self.orig = orig - try: - import StringIO - self.s = StringIO.StringIO() - except: - self.s = io.StringIO() + self.s = io.StringIO() def write(self, str): - try: - if self.orig: - self.orig.write(str) - self.s.write(str) - except: - print ('oops') + if self.orig: + self.orig.write(str) + self.s.write(str) + def writelines(self, lines): for l in lines: self.write(l + '\n') @@ -658,7 +653,7 @@ class SConfBase(object): """Adds all the tests given in the tests dictionary to this SConf instance """ - for name in list(tests.keys()): + for name in tests.keys(): self.AddTest(name, tests[name]) def _createDir( self, node ): diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index ba524fd..e604886 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -60,7 +60,7 @@ class SConfTestCase(unittest.TestCase): # We try to reset scons' state (including all global variables) import SCons.SConsign SCons.SConsign.write() # simulate normal scons-finish - for n in list(sys.modules.keys()): + for n in sys.modules.keys(): if n.split('.')[0] == 'SCons' and n[:12] != 'SCons.compat': m = sys.modules[n] if isinstance(m, ModuleType): diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index 5ce61be..ab8e297 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -26,6 +26,7 @@ Writing and reading information to the .sconsign file or 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -172,7 +173,7 @@ class Base(object): pass def merge(self): - for key, node in list(self.to_be_merged.items()): + for key, node in self.to_be_merged.items(): entry = node.get_stored_info() try: ninfo = entry.ninfo @@ -218,7 +219,7 @@ class DB(Base): except Exception as e: SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.tpath, e)) - for key, entry in list(self.entries.items()): + for key, entry in self.entries.items(): entry.convert_from_sconsign(dir, key) if mode == "r": @@ -245,7 +246,7 @@ class DB(Base): # the Repository; we only write to our own .sconsign file, # not to .sconsign files in Repositories. path = normcase(self.dir.path) - for key, entry in list(self.entries.items()): + for key, entry in self.entries.items(): entry.convert_to_sconsign() db[path] = pickle.dumps(self.entries, 1) @@ -333,7 +334,7 @@ class DirFile(Dir): fname = self.sconsign except IOError: return - for key, entry in list(self.entries.items()): + for key, entry in self.entries.items(): entry.convert_to_sconsign() pickle.dump(self.entries, file, 1) file.close() diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py index 5339ab2..1b55130 100644 --- a/src/engine/SCons/Scanner/Fortran.py +++ b/src/engine/SCons/Scanner/Fortran.py @@ -35,7 +35,6 @@ import SCons.Node.FS import SCons.Scanner import SCons.Util import SCons.Warnings -import collections class F90Scanner(SCons.Scanner.Classic): """ @@ -110,7 +109,7 @@ class F90Scanner(SCons.Scanner.Classic): # is actually found in a Repository or locally. nodes = [] source_dir = node.get_dir() - if isinstance(path, collections.Callable): + if callable(path): path = path() for dep in mods_and_includes: n, i = self.find_include(dep, source_dir, path) diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py index 1e0fea1..2cb1ed5 100644 --- a/src/engine/SCons/Scanner/LaTeX.py +++ b/src/engine/SCons/Scanner/LaTeX.py @@ -200,14 +200,14 @@ class LaTeX(SCons.Scanner.Base): """ def __init__(self, dictionary): self.dictionary = {} - for k,n in list(dictionary.items()): + for k,n in dictionary.items(): self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n), FindENVPathDirs(n) ) def __call__(self, env, dir=None, target=None, source=None, argument=None): di = {} - for k,(c,cENV) in list(self.dictionary.items()): + for k,(c,cENV) in self.dictionary.items(): di[k] = ( c(env, dir=None, target=None, source=None, argument=None) , cENV(env, dir=None, target=None, source=None, diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py index 6e2da21..49e93a5 100644 --- a/src/engine/SCons/Scanner/Prog.py +++ b/src/engine/SCons/Scanner/Prog.py @@ -27,7 +27,6 @@ import SCons.Node import SCons.Node.FS import SCons.Scanner import SCons.Util -import collections # global, set by --debug=findlibs print_find_libs = None @@ -77,7 +76,7 @@ def scan(node, env, libpath = ()): result = [] - if isinstance(libpath, collections.Callable): + if callable(libpath): libpath = libpath() find_file = SCons.Node.FS.find_file diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py index f564c91..250838d 100644 --- a/src/engine/SCons/Scanner/ProgTests.py +++ b/src/engine/SCons/Scanner/ProgTests.py @@ -230,7 +230,7 @@ def suite(): suite.addTest(ProgramScannerTestCase6()) suite.addTest(ProgramScannerTestCase7()) suite.addTest(ProgramScannerTestCase8()) - try: str + try: unicode except NameError: pass else: code = """if 1: diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py index 5a4639d..ee26922 100644 --- a/src/engine/SCons/Scanner/ScannerTests.py +++ b/src/engine/SCons/Scanner/ScannerTests.py @@ -569,7 +569,7 @@ class ClassicCPPTestCase(unittest.TestCase): assert n == 'path/bbb', n assert i == 'bbb', i - n, i = s.find_include(('<', 'ccc'), 'foo', ('path',)) + n, i = s.find_include(('<', u'ccc'), 'foo', ('path',)) assert n == 'path/ccc', n assert i == 'ccc', i diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index b947961..2375bc4 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -33,7 +33,6 @@ import re import SCons.Node.FS import SCons.Util -import collections class _Null(object): @@ -179,7 +178,7 @@ class Base(object): self.node_class = node_class self.node_factory = node_factory self.scan_check = scan_check - if isinstance(recursive, collections.Callable): + if callable(recursive): self.recurse_nodes = recursive elif recursive: self.recurse_nodes = self._recurse_all_nodes @@ -370,7 +369,7 @@ class Classic(Current): # is actually found in a Repository or locally. nodes = [] source_dir = node.get_dir() - if isinstance(path, collections.Callable): + if callable(path): path = path() for include in includes: n, i = self.find_include(include, source_dir, path) diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py index 87fe1cf..0b28f1a 100644 --- a/src/engine/SCons/Script/Interactive.py +++ b/src/engine/SCons/Script/Interactive.py @@ -19,6 +19,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -120,7 +121,7 @@ class SConsInteractiveCmd(cmd.Cmd): def __init__(self, **kw): cmd.Cmd.__init__(self) - for key, val in list(kw.items()): + for key, val in kw.items(): setattr(self, key, val) if sys.platform == 'win32': @@ -249,7 +250,7 @@ class SConsInteractiveCmd(cmd.Cmd): while n: n = walker.get_next() - for node in list(seen_nodes.keys()): + for node in seen_nodes.keys(): # Call node.clear() to clear most of the state node.clear() # node.clear() doesn't reset node.state, so call diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 9a52937..584960b 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,6 +10,8 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ +from __future__ import print_function + unsupported_python_version = (2, 3, 0) deprecated_python_version = (2, 7, 0) @@ -68,7 +70,6 @@ import SCons.Util import SCons.Warnings import SCons.Script.Interactive -import collections def fetch_win32_parallel_msg(): # A subsidiary function that exists solely to isolate this import @@ -105,7 +106,7 @@ class Progressor(object): self.interval = interval self.overwrite = overwrite - if isinstance(obj, collections.Callable): + if callable(obj): self.func = obj elif SCons.Util.is_List(obj): self.func = self.spinner @@ -716,7 +717,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): modname = os.path.basename(pathname)[:-len(sfx)] site_m = {"__file__": pathname, "__name__": modname, "__doc__": None} re_special = re.compile("__[^_]+__") - for k in list(m.__dict__.keys()): + for k in m.__dict__.keys(): if not re_special.match(k): site_m[k] = m.__dict__[k] diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py index 559db97..a97fc94 100644 --- a/src/engine/SCons/Script/SConsOptions.py +++ b/src/engine/SCons/Script/SConsOptions.py @@ -611,7 +611,7 @@ def Parser(version): deprecated_debug_options=deprecated_debug_options): if value in debug_options: parser.values.debug.append(value) - elif value in list(deprecated_debug_options.keys()): + elif value in deprecated_debug_options.keys(): parser.values.debug.append(value) try: parser.values.delayed_warnings diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 05cb6a6..b2dc4c1 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -26,7 +26,7 @@ files. # 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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -529,7 +529,7 @@ class SConsEnvironment(SCons.Environment.Base): return x ls = list(map(subst_element, ls)) subst_kw = {} - for key, val in list(kw.items()): + for key, val in kw.items(): if SCons.Util.is_String(val): val = self.subst(val) elif SCons.Util.is_List(val): diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py index cca9bbc..f1e80ac 100644 --- a/src/engine/SCons/Subst.py +++ b/src/engine/SCons/Subst.py @@ -472,7 +472,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars): return conv(substitute(l, lvars)) return list(map(func, s)) - elif isinstance(s, collections.Callable): + elif callable(s): try: s = s(target=lvars['TARGETS'], source=lvars['SOURCES'], @@ -681,7 +681,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv for a in s: self.substitute(a, lvars, 1) self.next_word() - elif isinstance(s, collections.Callable): + elif callable(s): try: s = s(target=lvars['TARGETS'], source=lvars['SOURCES'], diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py index da21020..7001899 100644 --- a/src/engine/SCons/SubstTests.py +++ b/src/engine/SCons/SubstTests.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 14ffe8c..86bff53 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -19,6 +19,7 @@ # 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 print_function __doc__ = """ Generic Taskmaster module for the SCons build engine. @@ -164,7 +165,7 @@ class Task(object): """ global print_prepare T = self.tm.trace - if T: T.write(self.trace_message('Task.prepare()', self.node)) + if T: T.write(self.trace_message(u'Task.prepare()', self.node)) # Now that it's the appropriate time, give the TaskMaster a # chance to raise any exceptions it encountered while preparing @@ -224,7 +225,7 @@ class Task(object): prepare(), executed() or failed(). """ T = self.tm.trace - if T: T.write(self.trace_message('Task.execute()', self.node)) + if T: T.write(self.trace_message(u'Task.execute()', self.node)) try: cached_targets = [] @@ -383,7 +384,7 @@ class Task(object): This is the default behavior for building only what's necessary. """ T = self.tm.trace - if T: T.write(self.trace_message('Task.make_ready_current()', + if T: T.write(self.trace_message(u'Task.make_ready_current()', self.node)) self.out_of_date = [] @@ -428,7 +429,7 @@ class Task(object): that can be put back on the candidates list. """ T = self.tm.trace - if T: T.write(self.trace_message('Task.postprocess()', self.node)) + if T: T.write(self.trace_message(u'Task.postprocess()', self.node)) # We may have built multiple targets, some of which may have # common parents waiting for this build. Count up how many @@ -445,7 +446,7 @@ class Task(object): # A node can only be in the pending_children set if it has # some waiting_parents. if t.waiting_parents: - if T: T.write(self.trace_message('Task.postprocess()', + if T: T.write(self.trace_message(u'Task.postprocess()', t, 'removing')) pending_children.discard(t) @@ -462,9 +463,9 @@ class Task(object): if p.ref_count == 0: self.tm.candidates.append(p) - for p, subtract in list(parents.items()): + for p, subtract in parents.items(): p.ref_count = p.ref_count - subtract - if T: T.write(self.trace_message('Task.postprocess()', + if T: T.write(self.trace_message(u'Task.postprocess()', p, 'adjusted parent ref count')) if p.ref_count == 0: @@ -744,12 +745,12 @@ class Taskmaster(object): self.ready_exc = None T = self.trace - if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) + if T: T.write(u'\n' + self.trace_message('Looking for a node to evaluate')) while True: node = self.next_candidate() if node is None: - if T: T.write(self.trace_message('No candidate anymore.') + '\n') + if T: T.write(self.trace_message('No candidate anymore.') + u'\n') return None node = node.disambiguate() @@ -772,7 +773,7 @@ class Taskmaster(object): else: S = None - if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node))) + if T: T.write(self.trace_message(u' Considering node %s and its children:' % self.trace_node(node))) if state == NODE_NO_STATE: # Mark this node as being on the execution stack: @@ -780,7 +781,7 @@ class Taskmaster(object): elif state > NODE_PENDING: # Skip this node if it has already been evaluated: if S: S.already_handled = S.already_handled + 1 - if T: T.write(self.trace_message(' already handled (executed)')) + if T: T.write(self.trace_message(u' already handled (executed)')) continue executor = node.get_executor() @@ -811,7 +812,7 @@ class Taskmaster(object): for child in chain(executor.get_all_prerequisites(), children): childstate = child.get_state() - if T: T.write(self.trace_message(' ' + self.trace_node(child))) + if T: T.write(self.trace_message(u' ' + self.trace_node(child))) if childstate == NODE_NO_STATE: children_not_visited.append(child) @@ -870,7 +871,7 @@ class Taskmaster(object): # count so we can be put back on the list for # re-evaluation when they've all finished. node.ref_count = node.ref_count + child.add_to_waiting_parents(node) - if T: T.write(self.trace_message(' adjusted ref count: %s, child %s' % + if T: T.write(self.trace_message(u' adjusted ref count: %s, child %s' % (self.trace_node(node), repr(str(child))))) if T: @@ -896,7 +897,7 @@ class Taskmaster(object): # The default when we've gotten through all of the checks above: # this node is ready to be built. if S: S.build = S.build + 1 - if T: T.write(self.trace_message('Evaluating %s\n' % + if T: T.write(self.trace_message(u'Evaluating %s\n' % self.trace_node(node))) # For debugging only: diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 0140278..278b690 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -20,7 +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 division __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py index c21128e..088c717 100644 --- a/src/engine/SCons/Tool/FortranCommon.py +++ b/src/engine/SCons/Tool/FortranCommon.py @@ -26,6 +26,7 @@ Stuff for processing Fortran, common to all fortran dialects. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -167,7 +168,7 @@ def add_fortran_to_env(env): except KeyError: FortranSuffixes = ['.f', '.for', '.ftn'] - #print "Adding %s to fortran suffixes" % FortranSuffixes + #print("Adding %s to fortran suffixes" % FortranSuffixes) try: FortranPPSuffixes = env['FORTRANPPFILESUFFIXES'] except KeyError: @@ -191,7 +192,7 @@ def add_f77_to_env(env): except KeyError: F77Suffixes = ['.f77'] - #print "Adding %s to f77 suffixes" % F77Suffixes + #print("Adding %s to f77 suffixes" % F77Suffixes) try: F77PPSuffixes = env['F77PPFILESUFFIXES'] except KeyError: diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index dcf69c8..e1b4820 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -113,7 +114,7 @@ def normalize_env(env, keys, force=False): Note: the environment is copied.""" normenv = {} if env: - for k in list(env.keys()): + for k in env.keys(): normenv[k] = copy.deepcopy(env[k]).encode('mbcs') for k in keys: @@ -217,7 +218,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): dkeep[key].append(p) for line in output.splitlines(): - for k,v in list(rdk.items()): + for k,v in rdk.items(): m = v.match(line) if m: add_env(m, k) diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py index 35b95d5..1a221ac 100644 --- a/src/engine/SCons/Tool/MSCommon/vc.py +++ b/src/engine/SCons/Tool/MSCommon/vc.py @@ -468,7 +468,7 @@ def msvc_setup_env(env): SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg) return None - for k, v in list(d.items()): + for k, v in d.items(): debug('vc.py:msvc_setup_env() env:%s -> %s'%(k,v)) env.PrependENVPath(k, v, delete_existing=True) diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py index 3219719..0a170fb 100644 --- a/src/engine/SCons/Tool/MSCommon/vs.py +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -536,7 +536,7 @@ def msvs_setup_env(env): env['ENV'] = save_ENV vars = parse_output(output, vars) - for k, v in list(vars.items()): + for k, v in vars.items(): env.PrependENVPath(k, v, delete_existing=1) def query_versions(): diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 1d5b504..517b987 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -34,6 +34,7 @@ tool definition. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -631,7 +632,7 @@ class ToolInitializer(object): so we no longer copy and re-bind them when the construction environment gets cloned. """ - for method in list(self.methods.values()): + for method in self.methods.values(): env.RemoveMethod(method) def apply_tools(self, env): diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py index ef03206..e7b8cfa 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py @@ -1,5 +1,6 @@ # docbook.py: extension module # $Id: docbook.py 8353 2009-03-17 16:57:50Z mzjn $ +from __future__ import print_function import sys import string diff --git a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py index 8554dd1..77ca0de 100644 --- a/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py +++ b/src/engine/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/xslt.py @@ -1,5 +1,6 @@ #!/usr/bin/python -u # $Id: xslt.py 8353 2009-03-17 16:57:50Z mzjn $ +from __future__ import print_function import sys import libxml2 diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py index 4236e81..0d75765 100644 --- a/src/engine/SCons/Tool/install.py +++ b/src/engine/SCons/Tool/install.py @@ -29,6 +29,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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py index 8b178a7..86c6e12 100644 --- a/src/engine/SCons/Tool/intelc.py +++ b/src/engine/SCons/Tool/intelc.py @@ -30,7 +30,7 @@ selection method. # 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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -438,14 +438,14 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0): 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in list(paths.keys()): + for p in paths.keys(): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_mac: paths={'INCLUDE' : 'include', 'LIB' : libdir, 'PATH' : bindir, 'LD_LIBRARY_PATH' : libdir} - for p in list(paths.keys()): + for p in paths.keys(): env.PrependENVPath(p, os.path.join(topdir, paths[p])) if is_windows: # env key reg valname default subdir of top diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py index 864a018..c7c6790 100644 --- a/src/engine/SCons/Tool/link.py +++ b/src/engine/SCons/Tool/link.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index b56d34a..f30c1d3 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -183,7 +184,7 @@ def prog_emitter(target, source, env): # MSVC 11 and above need the PCH object file to be added to the link line, # otherwise you get link error LNK2011. pchobj = SCons.Util.splitext(str(env['PCH']))[0] + '.obj' - # print "prog_emitter, version %s, appending pchobj %s"%(version_num, pchobj) + # print("prog_emitter, version %s, appending pchobj %s"%(version_num, pchobj)) if pchobj not in extrasources: extrasources.append(pchobj) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index 0879a28..370af9a 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -29,6 +29,7 @@ selection method. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -357,7 +358,7 @@ class _DSPGenerator(object): AddConfig(self, variants[i], buildtarget[i], outdir[i], runfile[i], cmdargs) self.platforms = [] - for key in list(self.configs.keys()): + for key in self.configs.keys(): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) @@ -480,7 +481,7 @@ class _GenerateV6DSP(_DSPGenerator): 'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe', 'Other Files': ''} - for kind in sorted(list(categories.keys()), key=lambda a: a.lower()): + for kind in sorted(categories.keys(), key=lambda a: a.lower()): if not self.sources[kind]: continue # skip empty groups @@ -744,7 +745,7 @@ class _GenerateV7DSP(_DSPGenerator): self.file.write(pdata + '-->\n') def printSources(self, hierarchy, commonprefix): - sorteditems = sorted(list(hierarchy.items()), key=lambda a: a[0].lower()) + sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -774,7 +775,7 @@ class _GenerateV7DSP(_DSPGenerator): self.file.write('\t\n') - cats = sorted([k for k in list(categories.keys()) if self.sources[k]], + cats = sorted([k for k in categories.keys() if self.sources[k]], key=lambda a: a.lower()) for kind in cats: if len(cats) > 1: @@ -1055,7 +1056,7 @@ class _GenerateV10DSP(_DSPGenerator): self.file.write(pdata + '-->\n') def printFilters(self, hierarchy, name): - sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) + sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) for key, value in sorteditems: if SCons.Util.is_Dict(value): @@ -1072,7 +1073,7 @@ class _GenerateV10DSP(_DSPGenerator): 'Resource Files': 'None', 'Other Files': 'None'} - sorteditems = sorted(list(hierarchy.items()), key = lambda a: a[0].lower()) + sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) # First folders, then files for key, value in sorteditems: @@ -1098,7 +1099,7 @@ class _GenerateV10DSP(_DSPGenerator): 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', 'Other Files': ''} - cats = sorted([k for k in list(categories.keys()) if self.sources[k]], + cats = sorted([k for k in categories.keys() if self.sources[k]], key = lambda a: a.lower()) # print vcxproj.filters file first @@ -1254,7 +1255,7 @@ class _GenerateV7DSW(_DSWGenerator): AddConfig(self, variant) self.platforms = [] - for key in list(self.configs.keys()): + for key in self.configs.keys(): platform = self.configs[key].platform if not platform in self.platforms: self.platforms.append(platform) diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 1466db6..1f5fb2b 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py index c3de2aa..345ec87 100644 --- a/src/engine/SCons/Tool/packaging/__init__.py +++ b/src/engine/SCons/Tool/packaging/__init__.py @@ -72,7 +72,7 @@ def Tag(env, target, source, *more_tags, **kw_tags): target=env.Flatten(target) for t in target: - for (k,v) in list(kw_tags.items()): + for (k,v) in kw_tags.items(): # all file tags have to start with PACKAGING_, so we can later # differentiate between "normal" object attributes and the # packaging attributes. As the user should not be bothered with diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py index ad27a62..6549445 100644 --- a/src/engine/SCons/Tool/packaging/ipk.py +++ b/src/engine/SCons/Tool/packaging/ipk.py @@ -169,7 +169,7 @@ Description: $X_IPK_DESCRIPTION # # close all opened files - for f in list(opened_files.values()): + for f in opened_files.values(): f.close() # call a user specified function diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py index 70fdc48..49c28ca 100644 --- a/src/engine/SCons/Tool/packaging/msi.py +++ b/src/engine/SCons/Tool/packaging/msi.py @@ -172,7 +172,7 @@ def generate_guids(root): # find all XMl nodes matching the key, retrieve their attribute, hash their # subtree, convert hash to string and add as a attribute to the xml node. - for (key,value) in list(needs_id.items()): + for (key,value) in needs_id.items(): node_list = root.getElementsByTagName(key) attribute = value for node in node_list: @@ -335,7 +335,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, } # fill in the default tags given above. - for k,v in [ (k, v) for (k,v) in list(h.items()) if not hasattr(file, k) ]: + for k,v in [ (k, v) for (k,v) in h.items() if not hasattr(file, k) ]: setattr( file, k, v ) File = factory.createElement( 'File' ) @@ -382,7 +382,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): Feature.attributes['Description'] = escape( SUMMARY ) Feature.attributes['Display'] = 'expand' - for (feature, files) in list(create_feature_dict(files).items()): + for (feature, files) in create_feature_dict(files).items(): SubFeature = factory.createElement('Feature') SubFeature.attributes['Level'] = '1' diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py index 4958065..a9e0fa2 100644 --- a/src/engine/SCons/Tool/packaging/rpm.py +++ b/src/engine/SCons/Tool/packaging/rpm.py @@ -277,7 +277,7 @@ def build_specfile_filesection(spec, files): for file in files: # build the tagset tags = {} - for k in list(supported_tags.keys()): + for k in supported_tags.keys(): try: tags[k]=getattr(file, k) except AttributeError: @@ -340,7 +340,7 @@ class SimpleTagCompiler(object): 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 = [t for t in list(values.items()) if strip_country_code(t[0]) == key] + 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 diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py index fdfdd26..723c39c 100644 --- a/src/engine/SCons/Tool/qt.py +++ b/src/engine/SCons/Tool/qt.py @@ -31,6 +31,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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/rpmutils.py b/src/engine/SCons/Tool/rpmutils.py index e96c54c..a444508 100644 --- a/src/engine/SCons/Tool/rpmutils.py +++ b/src/engine/SCons/Tool/rpmutils.py @@ -34,6 +34,7 @@ exact syntax. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py index febec35..dac98b7 100644 --- a/src/engine/SCons/Tool/tex.py +++ b/src/engine/SCons/Tool/tex.py @@ -31,6 +31,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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py index 4897113..693b62b 100644 --- a/src/engine/SCons/Tool/textfile.py +++ b/src/engine/SCons/Tool/textfile.py @@ -54,7 +54,6 @@ import re from SCons.Node import Node from SCons.Node.Python import Value from SCons.Util import is_String, is_Sequence, is_Dict -import collections def _do_subst(node, subs): """ @@ -97,7 +96,7 @@ def _action(target, source, env): raise SCons.Errors.UserError('SUBST_DICT must be dict or sequence') subs = [] for (k,v) in d: - if isinstance(v, collections.Callable): + if callable(v): v = v() if is_String(v): v = env.subst(v) diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index 489d4d7..f9375a2 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -23,6 +23,7 @@ Tool specific initialization of `xgettext` tool. # 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 six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -55,7 +56,7 @@ class _CmdRunner(object): proc = SCons.Action._subproc(env, command, **kw) self.out, self.err = proc.communicate() self.status = proc.wait() - if self.err: sys.stderr.write(str(self.err)) + if self.err: sys.stderr.write(u(self.err)) return self.status def strfunction(self, target, source, env): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 0c4daff..60e5c10 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -23,6 +23,7 @@ Various utility functions go here. # 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 six import PY2, PY3, u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -32,14 +33,22 @@ import copy import re import types -from collections import UserDict, UserList, UserString -import collections +try: + from collections import UserDict, UserList, UserString +except ImportError: # Python < 3 + from UserDict import UserDict + from UserList import UserList + from UserString import UserString # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. +try: + InstanceType = types.InstanceType +except AttributeError: # Python 3 + InstanceType = None MethodType = types.MethodType FunctionType = types.FunctionType -try: str +try: unicode except NameError: UnicodeType = None else: UnicodeType = str @@ -111,9 +120,12 @@ class NodeList(UserList): >>> someList.strip() [ 'foo', 'bar' ] """ - def __bool__(self): + def __nonzero__(self): return len(self.data) != 0 + def __bool__(self): + return self.__nonzero__() + def __str__(self): return ' '.join(map(str, self.data)) @@ -153,7 +165,7 @@ class DisplayEngine(object): return if append_newline: text = text + '\n' try: - sys.stdout.write(str(text)) + sys.stdout.write(u(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed @@ -239,7 +251,7 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): ' N = no clean\n' + ' H = no cache\n' + '\n') - sys.stdout.write(str(legend)) + sys.stdout.write(u(legend)) tags = ['['] tags.append(' E'[IDX(root.exists())]) @@ -264,10 +276,10 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}): children = child_func(root) if prune and rname in visited and children: - sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + '\n') + sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + u'\n') return - sys.stdout.write(''.join(tags + margins + ['+-', rname]) + '\n') + sys.stdout.write(''.join(tags + margins + ['+-', rname]) + u'\n') visited[rname] = 1 @@ -303,11 +315,17 @@ SequenceTypes = (list, tuple, UserList) # Note that profiling data shows a speed-up when comparing # explicitely with str and unicode instead of simply comparing # with basestring. (at least on Python 2.5.1) -StringTypes = (str, str, UserString) +try: + StringTypes = (str, unicode, UserString) +except NameError: + StringTypes = (str, UserString) # Empirically, it is faster to check explicitely for str and # unicode than for basestring. -BaseStringTypes = (str, str) +try: + BaseStringTypes = (str, unicode) +except NameError: + BaseStringTypes = (str) def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes): return isinstance(obj, DictTypes) @@ -440,7 +458,7 @@ _semi_deepcopy_dispatch = d = {} def semi_deepcopy_dict(x, exclude = [] ): copy = {} - for key, val in list(x.items()): + for key, val in x.items(): # The regular Python copy.deepcopy() also deepcopies the key, # as follows: # @@ -465,7 +483,7 @@ def semi_deepcopy(x): if copier: return copier(x) else: - if hasattr(x, '__semi_deepcopy__') and isinstance(x.__semi_deepcopy__, collections.Callable): + if hasattr(x, '__semi_deepcopy__') and callable(x.__semi_deepcopy__): return x.__semi_deepcopy__() elif isinstance(x, UserDict): return x.__class__(semi_deepcopy_dict(x)) @@ -979,7 +997,7 @@ class OrderedDict(UserDict): if key not in self._keys: self._keys.append(key) def update(self, dict): - for (key, val) in list(dict.items()): + for (key, val) in dict.items(): self.__setitem__(key, val) def values(self): @@ -1001,7 +1019,7 @@ class Selector(OrderedDict): # Try to perform Environment substitution on the keys of # the dictionary before giving up. s_dict = {} - for (k,v) in list(self.items()): + for (k,v) in self.items(): if k is not None: s_k = env.subst(k) if s_k in s_dict: @@ -1346,8 +1364,9 @@ def make_path_relative(path): def AddMethod(obj, function, name=None): """ - Adds either a bound method to an instance or an unbound method to - a class. If name is ommited the name of the specified function + Adds either a bound method to an instance or the function itself + (or an unbound method in Python 2) to a class. + If name is ommited the name of the specified function is used by default. Example: a = A() @@ -1366,9 +1385,15 @@ def AddMethod(obj, function, name=None): if hasattr(obj, '__class__') and obj.__class__ is not type: # "obj" is an instance, so it gets a bound method. - setattr(obj, name, MethodType(function, obj, obj.__class__)) + if PY3: + method = MethodType(function, obj) + else: + method = MethodType(function, obj, obj.__class__) + setattr(obj, name, method) else: # "obj" is a class, so it gets an unbound method. + if PY2: + function = MethodType(function, None, obj) setattr(obj, name, function) def RenameFunction(function, name): @@ -1461,6 +1486,8 @@ class Null(object): return self def __repr__(self): return "Null(0x%08X)" % id(self) + def __nonzero__(self): + return False def __bool__(self): return False def __getattr__(self, name): diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index a30404c..5666f36 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.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 six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -285,16 +286,16 @@ class UtilTestCase(unittest.TestCase): assert to_String(s2) == 'foo', s2 if HasUnicode: - s3=UserString(str('bar')) + s3=UserString(unicode('bar')) assert to_String(s3) == s3, s3 - assert to_String(s3) == str('bar'), s3 - assert isinstance(to_String(s3), str), \ + assert to_String(s3) == unicode('bar'), s3 + assert isinstance(to_String(s3), unicode), \ type(to_String(s3)) if HasUnicode: - s4 = str('baz') - assert to_String(s4) == str('baz'), to_String(s4) - assert isinstance(to_String(s4), str), \ + s4 = unicode('baz') + assert to_String(s4) == unicode('baz'), to_String(s4) + assert isinstance(to_String(s4), unicode), \ type(to_String(s4)) def test_WhereIs(self): @@ -681,7 +682,7 @@ bling fobj = io.StringIO(content) except TypeError: # Python 2.7 and beyond require unicode strings. - fobj = io.StringIO(str(content)) + fobj = io.StringIO(u(content)) lines = LogicalLines(fobj).readlines() assert lines == [ @@ -696,7 +697,7 @@ bling s1 = silent_intern("spam") # Python 3.x does not have a unicode() global function if sys.version[0] == '2': - s2 = silent_intern(str("unicode spam")) + s2 = silent_intern(unicode("unicode spam")) s3 = silent_intern(42) s4 = silent_intern("spam") assert id(s1) == id(s4) diff --git a/src/engine/SCons/Variables/EnumVariableTests.py b/src/engine/SCons/Variables/EnumVariableTests.py index 4feb712..f4b600d 100644 --- a/src/engine/SCons/Variables/EnumVariableTests.py +++ b/src/engine/SCons/Variables/EnumVariableTests.py @@ -122,7 +122,7 @@ class EnumVariableTestCase(unittest.TestCase): 'C' : ['C', 'three', 'three'], } - for k, l in list(table.items()): + for k, l in table.items(): x = o0.converter(k) assert x == l[0], "o0 got %s, expected %s" % (x, l[0]) x = o1.converter(k) @@ -186,7 +186,7 @@ class EnumVariableTestCase(unittest.TestCase): 'no_v' : [invalid, invalid, invalid], } - for v, l in list(table.items()): + for v, l in table.items(): l[0](o0, v) l[1](o1, v) l[2](o2, v) diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py index 8d15b8d..1c8d834 100644 --- a/src/engine/SCons/Variables/__init__.py +++ b/src/engine/SCons/Variables/__init__.py @@ -180,7 +180,7 @@ class Variables(object): if args is None: args = self.args - for arg, value in list(args.items()): + for arg, value in args.items(): added = False for option in self.options: if arg in list(option.aliases) + [ option.key ]: diff --git a/src/engine/SCons/compat/_scons_subprocess.py b/src/engine/SCons/compat/_scons_subprocess.py index 72581f7..e4ac777 100644 --- a/src/engine/SCons/compat/_scons_subprocess.py +++ b/src/engine/SCons/compat/_scons_subprocess.py @@ -351,6 +351,8 @@ except that: """ +from __future__ import print_function +from six import integer_types import sys mswindows = (sys.platform == "win32") @@ -444,15 +446,15 @@ else: def is_int(obj): return isinstance(obj, int) def is_int_or_long(obj): - return isinstance(obj, int) + return isinstance(obj, integer_types) try: - str + types.StringTypes except AttributeError: try: - str = (str, str) + types.StringTypes = (str, unicode) except NameError: - str = (str,) + types.StringTypes = (str,) def is_string(obj): return isinstance(obj, str) @@ -785,7 +787,7 @@ class Popen(object): errread, errwrite): """Execute program (MS Windows version)""" - if not isinstance(args, str): + if not isinstance(args, types.StringTypes): args = list2cmdline(args) # Process startup details diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py index 4cc771b..0ba10f5 100644 --- a/src/engine/SCons/cpp.py +++ b/src/engine/SCons/cpp.py @@ -31,7 +31,6 @@ import SCons.compat import os import re -import collections # # First "subsystem" of regular expressions that we set up: @@ -73,7 +72,7 @@ cpp_lines_dict = { # the corresponding compiled regular expression that fetches the arguments # we care about. Table = {} -for op_list, expr in list(cpp_lines_dict.items()): +for op_list, expr in cpp_lines_dict.items(): e = re.compile(expr) for op in op_list: Table[op] = e @@ -88,7 +87,7 @@ del op_list override = { 'if' : 'if(?!def)', } -l = [override.get(x, x) for x in list(Table.keys())] +l = [override.get(x, x) for x in Table.keys()] # Turn the list of expressions into one big honkin' regular expression @@ -131,7 +130,7 @@ CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)] # re module, as late as version 2.2.2, empirically matches the # "!" in "!=" first, instead of finding the longest match. # What's up with that? -l = sorted(list(CPP_to_Python_Ops_Dict.keys()), key=lambda a: len(a), reverse=True) +l = sorted(CPP_to_Python_Ops_Dict.keys(), key=lambda a: len(a), reverse=True) # Turn the list of keys into one regular expression that will allow us # to substitute all of the operators at once. @@ -267,7 +266,7 @@ class PreProcessor(object): d = { 'scons_current_file' : self.scons_current_file } - for op in list(Table.keys()): + for op in Table.keys(): d[op] = getattr(self, 'do_' + op) self.default_table = d @@ -553,7 +552,7 @@ class PreProcessor(object): except KeyError: m = function_name.search(s) s = self.cpp_namespace[m.group(1)] - if isinstance(s, collections.Callable): + if callable(s): args = function_arg_separator.split(m.group(2)) s = s(*args) if not s: diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 5566e53..2f2025b 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -27,7 +27,7 @@ import atexit import sys import unittest -from . import cpp +import cpp diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 4b02239..dbbd65d 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -1,5 +1,6 @@ # dblite.py module contributed by Ralf W. Grosse-Kunstleve. # Extended for Unicode by Steven Knight. +from __future__ import print_function import SCons.compat @@ -16,14 +17,19 @@ ignore_corrupt_dbfiles = 0 def corruption_warning(filename): print("Warning: Discarding corrupt database:", filename) -def is_string(s): - return isinstance(s, str) +try: unicode +except NameError: + def is_string(s): + return isinstance(s, str) +else: + def is_string(s): + return type(s) in (str, unicode) def is_bytes(s): return isinstance (s, bytes) try: - str('a') + unicode('a') except NameError: - def str(s): return s + def unicode(s): return s dblite_suffix = '.dblite' if bytes is not str: @@ -177,23 +183,23 @@ def _exercise(): assert len(db) == 0 db["foo"] = "bar" assert db["foo"] == "bar" - db[str("ufoo")] = str("ubar") - assert db[str("ufoo")] == str("ubar") + db[unicode("ufoo")] = unicode("ubar") + assert db[unicode("ufoo")] == unicode("ubar") db.sync() db = open("tmp", "c") assert len(db) == 2, len(db) assert db["foo"] == "bar" db["bar"] = "foo" assert db["bar"] == "foo" - db[str("ubar")] = str("ufoo") - assert db[str("ubar")] == str("ufoo") + db[unicode("ubar")] = unicode("ufoo") + assert db[unicode("ubar")] == unicode("ufoo") db.sync() db = open("tmp", "r") assert len(db) == 4, len(db) assert db["foo"] == "bar" assert db["bar"] == "foo" - assert db[str("ufoo")] == str("ubar") - assert db[str("ubar")] == str("ufoo") + assert db[unicode("ufoo")] == unicode("ubar") + assert db[unicode("ubar")] == unicode("ufoo") try: db.sync() except IOError as e: diff --git a/src/script/scons-time.py b/src/script/scons-time.py index 4296192..9737dfe 100644 --- a/src/script/scons-time.py +++ b/src/script/scons-time.py @@ -29,8 +29,7 @@ # 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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -42,7 +41,6 @@ import shutil import sys import tempfile import time -import collections try: sorted @@ -456,7 +454,7 @@ class SConsTimer(object): Each message is prepended with a standard prefix of our name plus the time. """ - if isinstance(msg, collections.Callable): + if callable(msg): msg = msg(*args) else: msg = msg % args @@ -475,7 +473,7 @@ class SConsTimer(object): The action is called if it's a callable Python function, and otherwise passed to os.system(). """ - if isinstance(action, collections.Callable): + if callable(action): action(*args) else: os.system(action % args) @@ -697,7 +695,7 @@ class SConsTimer(object): sys.stderr.write('%s Cannot use the "func" subcommand.\n' % self.name_spaces) sys.exit(1) statistics = pstats.Stats(file).stats - matches = [ e for e in list(statistics.items()) if e[0][2] == function ] + matches = [ e for e in statistics.items() if e[0][2] == function ] r = matches[0] return r[0][0], r[0][1], r[0][2], r[1][3] @@ -1467,7 +1465,7 @@ class SConsTimer(object): elif o in ('--title',): self.title = a elif o in ('--which',): - if not a in list(self.time_strings.keys()): + if not a in self.time_strings.keys(): sys.stderr.write('%s: time: Unrecognized timer "%s".\n' % (self.name, a)) sys.stderr.write('%s Type "%s help time" for help.\n' % (self.name_spaces, self.name)) sys.exit(1) diff --git a/src/script/sconsign.py b/src/script/sconsign.py index 323d1bf..e99a741 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -22,6 +22,9 @@ # 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 print_function + +from six import PY2, PY3 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -171,6 +174,8 @@ sys.path = libs + sys.path import SCons.compat # so pickle will import cPickle instead +if PY2: + import whichdb import dbm import time import pickle @@ -189,7 +194,10 @@ def my_whichdb(filename): pass return _orig_whichdb(filename) -_orig_whichdb = dbm.whichdb +if PY3: + _orig_whichdb = dbm.whichdb +else: + _orig_whichdb = whichdb.whichdb dbm.whichdb = my_whichdb def my_import(mname): diff --git a/src/test_files.py b/src/test_files.py index d71329b..1eee11d 100644 --- a/src/test_files.py +++ b/src/test_files.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -77,7 +78,7 @@ check = { missing = [] no_result = [] -for directory, check_list in list(check.items()): +for directory, check_list in check.items(): if os.path.exists(directory): for c in check_list: f = os.path.join(directory, c) diff --git a/src/test_interrupts.py b/src/test_interrupts.py index 1e027a1..de3a0db 100644 --- a/src/test_interrupts.py +++ b/src/test_interrupts.py @@ -102,7 +102,7 @@ for f in files: indent_list.append( (line_num, match.group('try_or_except') ) ) try_except_lines[match.group('indent')] = indent_list uncaught_this_file = [] - for indent in list(try_except_lines.keys()): + for indent in try_except_lines.keys(): exc_keyboardint_seen = 0 exc_all_seen = 0 for (l,statement) in try_except_lines[indent] + [(-1,indent + 'try')]: diff --git a/src/test_pychecker.py b/src/test_pychecker.py index 24aa966..54d78fb 100644 --- a/src/test_pychecker.py +++ b/src/test_pychecker.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/test_setup.py b/src/test_setup.py index 731fbe7..edf0de5 100644 --- a/src/test_setup.py +++ b/src/test_setup.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/test_strings.py b/src/test_strings.py index b57c714..297d59d 100644 --- a/src/test_strings.py +++ b/src/test_strings.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/AS/nasm.py b/test/AS/nasm.py index 551a5ab..be7db3e 100644 --- a/test/AS/nasm.py +++ b/test/AS/nasm.py @@ -69,7 +69,7 @@ else: # anyway...). nasm_format = 'elf' format_map = {} -for k, v in list(format_map.items()): +for k, v in format_map.items(): if sys.platform.find(k) != -1: nasm_format = v break diff --git a/test/Actions/unicode-signature.py b/test/Actions/unicode-signature.py index 0ba50c3..d91bfa8 100644 --- a/test/Actions/unicode-signature.py +++ b/test/Actions/unicode-signature.py @@ -35,12 +35,12 @@ import TestSCons test = TestSCons.TestSCons() -try: - str -except NameError: - import sys - msg = "Unicode not supported by Python version %s; skipping test\n" - test.skip_test(msg % sys.version[:3]) +## try: +## unicode +## except NameError: +## import sys +## msg = "Unicode not supported by Python version %s; skipping test\n" +## test.skip_test(msg % sys.version[:3]) test.write('SConstruct', """ fnode = File(u'foo.txt') diff --git a/test/AddOption/help.py b/test/AddOption/help.py index a3fd7be..7b886cb 100644 --- a/test/AddOption/help.py +++ b/test/AddOption/help.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Configure/ConfigureDryRunError.py b/test/Configure/ConfigureDryRunError.py index a8c6309..fa85042 100644 --- a/test/Configure/ConfigureDryRunError.py +++ b/test/Configure/ConfigureDryRunError.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Configure/config-h.py b/test/Configure/config-h.py index 6c70c9c..ed95055 100644 --- a/test/Configure/config-h.py +++ b/test/Configure/config-h.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Configure/implicit-cache.py b/test/Configure/implicit-cache.py index 059fd4c..1a9ff34 100644 --- a/test/Configure/implicit-cache.py +++ b/test/Configure/implicit-cache.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py b/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py index 9a36eac..2959736 100644 --- a/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py +++ b/test/Deprecated/SourceCode/BitKeeper/BitKeeper.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Deprecated/SourceCode/Subversion.py b/test/Deprecated/SourceCode/Subversion.py index ac3eb57..7d45a8c 100644 --- a/test/Deprecated/SourceCode/Subversion.py +++ b/test/Deprecated/SourceCode/Subversion.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/GetBuildFailures/parallel.py b/test/GetBuildFailures/parallel.py index 101c2e2..e746d53 100644 --- a/test/GetBuildFailures/parallel.py +++ b/test/GetBuildFailures/parallel.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 print_function """ Verify that a failed build action with -j works as expected. diff --git a/test/Glob/glob-libpath.py b/test/Glob/glob-libpath.py index 6ee06e6..0878090 100644 --- a/test/Glob/glob-libpath.py +++ b/test/Glob/glob-libpath.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Interactive/version.py b/test/Interactive/version.py index 295b9d3..34f8825 100644 --- a/test/Interactive/version.py +++ b/test/Interactive/version.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ diff --git a/test/Java/multi-step.py b/test/Java/multi-step.py index add4208..44ebd31 100644 --- a/test/Java/multi-step.py +++ b/test/Java/multi-step.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index 6f5c8d6..a70ed67 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index b7172fc..008397a 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -147,7 +147,7 @@ test.must_exist(['work1', 'mmmmocFromH.cxx'], ['work1', 'mmmanother_ui_file.cxx']) def _flagTest(test,fileToContentsStart): - for f,c in list(fileToContentsStart.items()): + for f,c in fileToContentsStart.items(): if test.read(test.workpath('work1', f)).find(c) != 0: return 1 return 0 diff --git a/test/QT/copied-env.py b/test/QT/copied-env.py index 59a344d..3989143 100644 --- a/test/QT/copied-env.py +++ b/test/QT/copied-env.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/QT/warnings.py b/test/QT/warnings.py index 5e680f6..a1cf221 100644 --- a/test/QT/warnings.py +++ b/test/QT/warnings.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Scanner/unicode.py b/test/Scanner/unicode.py index 7a72804..2737f7d 100644 --- a/test/Scanner/unicode.py +++ b/test/Scanner/unicode.py @@ -35,12 +35,12 @@ _python_ = TestSCons._python_ test = TestSCons.TestSCons() -try: - str -except NameError: - import sys - msg = "Unicode not supported by Python version %s; skipping test\n" - test.skip_test(msg % sys.version[:3]) +## try: +## unicode +## except NameError: +## import sys +## msg = "Unicode not supported by Python version %s; skipping test\n" +## test.skip_test(msg % sys.version[:3]) import codecs @@ -102,28 +102,28 @@ include utf16be.k foo.k 1 line 4 """) -contents = str("""\ +contents = (u"""\ ascii.k 1 line 1 include ascii.inc ascii.k 1 line 3 """) test.write('ascii.k', contents.encode('ascii')) -contents = str("""\ +contents = (u"""\ utf8.k 1 line 1 include utf8.inc utf8.k 1 line 3 """) test.write('utf8.k', codecs.BOM_UTF8 + contents.encode('utf-8')) -contents = str("""\ +contents = (u"""\ utf16le.k 1 line 1 include utf16le.inc utf16le.k 1 line 3 """) test.write('utf16le.k', codecs.BOM_UTF16_LE + contents.encode('utf-16-le')) -contents = str("""\ +contents = (u"""\ utf16be.k 1 line 1 include utf16be.inc utf16be.k 1 line 3 diff --git a/test/TEX/TEX.py b/test/TEX/TEX.py index 863144d..b749690 100644 --- a/test/TEX/TEX.py +++ b/test/TEX/TEX.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Value.py b/test/Value.py index 025c6de..7abe758 100644 --- a/test/Value.py +++ b/test/Value.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/Win32/bad-drive.py b/test/Win32/bad-drive.py index ff98b4e..4d0d6e9 100644 --- a/test/Win32/bad-drive.py +++ b/test/Win32/bad-drive.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 print_function """ This test verifies (on Windows systems) that we fail gracefully and diff --git a/test/Win32/default-drive.py b/test/Win32/default-drive.py index 2bc14b1..31253e4 100644 --- a/test/Win32/default-drive.py +++ b/test/Win32/default-drive.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 print_function """ This test verifies (on Windows systems) that specifying an diff --git a/test/gnutools.py b/test/gnutools.py index f79efe4..b0ebc1c 100644 --- a/test/gnutools.py +++ b/test/gnutools.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/import.py b/test/import.py index fb8a28c..d1e1ecf 100644 --- a/test/import.py +++ b/test/import.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option--random.py b/test/option--random.py index 59592cb..357cf2e 100644 --- a/test/option--random.py +++ b/test/option--random.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option-v.py b/test/option-v.py index 8985db0..43245da 100644 --- a/test/option-v.py +++ b/test/option-v.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option/debug-count.py b/test/option/debug-count.py index 076d7fa..ce79086 100644 --- a/test/option/debug-count.py +++ b/test/option/debug-count.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option/debug-time.py b/test/option/debug-time.py index 7448e1c..7dd17fe 100644 --- a/test/option/debug-time.py +++ b/test/option/debug-time.py @@ -20,7 +20,7 @@ # 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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option/help-options.py b/test/option/help-options.py index 1b23cb3..e14eff2 100644 --- a/test/option/help-options.py +++ b/test/option/help-options.py @@ -20,6 +20,7 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/option/profile.py b/test/option/profile.py index 513da47..97f84db 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -21,6 +21,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 six import u + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import sys @@ -36,7 +38,7 @@ else: # when we drop support for Python 2.6. class StringIO(_StringIO): def write(self, s): - _StringIO.write(self, str(s)) + _StringIO.write(self, u(s)) import TestSCons diff --git a/test/site_scons/sysdirs.py b/test/site_scons/sysdirs.py index d05f6a4..87f448d 100644 --- a/test/site_scons/sysdirs.py +++ b/test/site_scons/sysdirs.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/test/update-release-info/update-release-info.py b/test/update-release-info/update-release-info.py index 0db65ba..d3125c7 100644 --- a/test/update-release-info/update-release-info.py +++ b/test/update-release-info/update-release-info.py @@ -201,7 +201,7 @@ RELEASE 2.0.0.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE """, mode = 'r') -years = ', '.join(map(str, list(range(2001, this_year + 1)))) +years = ', '.join(map(str, range(2001, this_year + 1))) test.must_match(SConstruct, """ month_year = 'MONTH YEAR' copyright_years = %s diff --git a/timings/ElectricCloud/TimeSCons-run.py b/timings/ElectricCloud/TimeSCons-run.py index fbe0028..130d916 100644 --- a/timings/ElectricCloud/TimeSCons-run.py +++ b/timings/ElectricCloud/TimeSCons-run.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 print_function """ This configuration comes from the following blog article: diff --git a/www/gen_sched_table.py b/www/gen_sched_table.py index 9ac8acd..85b1b81 100755 --- a/www/gen_sched_table.py +++ b/www/gen_sched_table.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from __future__ import print_function import sys import datetime -- cgit v0.12 From cbd2254037664fdfe6ba1bf6678896fbd51698a9 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 09:39:26 +0000 Subject: QMTest: open() in text mode. Add ()s to prints on writing test scripts from str. --- QMTest/SConscript | 4 ++-- QMTest/TestCmd.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/QMTest/SConscript b/QMTest/SConscript index 33fe903..5469d29 100644 --- a/QMTest/SConscript +++ b/QMTest/SConscript @@ -44,12 +44,12 @@ files = [ def copy(target, source, env): t = str(target[0]) s = str(source[0]) - c = open(s, 'rb').read() + c = open(s, 'r').read() # 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 = c.replace('__' + 'VERSION' + '__', env['VERSION']) - open(t, 'wb').write(c) + open(t, 'w').write(c) for file in files: # Guarantee that real copies of these files always exist in diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 488d940..c075cd3 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -287,6 +287,8 @@ version. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. from __future__ import division, print_function +from six import PY3 + __author__ = "Steven Knight " __revision__ = "TestCmd.py 1.3.D001 2010/06/03 12:58:27 knight" __version__ = "1.3" @@ -1705,7 +1707,7 @@ class TestCmd(object): do_chmod(os.path.join(dirpath, name)) do_chmod(top) - def write(self, file, content, mode = 'wb'): + def write(self, file, content, mode = 'w'): """Writes the specified content text (second argument) to the specified file name (first argument). The file name may be a list, in which case the elements are concatenated with the @@ -1714,6 +1716,8 @@ class TestCmd(object): exist. The I/O mode for the file may be specified; it must begin with a 'w'. The default is 'wb' (binary write). """ + if PY3: + content = re.sub('print (.+)', 'print(\1)', content) file = self.canonicalize(file) if mode[0] != 'w': raise ValueError("mode must begin with 'w'") -- cgit v0.12 From 724d115835ddfe49096b9ad695a3b75cb612745a Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 09:40:41 +0000 Subject: SConstruct: open() in text mode. Fixed octal literals. --- SConstruct | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/SConstruct b/SConstruct index 1a0aef0..09eb739 100644 --- a/SConstruct +++ b/SConstruct @@ -70,7 +70,7 @@ def whereis(file): st = os.stat(f_ext) except: continue - if stat.S_IMODE(st[stat.ST_MODE]) & 0111: + if stat.S_IMODE(st[stat.ST_MODE]) & 0o111: return f_ext return None @@ -372,7 +372,7 @@ def SCons_revision(target, source, env): """ t = str(target[0]) s = source[0].rstr() - contents = open(s, 'rb').read() + contents = open(s, 'r').read() # Note: We construct the __*__ substitution strings here # so that they don't get replaced when this file gets # copied into the tree for packaging. @@ -386,7 +386,7 @@ def SCons_revision(target, source, env): contents = contents.replace('__REVISION' + '__', env['REVISION']) contents = contents.replace('__VERSION' + '__', env['VERSION']) contents = contents.replace('__NULL' + '__', '') - open(t, 'wb').write(contents) + open(t, 'w').write(contents) os.chmod(t, os.stat(s)[0]) revaction = SCons_revision @@ -851,7 +851,7 @@ for p in [ scons ]: dist_distutils_targets = env.Install('$DISTDIR', distutils_targets) Local(dist_distutils_targets) - AddPostAction(dist_distutils_targets, Chmod(dist_distutils_targets, 0644)) + AddPostAction(dist_distutils_targets, Chmod(dist_distutils_targets, 0o644)) if not gzip: print("gzip not found in %s; skipping .tar.gz package for %s." % (os.environ['PATH'], pkg)) @@ -866,8 +866,8 @@ for p in [ scons ]: dist_tar_gz = env.Install('$DISTDIR', tar_gz) dist_platform_tar_gz = env.Install('$DISTDIR', platform_tar_gz) Local(dist_tar_gz, dist_platform_tar_gz) - AddPostAction(dist_tar_gz, Chmod(dist_tar_gz, 0644)) - AddPostAction(dist_platform_tar_gz, Chmod(dist_platform_tar_gz, 0644)) + AddPostAction(dist_tar_gz, Chmod(dist_tar_gz, 0o644)) + AddPostAction(dist_platform_tar_gz, Chmod(dist_platform_tar_gz, 0o644)) # # Unpack the tar.gz archive created by the distutils into @@ -941,8 +941,8 @@ for p in [ scons ]: dist_zip = env.Install('$DISTDIR', zip) dist_platform_zip = env.Install('$DISTDIR', platform_zip) Local(dist_zip, dist_platform_zip) - AddPostAction(dist_zip, Chmod(dist_zip, 0644)) - AddPostAction(dist_platform_zip, Chmod(dist_platform_zip, 0644)) + AddPostAction(dist_zip, Chmod(dist_zip, 0o644)) + AddPostAction(dist_platform_zip, Chmod(dist_platform_zip, 0o644)) # # Unpack the zip archive created by the distutils into @@ -1029,8 +1029,8 @@ for p in [ scons ]: dist_noarch_rpm = env.Install('$DISTDIR', noarch_rpm) dist_src_rpm = env.Install('$DISTDIR', src_rpm) Local(dist_noarch_rpm, dist_src_rpm) - AddPostAction(dist_noarch_rpm, Chmod(dist_noarch_rpm, 0644)) - AddPostAction(dist_src_rpm, Chmod(dist_src_rpm, 0644)) + AddPostAction(dist_noarch_rpm, Chmod(dist_noarch_rpm, 0o644)) + AddPostAction(dist_src_rpm, Chmod(dist_src_rpm, 0o644)) dfiles = [os.path.join(test_rpm_dir, 'usr', x) for x in dst_files] env.Command(dfiles, @@ -1097,8 +1097,8 @@ for p in [ scons ]: dist_local_tar_gz = os.path.join("$DISTDIR/%s.tar.gz" % s_l_v) dist_local_zip = os.path.join("$DISTDIR/%s.zip" % s_l_v) - AddPostAction(dist_local_tar_gz, Chmod(dist_local_tar_gz, 0644)) - AddPostAction(dist_local_zip, Chmod(dist_local_zip, 0644)) + AddPostAction(dist_local_tar_gz, Chmod(dist_local_tar_gz, 0o644)) + AddPostAction(dist_local_zip, Chmod(dist_local_zip, 0o644)) commands = [ Delete(build_dir_local), -- cgit v0.12 From b5d204ffae80f78083c34b0ba4c105791d57c084 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 09:43:46 +0000 Subject: copy_func: return 0 instead of return shutil.* --- src/engine/SCons/Defaults.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 491b9f2..92f2344 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -183,11 +183,11 @@ def copy_func(dest, src): if SCons.Util.is_List(src) and os.path.isdir(dest): for file in src: shutil.copy2(file, dest) - return 0 elif os.path.isfile(src): - return shutil.copy2(src, dest) + shutil.copy2(src, dest) else: - return shutil.copytree(src, dest, 1) + shutil.copytree(src, dest, 1) + return 0 Copy = ActionFactory(copy_func, lambda dest, src: 'Copy("%s", "%s")' % (dest, src), -- cgit v0.12 From 808610957042c630d19c7f7b0fd9b87b81f9de2e Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 09:51:19 +0000 Subject: Environment.py: __cmp__ to __eq__. list(*.keys()) for item deletion loops. --- src/engine/SCons/Environment.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index b5bd620..7a369a9 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -127,7 +127,7 @@ future_reserved_construction_var_names = [ def copy_non_reserved_keywords(dict): result = semi_deepcopy(dict) - for k in result.keys(): + for k in list(result.keys()): if k in reserved_construction_var_names: msg = "Ignoring attempt to set reserved variable `$%s'" SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) @@ -398,8 +398,8 @@ class SubstitutionEnvironment(object): # gotten better than dict.has_key() in Python 2.5.) self._special_set_keys = list(self._special_set.keys()) - def __cmp__(self, other): - return cmp(self._dict, other._dict) + def __eq__(self, other): + return self._dict == other._dict def __delitem__(self, key): special = self._special_del.get(key) @@ -1768,7 +1768,7 @@ class Base(SubstitutionEnvironment): return os.path.join(dir, new_prefix+name+new_suffix) def SetDefault(self, **kw): - for k in kw.keys(): + for k in list(kw.keys()): if k in self._dict: del kw[k] self.Replace(**kw) -- cgit v0.12 From d1c2f4dbdbf5ca3f5c1f8bf6da45c09d82046683 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 13:05:24 +0000 Subject: doc/SConscript: Fixed octal literal. --- doc/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/SConscript b/doc/SConscript index c6b8f74..a1feba9 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -414,7 +414,7 @@ if tar_deps: 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)) + AddPostAction(dist_doc_tar_gz, Chmod(dist_doc_tar_gz, 0o644)) Local(t) Alias('doc', t) else: -- cgit v0.12 From fd24c4ea622e271936c2df2a5efa484cd351bd9c Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 13:07:07 +0000 Subject: Use exec() with compile() to preserve script name. --- src/engine/SCons/Script/SConscript.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index b2dc4c1..3ee9464 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -26,7 +26,6 @@ files. # 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 division, print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -257,7 +256,8 @@ def _SConscript(fs, *files, **kw): pass try: try: - exec(_file_.read(), call_stack[-1].globals) + exec(compile(_file_.read(), _file_.name, 'exec'), + call_stack[-1].globals) except SConscriptReturn: pass finally: -- cgit v0.12 From 87b458d186fe0553b054b8eeb7d57c80e0a54f21 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 15:21:40 +0000 Subject: More __cmp__ to __eq__ (and __lt__). Resolved some UnboundLocalErrors after except. --- bin/SConsDoc.py | 6 ++++-- bin/scons-proc.py | 11 ++++++++--- src/engine/SCons/Action.py | 4 ++-- src/engine/SCons/Builder.py | 11 +++++++---- src/engine/SCons/BuilderTests.py | 22 ++++++++++++++-------- src/engine/SCons/EnvironmentTests.py | 8 ++++---- src/engine/SCons/Memoize.py | 6 +++--- src/engine/SCons/Scanner/ScannerTests.py | 2 +- src/engine/SCons/Scanner/__init__.py | 6 +++--- src/engine/SCons/Util.py | 6 +++--- test/Scanner/generated.py | 4 ++-- 11 files changed, 51 insertions(+), 35 deletions(-) diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py index 80f41a5..72c0306 100644 --- a/bin/SConsDoc.py +++ b/bin/SConsDoc.py @@ -668,8 +668,10 @@ class Item(object): if name[0] == '_': name = name[1:] return name.lower() - def __cmp__(self, other): - return cmp(self.sort_name, other.sort_name) + def __eq__(self, other): + return self.sort_name == other.sort_name + def __lt__(self, other): + return self.sort_name < other.sort_name class Builder(Item): pass diff --git a/bin/scons-proc.py b/bin/scons-proc.py index b93b25a..138cff7 100644 --- a/bin/scons-proc.py +++ b/bin/scons-proc.py @@ -231,10 +231,15 @@ class Proxy(object): """Retrieve the entire wrapped object""" return self.__subject - def __cmp__(self, other): + def __eq__(self, other): if issubclass(other.__class__, self.__subject.__class__): - return cmp(self.__subject, other) - return cmp(self.__dict__, other.__dict__) + return self.__subject == other + return self.__dict__ == other.__dict__ + + ## def __lt__(self, other): + ## if issubclass(other.__class__, self.__subject.__class__): + ## return self.__subject < other + ## return self.__dict__ < other.__dict__ class SConsThing(Proxy): def idfunc(self): diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index 006e8f5..49b9f35 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -420,8 +420,8 @@ class ActionBase(object): other objects (Builders, Executors, etc.) This provides the common methods for manipulating and combining those actions.""" - def __cmp__(self, other): - return cmp(self.__dict__, other) + def __eq__(self, other): + return self.__dict__ == other def no_batch_key(self, env, target, source): return None diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 0f7aff4..4b41827 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -345,8 +345,11 @@ class EmitterProxy(object): return (target, source) - def __cmp__(self, other): - return cmp(self.var, other.var) + def __eq__(self, other): + return self.var == other.var + + def __lt__(self, other): + return self.var < other.var class BuilderBase(object): """Base class for Builders, objects that create output @@ -449,8 +452,8 @@ class BuilderBase(object): except AttributeError: return str(self.__class__) - def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) + def __eq__(self, other): + return self.__dict__ == other.__dict__ def splitext(self, path, env=None): if not env: diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 41b640b..eb56299 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -145,8 +145,8 @@ class Environment(object): d['SOURCES'] = ['__s1__', '__s2__', '__s3__', '__s4__', '__s5__', '__s6__'] d['SOURCE'] = d['SOURCES'][0] return d - def __cmp__(self, other): - return cmp(self.scanner, other.scanner) or cmp(self.d, other.d) + def __eq__(self, other): + return self.scanner == other.scanner or self.d == other.d class MyAction(object): def __init__(self, action): @@ -1500,9 +1500,10 @@ class CompositeBuilderTestCase(unittest.TestCase): builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo" - assert str(e) == expect, e + assert str(err) == expect, err def test_source_ext_match(self): """Test the CompositeBuilder source_ext_match argument""" @@ -1584,45 +1585,50 @@ class CompositeBuilderTestCase(unittest.TestCase): builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t5']' from `test5b.bar': Cannot build multiple sources with different extensions: .foo, .bar" - assert str(e) == expect, e + assert str(err) == expect, err flag = 0 try: builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t6']' from `test6b.foo': Cannot build multiple sources with different extensions: .bar, .foo" - assert str(e) == expect, e + assert str(err) == expect, err flag = 0 try: builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t4']' from `test4b.bar': Cannot build multiple sources with different extensions: .foo, .bar" - assert str(e) == expect, e + assert str(err) == expect, err flag = 0 try: builder(env, target='t7', source=[env.fs.File('test7')])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder with files of different suffixes." expect = "While building `['t7']': Cannot deduce file extension from source files: ['test7']" - assert str(e) == expect, e + assert str(err) == expect, err flag = 0 try: builder(env, target='t8', source=['test8.unknown'])[0] except SCons.Errors.UserError as e: flag = 1 + err = e assert flag, "UserError should be thrown when we call a builder target with an unknown suffix." expect = "While building `['t8']' from `['test8.unknown']': Don't know how to build from a source file with suffix `.unknown'. Expected a suffix in this list: ['.foo', '.bar']." - assert str(e) == expect, e + assert str(err) == expect, err if __name__ == "__main__": suite = unittest.TestSuite() diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 22552b3..6933b6b 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -113,11 +113,11 @@ class Scanner(object): global scanned_it scanned_it[filename] = 1 - def __cmp__(self, other): + def __eq__(self, other): try: - return cmp(self.__dict__, other.__dict__) + return self.__dict__ == other.__dict__ except AttributeError: - return 1 + return False def get_skeys(self, env): return self.skeys @@ -1613,7 +1613,7 @@ def exists(env): self.name = name def __str__(self): return self.name - def __cmp__(self, other): + def __eq__(self, other): raise Exception("should not compare") ccc = C('ccc') diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py index ac728c9..d2938c7 100644 --- a/src/engine/SCons/Memoize.py +++ b/src/engine/SCons/Memoize.py @@ -145,11 +145,11 @@ class Counter(object): def display(self): fmt = " %7d hits %7d misses %s()" print(fmt % (self.hit, self.miss, self.name)) - def __cmp__(self, other): + def __eq__(self, other): try: - return cmp(self.name, other.name) + return self.name == other.name except AttributeError: - return 0 + return True class CountValue(Counter): """ diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py index ee26922..f29d545 100644 --- a/src/engine/SCons/Scanner/ScannerTests.py +++ b/src/engine/SCons/Scanner/ScannerTests.py @@ -234,7 +234,7 @@ class BaseTestCase(unittest.TestCase): def test___cmp__(self): """Test the Scanner.Base class __cmp__() method""" s = SCons.Scanner.Base(self.func, "Cmp") - assert cmp(s, None) + assert s != None def test_hash(self): """Test the Scanner.Base class __hash__() method""" diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py index 2375bc4..5700fe9 100644 --- a/src/engine/SCons/Scanner/__init__.py +++ b/src/engine/SCons/Scanner/__init__.py @@ -221,12 +221,12 @@ class Base(object): nodes.append(l) return nodes - def __cmp__(self, other): + def __eq__(self, other): try: - return cmp(self.__dict__, other.__dict__) + return self.__dict__ == other.__dict__ except AttributeError: # other probably doesn't have a __dict__ - return cmp(self.__dict__, other) + return self.__dict__ == other def __hash__(self): return id(self) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 60e5c10..7ea2789 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -537,10 +537,10 @@ class Proxy(object): """Retrieve the entire wrapped object""" return self._subject - def __cmp__(self, other): + def __eq__(self, other): if issubclass(other.__class__, self._subject.__class__): - return cmp(self._subject, other) - return cmp(self.__dict__, other.__dict__) + return self._subject == other + return self.__dict__ == other.__dict__ class Delegate(object): """A Python Descriptor class that delegates attribute fetches diff --git a/test/Scanner/generated.py b/test/Scanner/generated.py index 845111c..82206c2 100644 --- a/test/Scanner/generated.py +++ b/test/Scanner/generated.py @@ -317,8 +317,8 @@ def write_out(file, dict): class CScannerCounter(object): def __init__(self, original_CScanner, *args, **kw): self.original_CScanner = original_CScanner - def __cmp__(self, *args, **kw): - return self.original_CScanner.__cmp__(*args, **kw) + def __eq__(self, *args, **kw): + return self.original_CScanner.__eq__(*args, **kw) def __hash__(self, *args, **kw): return self.original_CScanner.__hash__(*args, **kw) def __str__(self, *args, **kw): -- cgit v0.12 From 6c1162f68d4682a045d35806a49dee50fba62808 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 13:28:41 +0000 Subject: ActionTests: No string.join(). b prefix for assert Action.get_contents(). --- src/engine/SCons/ActionTests.py | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 754c6e7..01b38f3 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -62,7 +62,7 @@ test = TestCmd.TestCmd(workdir = '') test.write('act.py', """\ import os, string, sys f = open(sys.argv[1], 'w') -f.write("act.py: '" + string.join(sys.argv[2:], "' '") + "'\\n") +f.write("act.py: '" + "' '".join(sys.argv[2:]) + "'\\n") try: if sys.argv[3]: f.write("act.py: '" + os.environ[sys.argv[3]] + "'\\n") @@ -1326,7 +1326,7 @@ class CommandActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=Environment(foo = 'FFF', bar = 'BBB', baz = CmdGen)) - assert c == "| | FFF BBB 1", c + assert c == b"| | FFF BBB 1", c # Make sure that CommandActions use an Environment's # subst_target_source() method for substitution. @@ -1337,7 +1337,7 @@ class CommandActionTestCase(unittest.TestCase): c = a.get_contents(target=DummyNode('ttt'), source = DummyNode('sss'), env=SpecialEnvironment(foo = 'GGG', bar = 'CCC', baz = 'ZZZ')) - assert c == 'subst_target_source: | $( $foo | $bar $) | $baz 1', c + assert c == b'subst_target_source: | $( $foo | $bar $) | $baz 1', c # We've discussed using the real target and source names in a # CommandAction's signature contents. This would have have the @@ -1354,35 +1354,35 @@ class CommandActionTestCase(unittest.TestCase): a = SCons.Action.CommandAction(["$TARGET"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "t1", c + assert c == b"t1", c a = SCons.Action.CommandAction(["$TARGETS"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "t1 t2 t3 t4 t5 t6", c + assert c == b"t1 t2 t3 t4 t5 t6", c a = SCons.Action.CommandAction(["${TARGETS[2]}"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "t3", c + assert c == b"t3", c a = SCons.Action.CommandAction(["${TARGETS[3:5]}"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "t4 t5", c + assert c == b"t4 t5", c a = SCons.Action.CommandAction(["$SOURCE"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "s1", c + assert c == b"s1", c a = SCons.Action.CommandAction(["$SOURCES"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "s1 s2 s3 s4 s5 s6", c + assert c == b"s1 s2 s3 s4 s5 s6", c a = SCons.Action.CommandAction(["${SOURCES[2]}"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "s3", c + assert c == b"s3", c a = SCons.Action.CommandAction(["${SOURCES[3:5]}"]) c = a.get_contents(target=t, source=s, env=env) - assert c == "s4 s5", c + assert c == b"s4 s5", c class CommandGeneratorActionTestCase(unittest.TestCase): @@ -1499,7 +1499,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): ignore = 'foo', test=test) a = self.factory(f) c = a.get_contents(target=[], source=[], env=env) - assert c == "guux FFF BBB test", c + assert c == b"guux FFF BBB test", c def test_get_contents_of_function_action(self): """Test contents of a CommandGeneratorAction-generated FunctionAction @@ -1509,13 +1509,13 @@ class CommandGeneratorActionTestCase(unittest.TestCase): pass func_matches = [ - "0,0,0,0,(),(),(d\000\000S),(),()", - "0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0,0,0,0,(),(),(d\000\000S),(),()", + b"0,0,0,0,(),(),(d\x00\x00S),(),()", ] meth_matches = [ - "1,1,0,0,(),(),(d\000\000S),(),()", - "1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1,1,0,0,(),(),(d\000\000S),(),()", + b"1,1,0,0,(),(),(d\x00\x00S),(),()", ] def f_global(target, source, env, for_signature): @@ -1540,7 +1540,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def f_local(target, source, env, for_signature): return SCons.Action.Action(LocalFunc, varlist=['XYZ']) - matches_foo = [x + "foo" for x in func_matches] + matches_foo = [x + b"foo" for x in func_matches] a = self.factory(f_global) c = a.get_contents(target=[], source=[], env=env) @@ -1668,13 +1668,13 @@ class FunctionActionTestCase(unittest.TestCase): pass func_matches = [ - "0,0,0,0,(),(),(d\000\000S),(),()", - "0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0,0,0,0,(),(),(d\000\000S),(),()", + b"0,0,0,0,(),(),(d\x00\x00S),(),()", ] meth_matches = [ - "1,1,0,0,(),(),(d\000\000S),(),()", - "1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1,1,0,0,(),(),(d\000\000S),(),()", + b"1,1,0,0,(),(),(d\x00\x00S),(),()", ] def factory(act, **kw): @@ -1688,7 +1688,7 @@ class FunctionActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=Environment()) assert c in func_matches, repr(c) - matches_foo = [x + "foo" for x in func_matches] + matches_foo = [x + b"foo" for x in func_matches] a = factory(GlobalFunc, varlist=['XYZ']) c = a.get_contents(target=[], source=[], env=Environment()) @@ -1706,10 +1706,10 @@ class FunctionActionTestCase(unittest.TestCase): class Foo(object): def get_contents(self, target, source, env): - return 'xyzzy' + return b'xyzzy' a = factory(Foo()) c = a.get_contents(target=[], source=[], env=Environment()) - assert c == 'xyzzy', repr(c) + assert c == b'xyzzy', repr(c) class LocalClass(object): def LocalMethod(self): @@ -1820,7 +1820,7 @@ class ListActionTestCase(unittest.TestCase): "z"]) c = a.get_contents(target=[], source=[], env=Environment(s = self)) assert self.foo==1, self.foo - assert c == "xyz", c + assert c == b"xyz", c class LazyActionTestCase(unittest.TestCase): def test___init__(self): @@ -1871,7 +1871,7 @@ class LazyActionTestCase(unittest.TestCase): a = SCons.Action.Action("${FOO}") env = Environment(FOO = [["This", "is", "a", "test"]]) c = a.get_contents(target=[], source=[], env=env) - assert c == "This is a test", c + assert c == b"This is a test", c def test_get_contents_of_function_action(self): """Test fetching the contents of a lazy-evaluation FunctionAction @@ -1881,13 +1881,13 @@ class LazyActionTestCase(unittest.TestCase): pass func_matches = [ - "0,0,0,0,(),(),(d\000\000S),(),()", - "0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0,0,0,0,(),(),(d\000\000S),(),()", + b"0,0,0,0,(),(),(d\x00\x00S),(),()", ] meth_matches = [ - "1,1,0,0,(),(),(d\000\000S),(),()", - "1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1,1,0,0,(),(),(d\000\000S),(),()", + b"1,1,0,0,(),(),(d\x00\x00S),(),()", ] def factory(act, **kw): @@ -1904,7 +1904,7 @@ class LazyActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c in func_matches, repr(c) - matches_foo = [x + "foo" for x in func_matches] + matches_foo = [x + b"foo" for x in func_matches] env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ'])) c = a.get_contents(target=[], source=[], env=env) @@ -1931,8 +1931,8 @@ class ActionCallerTestCase(unittest.TestCase): pass matches = [ - "d\000\000S", - "d\x00\x00S" + b"d\000\000S", + b"d\x00\x00S" ] af = SCons.Action.ActionFactory(GlobalFunc, strfunc) @@ -1946,8 +1946,8 @@ class ActionCallerTestCase(unittest.TestCase): assert c in matches, repr(c) matches = [ - 'd\000\000S', - "d\x00\x00S" + b'd\000\000S', + b"d\x00\x00S" ] class LocalActFunc(object): @@ -1965,8 +1965,8 @@ class ActionCallerTestCase(unittest.TestCase): assert c in matches, repr(c) matches = [ - "", - "", + b"", + b"", ] af = SCons.Action.ActionFactory(str, strfunc) -- cgit v0.12 From 2d2df48b33045bb15b543264114c6ef35773ef29 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Fri, 27 Dec 2013 13:30:45 +0000 Subject: Another list(*.keys()) for item deletion loop. --- src/engine/SCons/SConfTests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py index e604886..ba524fd 100644 --- a/src/engine/SCons/SConfTests.py +++ b/src/engine/SCons/SConfTests.py @@ -60,7 +60,7 @@ class SConfTestCase(unittest.TestCase): # We try to reset scons' state (including all global variables) import SCons.SConsign SCons.SConsign.write() # simulate normal scons-finish - for n in sys.modules.keys(): + for n in list(sys.modules.keys()): if n.split('.')[0] == 'SCons' and n[:12] != 'SCons.compat': m = sys.modules[n] if isinstance(m, ModuleType): -- cgit v0.12 From 26003a0bd3168f8c2ee3d92a26d35ca977f8e25b Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Wed, 8 Jan 2014 13:25:16 +0000 Subject: Some more six.PY2/PY3 usage. --- bin/install_scons.py | 6 ++++-- review.py | 14 ++++++++------ runtest.py | 6 ++++-- src/engine/SCons/Util.py | 11 ++++------- 4 files changed, 20 insertions(+), 17 deletions(-) diff --git a/bin/install_scons.py b/bin/install_scons.py index 7a39e96..afd0789 100644 --- a/bin/install_scons.py +++ b/bin/install_scons.py @@ -19,14 +19,16 @@ # hierarchy. from __future__ import print_function +from six import PY3 + import getopt import os import shutil import sys import tarfile -try: +if PY3: from urllib.request import urlretrieve -except ImportError: # Python < 3 +else: from urllib import urlretrieve from Command import CommandRunner, Usage diff --git a/review.py b/review.py index c01472e..9f1ba82 100644 --- a/review.py +++ b/review.py @@ -15,6 +15,8 @@ # limitations under the License. from __future__ import print_function +from six import PY3 + """Tool for uploading diffs from a version control system to the codereview app. Usage summary: upload.py [options] [-- diff_options] [path...] @@ -32,14 +34,14 @@ against by using the '--rev' option. # This code is derived from appcfg.py in the App Engine SDK (open source), # and from ASPN recipe #146306. -try: +if PY3: from configparser import ConfigParser -except ImportError: # Python < 3 +else: from ConfigParser import ConfigParser -try: +if PY3: from http.cookiejar import ( CookieJar, MozillaCookieJar, LoadError as CookieLoadError) -except ImportError: # Python < 3 +else: from cookielib import ( CookieJar, MozillaCookieJar, LoadError as CookieLoadError) import fnmatch @@ -52,7 +54,7 @@ import re import socket import subprocess import sys -try: +if PY3: from urllib.request import ( Request, OpenerDirector, ProxyHandler, UnknownHandler, HTTPHandler, HTTPSHandler, @@ -61,7 +63,7 @@ try: from urllib.error import HTTPError from urllib.parse import ( urlencode, urlparse, urlunparse, splituser as urlsplituser) -except ImportError: # Python < 3 +else: from urllib2 import ( Request, OpenerDirector, ProxyHandler, UnknownHandler, HTTPHandler, HTTPSHandler, diff --git a/runtest.py b/runtest.py index 2470a61..6380292 100755 --- a/runtest.py +++ b/runtest.py @@ -85,6 +85,8 @@ # rather than reinventing that wheel.) from __future__ import print_function +from six import PY3 + import getopt import glob import os @@ -95,9 +97,9 @@ import time try: import threading - try: + if PY3: from queue import Queue - except ImportError: # Python < 3 + else: from Queue import Queue threading_ok = True except ImportError: diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 7ea2789..052b3fc 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -33,24 +33,21 @@ import copy import re import types -try: +if PY3: from collections import UserDict, UserList, UserString -except ImportError: # Python < 3 +else: from UserDict import UserDict from UserList import UserList from UserString import UserString # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. -try: - InstanceType = types.InstanceType -except AttributeError: # Python 3 - InstanceType = None +InstanceType = types.InstanceType if PY2 else None MethodType = types.MethodType FunctionType = types.FunctionType try: unicode except NameError: UnicodeType = None -else: UnicodeType = str +else: UnicodeType = unicode def dictify(keys, values, result={}): for k, v in zip(keys, values): -- cgit v0.12 From 8986df6b325e924f4143b03705129899fccc72ba Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Wed, 8 Jan 2014 13:27:10 +0000 Subject: Fixed re.sub for PY3 print() in TestCmd.write(). --- QMTest/TestCmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index c075cd3..2ac3da1 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1717,7 +1717,7 @@ class TestCmd(object): begin with a 'w'. The default is 'wb' (binary write). """ if PY3: - content = re.sub('print (.+)', 'print(\1)', content) + content = re.sub(r'print (.+)', r'print(\1)', content) file = self.canonicalize(file) if mode[0] != 'w': raise ValueError("mode must begin with 'w'") -- cgit v0.12 From ea1890249923aab9cda388b2d22b566dbb7b8949 Mon Sep 17 00:00:00 2001 From: Rocco Matano Date: Fri, 7 Mar 2014 15:39:43 +0100 Subject: fix some minor 2to3 issues on windows --- src/engine/SCons/Platform/win32.py | 22 +++++++++++++--------- src/engine/SCons/Tool/386asm.py | 2 +- src/engine/SCons/Tool/MSCommon/common.py | 5 ++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 879817d..1e4fb2a 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -61,16 +61,21 @@ else: parallel_msg = None import builtins - - _builtin_file = builtins.file + builtin_file = getattr(builtins, 'file', None) is not None + + if builtin_file: + _builtin_file = builtins.file + + class _scons_file(_builtin_file): + def __init__(self, *args, **kw): + _builtin_file.__init__(self, *args, **kw) + win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), + win32con.HANDLE_FLAG_INHERIT, 0) + + builtins.file = _scons_file + _builtin_open = builtins.open - class _scons_file(_builtin_file): - def __init__(self, *args, **kw): - _builtin_file.__init__(self, *args, **kw) - win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), - win32con.HANDLE_FLAG_INHERIT, 0) - def _scons_open(*args, **kw): fp = _builtin_open(*args, **kw) win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), @@ -78,7 +83,6 @@ else: 0) return fp - builtins.file = _scons_file builtins.open = _scons_open try: diff --git a/src/engine/SCons/Tool/386asm.py b/src/engine/SCons/Tool/386asm.py index 8acc55f..51738eb 100644 --- a/src/engine/SCons/Tool/386asm.py +++ b/src/engine/SCons/Tool/386asm.py @@ -37,7 +37,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from SCons.Tool.PharLapCommon import addPharLapPaths import SCons.Util -as_module = __import__('as', globals(), locals(), []) +as_module = __import__('as', globals(), locals(), [], 1) def generate(env): """Add Builders and construction variables for ar to an Environment.""" diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py index e5c78e9..4a91310 100644 --- a/src/engine/SCons/Tool/MSCommon/common.py +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -115,11 +115,11 @@ def normalize_env(env, keys, force=False): normenv = {} if env: for k in env.keys(): - normenv[k] = copy.deepcopy(env[k]).encode('mbcs') + normenv[k] = copy.deepcopy(env[k]) for k in keys: if k in os.environ and (force or not k in normenv): - normenv[k] = os.environ[k].encode('mbcs') + normenv[k] = os.environ[k] # This shouldn't be necessary, since the default environment should include system32, # but keep this here to be safe, since it's needed to find reg.exe which the MSVC @@ -212,7 +212,6 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")): for p in plist: # Do not add empty paths (when a var ends with ;) if p: - p = p.encode('mbcs') # XXX: For some reason, VC98 .bat file adds "" around the PATH # values, and it screws up the environment later, so we strip # it. -- cgit v0.12 From 18ecb44af82ac0b95c852ff05eaf4fe3af3fb724 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 22:32:02 +0000 Subject: Additional ()s for print. --- src/script/scons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script/scons.py b/src/script/scons.py index d0bb812..25ae644 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -191,7 +191,7 @@ if __name__ == "__main__": except: print("Import failed. Unable to find SCons files in:") for path in libs: - print " %s" % path + print(" %s" % path) raise # this does all the work, and calls sys.exit -- cgit v0.12 From e7fbae42ed9a4db4be2152c2bccd05ce46226689 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 22:37:42 +0000 Subject: SConstruct: More bytes/str fixes. --- SConstruct | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SConstruct b/SConstruct index f1f1fa3..a18de57 100644 --- a/SConstruct +++ b/SConstruct @@ -418,7 +418,8 @@ def soelim(target, source, env): def soscan(node, env, path): c = node.get_text_contents() - return re.compile(r"^[\.']so\s+(\S+)", re.M).findall(c) + # Node contents are bytes ==> br"..." + return re.compile(br"^[\.']so\s+(\S+)", re.M).findall(c) soelimbuilder = Builder(action = Action(soelim), source_scanner = Scanner(soscan)) @@ -828,7 +829,7 @@ for p in [ scons ]: def write_src_files(target, source, **kw): global src_files src_files.sort() - f = open(str(target[0]), 'wb') + f = open(str(target[0]), 'w') for file in src_files: f.write(file + "\n") f.close() -- cgit v0.12 From 83cdce661b4a953f2b307f60577db53fb23a8b2d Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 22:38:22 +0000 Subject: engine.SCons: More bytes/str fixes. --- src/engine/SCons/Action.py | 2 +- src/engine/SCons/Node/FS.py | 2 +- src/engine/SCons/Tool/docbook/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index d7d9afd..cec241d 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -290,7 +290,7 @@ def _function_contents(func): xxx = [_object_contents(x.cell_contents) for x in closure] except AttributeError: xxx = [] - contents.append(b',(' + b','.join(xxx) + b')') + contents.append(b',(' + ','.join(xxx).encode('ascii') + b')') return b''.join(contents) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index a537ca8..efca0c7 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -2420,7 +2420,7 @@ class File(Base): def get_contents(self): if not self.rexists(): - return '' + return b'' # Should always be bytes fname = self.rfile().abspath try: contents = open(fname, "rb").read() diff --git a/src/engine/SCons/Tool/docbook/__init__.py b/src/engine/SCons/Tool/docbook/__init__.py index aacc26d..627ff51 100644 --- a/src/engine/SCons/Tool/docbook/__init__.py +++ b/src/engine/SCons/Tool/docbook/__init__.py @@ -335,7 +335,7 @@ def __build_lxml(target, source, env): result = transform(doc) try: - of = open(str(target[0]), "w") + of = open(str(target[0]), "wb") of.write(of.write(etree.tostring(result, pretty_print=True))) of.close() except: -- cgit v0.12 From 7ae89fc5202506a060260f6052ec2f464c451107 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Mon, 31 Mar 2014 22:39:12 +0000 Subject: Tool.gs: Changed relative pdf import to absolute. --- src/engine/SCons/Tool/gs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py index 443ace2..25359a8 100644 --- a/src/engine/SCons/Tool/gs.py +++ b/src/engine/SCons/Tool/gs.py @@ -62,7 +62,7 @@ def generate(env): if GhostscriptAction is None: GhostscriptAction = SCons.Action.Action('$GSCOM', '$GSCOMSTR') - from . import pdf + from SCons.Tool import pdf pdf.generate(env) bld = env['BUILDERS']['PDF'] -- cgit v0.12 From fad7c3eaf7f9cae12dbf03e03df7919d6fedea0e Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Tue, 1 Apr 2014 07:19:29 +0000 Subject: Main: Use exec() with compile(). --- src/engine/SCons/Script/Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 7906488..8725530 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -733,7 +733,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): site_m[k] = m.__dict__[k] # This is the magic. - exec(fp, site_m) + exec(compile(fp.read(), fp.name, 'exec'), site_m) except KeyboardInterrupt: raise except Exception as e: -- cgit v0.12 From a13f1049893f07d3a77474d77214a24eee3cb75b Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Tue, 1 Apr 2014 07:28:31 +0000 Subject: test: site_scons/site_init: list() globals keys for looping to allow changes. --- test/site_scons/site_init.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/site_scons/site_init.py b/test/site_scons/site_init.py index 9f2e411..45201ac 100644 --- a/test/site_scons/site_init.py +++ b/test/site_scons/site_init.py @@ -51,7 +51,7 @@ import os.path import re special = [] -for x in globals().keys(): +for x in list(globals().keys()): if re.match("__[^_]+__", x): if x in ("__builtins__", "__package__",): # Ignore certain keywords, as they are known to be added by Python -- cgit v0.12 From 4631c0c43550e65bb4cb57a21b17c329966b2e03 Mon Sep 17 00:00:00 2001 From: Stefan Zimmermann Date: Tue, 1 Apr 2014 07:40:28 +0000 Subject: Main: No __future__.print_function (would affect exec()'d code). --- src/engine/SCons/Script/Main.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 8725530..0663c7a 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,7 +10,9 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ -from __future__ import print_function +# Would affect exec()'d site_init.py: +## from __future__ import print_function +from six import print_ unsupported_python_version = (2, 3, 0) deprecated_python_version = (2, 7, 0) @@ -339,7 +341,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): except SCons.Errors.UserError as e: print(e) except (IOError, OSError) as e: - print("scons: Could not remove '%s':" % pathstr, e.strerror) + print_("scons: Could not remove '%s':" % pathstr, e.strerror) def show(self): target = self.targets[0] @@ -364,7 +366,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # the file not existing. In either case, print a # message and keep going to try to remove as many # targets aa possible. - print("scons: Could not remove '%s':" % str(t), e.strerror) + print_("scons: Could not remove '%s':" % str(t), e.strerror) else: if removed: display("Removed " + str(t)) @@ -798,7 +800,7 @@ def _load_all_site_scons_dirs(topdir, verbose=None): dirs=sysdirs + [topdir] for d in dirs: if verbose: # this is used by unit tests. - print("Loading site dir ", d) + print_("Loading site dir ", d) _load_site_scons_dir(d) def test_load_all_site_scons_dirs(d): -- cgit v0.12 From 8490ea812140862af7058f9617959061510c3701 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 6 Apr 2014 10:50:33 -0400 Subject: Added change log for python3 port --- src/CHANGES.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5cea35f..f65dfd5 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -6,6 +6,9 @@ RELEASE 2.3.2.alpha.yyyymmdd - NEW DATE WILL BE INSERTED HERE + From Neal Becker and Stefan Zimmermann: + - Python 3 port and compatibility + From Gary Oberbrunner: - get default RPM architecture more robustly when building RPMs -- cgit v0.12 From a6ea2d760464092ea91a0dd01ba6260288aa3587 Mon Sep 17 00:00:00 2001 From: Gary Oberbrunner Date: Sun, 20 Apr 2014 06:56:10 -0400 Subject: Added six module as SCons.compat.six, for python3 port. --- QMTest/TestCmd.py | 4 +- QMTest/TestCmdTests.py | 50 +-- bin/install_scons.py | 2 +- review.py | 8 +- runtest.py | 5 +- src/engine/SCons/MemoizeTests.py | 2 +- src/engine/SCons/Script/Main.py | 2 +- src/engine/SCons/Taskmaster.py | 10 +- src/engine/SCons/Tool/xgettext.py | 30 +- src/engine/SCons/Util.py | 32 +- src/engine/SCons/UtilTests.py | 6 +- src/engine/SCons/compat/_scons_subprocess.py | 2 +- src/engine/SCons/compat/six.py | 646 +++++++++++++++++++++++++++ src/engine/SCons/compat/sixTests.py | 34 ++ src/script/sconsign.py | 4 +- test/option/profile.py | 4 +- 16 files changed, 760 insertions(+), 81 deletions(-) create mode 100755 src/engine/SCons/compat/six.py create mode 100644 src/engine/SCons/compat/sixTests.py diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 55c198f..e6b128b 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -287,7 +287,7 @@ version. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. from __future__ import division, print_function -from six import PY3 +from SCons.compat.six import PY3 __author__ = "Steven Knight " __revision__ = "TestCmd.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -685,7 +685,7 @@ if subprocess.mswindows: assert ol is None lpBuffer = ctypes.create_string_buffer(bufSize) bytesRead = DWORD() - bErr = ctypes.windll.kernel32.ReadFile( + bErr = ctypes.windll.kernel32.ReadFile( hFile, lpBuffer, bufSize, ctypes.byref(bytesRead), ol) if not bErr: raise ctypes.WinError() return (0, ctypes.string_at(lpBuffer, bytesRead.value)) diff --git a/QMTest/TestCmdTests.py b/QMTest/TestCmdTests.py index 6611590..a2e7022 100644 --- a/QMTest/TestCmdTests.py +++ b/QMTest/TestCmdTests.py @@ -19,7 +19,7 @@ AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ -from six import PY3 +from SCons.compat.six import PY3 __author__ = "Steven Knight " __revision__ = "TestCmdTests.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -1870,24 +1870,24 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '', verbose = 1) - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % t.script_path assert expect == e, (expect, e) - + testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 1) - + sys.stdout = StringIO() sys.stderr = StringIO() - + testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path o = sys.stdout.getvalue() @@ -1921,10 +1921,10 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '', verbose = 2) - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) line_fmt = "script: %s: %s: ['arg1 arg2']\n" @@ -1938,14 +1938,14 @@ class run_verbose_TestCase(TestCmdTestCase): expect = 'python "%s" "arg1 arg2"\n' % t.script_path e = sys.stderr.getvalue() assert e == expect, (e, expect) - + testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 2) - + sys.stdout = StringIO() sys.stderr = StringIO() - + testx.run(arguments = ['arg1 arg2']) line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n" @@ -1966,10 +1966,10 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '', verbose = 2) - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n" @@ -1986,10 +1986,10 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '', verbose = 3) - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n" @@ -2010,10 +2010,10 @@ class run_verbose_TestCase(TestCmdTestCase): test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '') - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) line_fmt = "script: %s: %s: ['arg1 arg2']\n" @@ -2027,13 +2027,13 @@ class run_verbose_TestCase(TestCmdTestCase): expect = 'python "%s" "arg1 arg2"\n' % t.script_path e = sys.stderr.getvalue() assert e == expect, (e, expect) - + testx = TestCmd.TestCmd(program = t.scriptx, workdir = '') - + sys.stdout = StringIO() sys.stderr = StringIO() - + testx.run(arguments = ['arg1 arg2']) line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n" @@ -2056,24 +2056,24 @@ class run_verbose_TestCase(TestCmdTestCase): interpreter = 'python', workdir = '', verbose = 1) - + sys.stdout = StringIO() sys.stderr = StringIO() - + test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % t.script_path assert expect == e, (expect, e) - + testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 1) - + sys.stdout = StringIO() sys.stderr = StringIO() - + testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path o = sys.stdout.getvalue() diff --git a/bin/install_scons.py b/bin/install_scons.py index afd0789..55e327d 100644 --- a/bin/install_scons.py +++ b/bin/install_scons.py @@ -19,7 +19,7 @@ # hierarchy. from __future__ import print_function -from six import PY3 +from SCons.compat.six import PY3 import getopt import os diff --git a/review.py b/review.py index 9f1ba82..a796b2f 100644 --- a/review.py +++ b/review.py @@ -15,7 +15,7 @@ # limitations under the License. from __future__ import print_function -from six import PY3 +from SCons.compat.six import PY3 """Tool for uploading diffs from a version control system to the codereview app. @@ -120,7 +120,7 @@ VCS_UNKNOWN = "Unknown" # whitelist for non-binary filetypes which do not start with "text/" # .mm (Objective-C) shows up as application/x-freemind on my Linux box. TEXT_MIMETYPES = ['application/javascript', 'application/x-javascript', - 'application/xml', 'application/x-freemind', + 'application/xml', 'application/x-freemind', 'application/x-sh'] VCS_ABBREVIATIONS = { @@ -1474,7 +1474,7 @@ def GuessVCSName(): """ def RunDetectCommand(vcs_type, command): """Helper to detect VCS by executing command. - + Returns: A pair (vcs, output) or None. Throws exception on error. """ @@ -1486,7 +1486,7 @@ def GuessVCSName(): (errcode, message) = xxx_todo_changeme.args if errcode != errno.ENOENT: # command not found code raise - + # Mercurial has a command to get the base directory of a repository # Try running it, but don't die if we don't have hg installed. # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. diff --git a/runtest.py b/runtest.py index 7155556..485374a 100755 --- a/runtest.py +++ b/runtest.py @@ -81,7 +81,6 @@ # rather than reinventing that wheel.) from __future__ import print_function -from six import PY3 import getopt import glob @@ -93,9 +92,9 @@ import time try: import threading - if PY3: + try: # python3 from queue import Queue - else: + except ImportError as e: # python2 from Queue import Queue threading_ok = True except ImportError: diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py index c1c69ae..8476349 100644 --- a/src/engine/SCons/MemoizeTests.py +++ b/src/engine/SCons/MemoizeTests.py @@ -20,7 +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 six import add_metaclass +from SCons.compat.six import add_metaclass __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 0663c7a..1357e7f 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -12,7 +12,7 @@ it goes here. # Would affect exec()'d site_init.py: ## from __future__ import print_function -from six import print_ +from SCons.compat.six import print_ unsupported_python_version = (2, 3, 0) deprecated_python_version = (2, 7, 0) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 00147b2..4a06654 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -306,7 +306,7 @@ class Task(object): t.push_to_cache() t.built() t.visited() - if (not print_prepare and + if (not print_prepare and (not hasattr(self, 'options') or not self.options.debug_includes)): t.release_target_info() else: @@ -424,7 +424,7 @@ class Task(object): # parallel build...) t.visited() t.set_state(NODE_UP_TO_DATE) - if (not print_prepare and + if (not print_prepare and (not hasattr(self, 'options') or not self.options.debug_includes)): t.release_target_info() @@ -533,8 +533,8 @@ class Task(object): Task ready for execution. """ - import six - six.reraise(*self.exc_info()) + import SCons.compat.six + SCons.compat.six.reraise(*self.exc_info()) class AlwaysTask(Task): def needs_execute(self): @@ -940,7 +940,7 @@ class Taskmaster(object): executor = node.get_executor() if executor is None: return None - + tlist = executor.get_all_targets() task = self.tasker(self, tlist, node in self.original_top, node) diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index f9375a2..923fd17 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -1,10 +1,10 @@ -""" xgettext tool +""" xgettext tool Tool specific initialization of `xgettext` tool. """ # __COPYRIGHT__ -# +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -12,10 +12,10 @@ Tool specific initialization of `xgettext` tool. # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: -# +# # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -23,7 +23,7 @@ Tool specific initialization of `xgettext` tool. # 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 six import u +from SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -40,12 +40,12 @@ class _CmdRunner(object): self.command = command self.commandstr = commandstr - def __call__(self, target, source, env): + def __call__(self, target, source, env): import SCons.Action import subprocess import os import sys - kw = { + kw = { 'stdin' : 'devnull', 'stdout' : subprocess.PIPE, 'stderr' : subprocess.PIPE, @@ -105,9 +105,9 @@ def _update_pot_file(target, source, env): os.chdir(save_os_cwd) # If the command was not successfull, return error code. if status: return status - + new_content = cmd.out - + if not new_content: # When xgettext finds no internationalized messages, no *.pot is created # (because we don't want to bother translators with empty POT files). @@ -145,7 +145,7 @@ def _update_pot_file(target, source, env): # Print message employing SCons.Action.Action for that. msg = "Not writting " + repr(str(target[0])) + " (" + explain + ")" env.Execute(SCons.Action.Action(nop, msg)) - return 0 + return 0 ############################################################################# ############################################################################# @@ -208,7 +208,7 @@ def _scan_xgettext_from_files(target, source, env, files = None, path = None): contents = re_emptyln.sub("", contents) contents = re_trailws.sub("", contents) depnames = contents.splitlines() - for depname in depnames: + for depname in depnames: depfile = SCons.Node.FS.find_file(depname, dirs) if not depfile: depfile = env.arg2nodes(depname, dirs[0].File) @@ -223,7 +223,7 @@ def _pot_update_emitter(target, source, env): import SCons.Util import SCons.Node.FS - if 'XGETTEXTFROM' in env: + if 'XGETTEXTFROM' in env: xfrom = env['XGETTEXTFROM'] else: return target, source @@ -231,13 +231,13 @@ def _pot_update_emitter(target, source, env): xfrom = [ xfrom ] xfrom = SCons.Util.flatten(xfrom) - + # Prepare list of 'POTFILE.in' files. files = [] for xf in xfrom: if not isinstance(xf, SCons.Node.FS.Base): if SCons.Util.is_String(xf): - # Interpolate variables in strings + # Interpolate variables in strings xf = env.subst(xf, source = source, target = target) xf = env.arg2nodes(xf) files.extend(xf) @@ -275,7 +275,7 @@ def generate(env,**kw): try: env['XGETTEXT'] = _detect_xgettext(env) except: - env['XGETTEXT'] = 'xgettext' + env['XGETTEXT'] = 'xgettext' # NOTE: sources="$SOURCES" would work as well. However, we use following # construction to convert absolute paths provided by scons onto paths # relative to current working dir. Note, that scons expands $SOURCE(S) to diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 052b3fc..3a368cb 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -23,7 +23,7 @@ Various utility functions go here. # 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 six import PY2, PY3, u +from SCons.compat.six import PY2, PY3, u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -348,7 +348,7 @@ def is_Scalar(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes # assumes that the obj argument is a string must of the time. return isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes) -def do_flatten(sequence, result, isinstance=isinstance, +def do_flatten(sequence, result, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes): for item in sequence: if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): @@ -356,7 +356,7 @@ def do_flatten(sequence, result, isinstance=isinstance, else: do_flatten(item, result) -def flatten(obj, isinstance=isinstance, StringTypes=StringTypes, +def flatten(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes, do_flatten=do_flatten): """Flatten a sequence to a non-nested list. @@ -374,7 +374,7 @@ def flatten(obj, isinstance=isinstance, StringTypes=StringTypes, do_flatten(item, result) return result -def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes, +def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes, do_flatten=do_flatten): """Flatten a sequence to a non-nested list. @@ -395,7 +395,7 @@ def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes, # to_String_for_signature() will use a for_signature() method if the # specified object has one. # -def to_String(s, +def to_String(s, isinstance=isinstance, str=str, UserString=UserString, BaseStringTypes=BaseStringTypes): if isinstance(s,BaseStringTypes): @@ -408,11 +408,11 @@ def to_String(s, else: return str(s) -def to_String_for_subst(s, +def to_String_for_subst(s, isinstance=isinstance, str=str, to_String=to_String, BaseStringTypes=BaseStringTypes, SequenceTypes=SequenceTypes, UserString=UserString): - + # Note that the test cases are sorted by order of probability. if isinstance(s, BaseStringTypes): return s @@ -428,7 +428,7 @@ def to_String_for_subst(s, else: return str(s) -def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst, +def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst, AttributeError=AttributeError): try: f = obj.for_signature @@ -486,7 +486,7 @@ def semi_deepcopy(x): return x.__class__(semi_deepcopy_dict(x)) elif isinstance(x, UserList): return x.__class__(_semi_deepcopy_list(x)) - + return x @@ -632,7 +632,7 @@ else: builtins.WindowsError = WindowsError else: del e - + HKEY_CLASSES_ROOT = None HKEY_LOCAL_MACHINE = None HKEY_CURRENT_USER = None @@ -741,7 +741,7 @@ else: continue return None -def PrependPath(oldpath, newpath, sep = os.pathsep, +def PrependPath(oldpath, newpath, sep = os.pathsep, delete_existing=1, canonicalize=None): """This prepends newpath elements to the given oldpath. Will only add any particular path once (leaving the first one it encounters @@ -760,7 +760,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep, not move it to the beginning; it will stay where it is in the list. - If canonicalize is not None, it is applied to each element of + If canonicalize is not None, it is applied to each element of newpath before use. """ @@ -782,7 +782,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep, newpaths=list(map(canonicalize, newpaths)) if not delete_existing: - # First uniquify the old paths, making sure to + # First uniquify the old paths, making sure to # preserve the first instance (in Unix/Linux, # the first one wins), and remembering them in normpaths. # Then insert the new paths at the head of the list @@ -823,7 +823,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep, else: return sep.join(paths) -def AppendPath(oldpath, newpath, sep = os.pathsep, +def AppendPath(oldpath, newpath, sep = os.pathsep, delete_existing=1, canonicalize=None): """This appends new path elements to the given old path. Will only add any particular path once (leaving the last one it @@ -841,7 +841,7 @@ def AppendPath(oldpath, newpath, sep = os.pathsep, If delete_existing is 0, then adding a path that exists will not move it to the end; it will stay where it is in the list. - If canonicalize is not None, it is applied to each element of + If canonicalize is not None, it is applied to each element of newpath before use. """ @@ -1436,7 +1436,7 @@ else: m.update(to_bytes (str(blck))) f.close() return m.hexdigest() - + def MD5collect(signatures): """ Collects a list of signatures into an aggregate signature. diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 3167b9d..c52c910 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -20,7 +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 six import u +from SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -697,7 +697,7 @@ bling def test_intern(self): s1 = silent_intern("spam") # Python 3.x does not have a unicode() global function - if sys.version[0] == '2': + if sys.version[0] == '2': s2 = silent_intern(unicode("unicode spam")) s3 = silent_intern(42) s4 = silent_intern("spam") @@ -710,7 +710,7 @@ class MD5TestCase(unittest.TestCase): """Test collecting a list of signatures into a new signature value """ s = list(map(MD5signature, ('111', '222', '333'))) - + assert '698d51a19d8a121ce581499d7b701668' == MD5collect(s[0:1]) assert '8980c988edc2c78cc43ccb718c06efd5' == MD5collect(s[0:2]) assert '53fd88c84ff8a285eb6e0a687e55b8c7' == MD5collect(s) diff --git a/src/engine/SCons/compat/_scons_subprocess.py b/src/engine/SCons/compat/_scons_subprocess.py index e4ac777..a58539d 100644 --- a/src/engine/SCons/compat/_scons_subprocess.py +++ b/src/engine/SCons/compat/_scons_subprocess.py @@ -352,7 +352,7 @@ except that: """ from __future__ import print_function -from six import integer_types +from SCons.compat.six import integer_types import sys mswindows = (sys.platform == "win32") diff --git a/src/engine/SCons/compat/six.py b/src/engine/SCons/compat/six.py new file mode 100755 index 0000000..019130f --- /dev/null +++ b/src/engine/SCons/compat/six.py @@ -0,0 +1,646 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2014 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.6.1" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + try: + result = self._resolve() + except ImportError: + # See the nice big comment in MovedModule.__getattr__. + raise AttributeError("%s could not be imported " % self.name) + setattr(obj, self.name, result) # Invokes __set__. + # This is a bit ugly, but it avoids running this again. + delattr(obj.__class__, self.name) + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + # It turns out many Python frameworks like to traverse sys.modules and + # try to load various attributes. This causes problems if this is a + # platform-specific module on the wrong platform, like _winreg on + # Unixes. Therefore, we silently pretend unimportable modules do not + # have any attributes. See issues #51, #53, #56, and #63 for the full + # tales of woe. + # + # First, if possible, avoid loading the module just to look at __file__, + # __name__, or __path__. + if (attr in ("__file__", "__name__", "__path__") and + self.mod not in sys.modules): + raise AttributeError(attr) + try: + _module = self._resolve() + except ImportError: + raise AttributeError(attr) + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + + +class _MovedItems(_LazyModule): + """Lazy loading of moved objects""" + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "xmlrpclib", "xmlrpc.server"), + MovedModule("winreg", "_winreg"), +] +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + sys.modules[__name__ + ".moves." + attr.name] = attr +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +sys.modules[__name__ + ".moves.urllib_parse"] = sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse") + + +class Module_six_moves_urllib_error(_LazyModule): + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +sys.modules[__name__ + ".moves.urllib_error"] = sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +sys.modules[__name__ + ".moves.urllib_request"] = sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +sys.modules[__name__ + ".moves.urllib_response"] = sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +sys.modules[__name__ + ".moves.urllib_robotparser"] = sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + parse = sys.modules[__name__ + ".moves.urllib_parse"] + error = sys.modules[__name__ + ".moves.urllib_error"] + request = sys.modules[__name__ + ".moves.urllib_request"] + response = sys.modules[__name__ + ".moves.urllib_response"] + robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"] + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + + +sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" + + _iterkeys = "keys" + _itervalues = "values" + _iteritems = "items" + _iterlists = "lists" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + _iterkeys = "iterkeys" + _itervalues = "itervalues" + _iteritems = "iteritems" + _iterlists = "iterlists" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +def iterkeys(d, **kw): + """Return an iterator over the keys of a dictionary.""" + return iter(getattr(d, _iterkeys)(**kw)) + +def itervalues(d, **kw): + """Return an iterator over the values of a dictionary.""" + return iter(getattr(d, _itervalues)(**kw)) + +def iteritems(d, **kw): + """Return an iterator over the (key, value) pairs of a dictionary.""" + return iter(getattr(d, _iteritems)(**kw)) + +def iterlists(d, **kw): + """Return an iterator over the (key, [values]) pairs of a dictionary.""" + return iter(getattr(d, _iterlists)(**kw)) + + +if PY3: + def b(s): + return s.encode("latin-1") + def u(s): + return s + unichr = chr + if sys.version_info[1] <= 1: + def int2byte(i): + return bytes((i,)) + else: + # This is about 2x faster than the implementation above on 3.2+ + int2byte = operator.methodcaller("to_bytes", 1, "big") + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO +else: + def b(s): + return s + # Workaround for standalone backslash + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + def byte2int(bs): + return ord(bs[0]) + def indexbytes(buf, i): + return ord(buf[i]) + def iterbytes(buf): + return (ord(byte) for byte in buf) + import StringIO + StringIO = BytesIO = StringIO.StringIO +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + + def reraise(tp, value, tb=None): + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + +_add_doc(reraise, """Reraise an exception.""") + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + return meta("NewBase", bases, {}) + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper diff --git a/src/engine/SCons/compat/sixTests.py b/src/engine/SCons/compat/sixTests.py new file mode 100644 index 0000000..f8c1979 --- /dev/null +++ b/src/engine/SCons/compat/sixTests.py @@ -0,0 +1,34 @@ +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +import unittest + +class sixTestCase(unittest.TestCase): + + def test_import(self): + """Test that six imports correctly.""" + import sys + print sys.path + from SCons.compat.six import PY2, PY3 + self.assertTrue(PY2 or PY3) + diff --git a/src/script/sconsign.py b/src/script/sconsign.py index e99a741..9f75e3a 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -24,7 +24,7 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. from __future__ import print_function -from six import PY2, PY3 +from SCons.compat.six import PY2, PY3 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -85,7 +85,7 @@ try: except ImportError: pass else: - # when running from an egg add the egg's directory + # when running from an egg add the egg's directory try: d = pkg_resources.get_distribution('scons') except pkg_resources.DistributionNotFound: diff --git a/test/option/profile.py b/test/option/profile.py index 97f84db..f408136 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -21,7 +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 six import u +from SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -113,7 +113,7 @@ memory_lines = [l for l in lines if l.find(expect) != -1] test.fail_test(len(memory_lines) != 1) - + test.pass_test() -- cgit v0.12 From 98bb69c7c9e13ea57ae7e6e8db4740a4dd43ed16 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 25 Feb 2015 21:02:49 -0800 Subject: remove extra parens causing syntax error --- src/engine/SCons/Script/Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 3ef88c7..556ddd3 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -373,7 +373,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # the file not existing. In either case, print a # message and keep going to try to remove as many # targets aa possible. - print(("scons: Could not remove '%s':" % str(t), e.strerror) + print("scons: Could not remove '%s':" % str(t), e.strerror) else: if removed: display("Removed " + str(t)) -- cgit v0.12 From 34cf3bdb1743de9a5534bfd25998d0a01297f004 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 13:52:31 +0000 Subject: Run futurize --stage1. --- bin/SConsExamples.py | 128 ++++---- bin/memlogs.py | 3 +- bin/memoicmp.py | 7 +- src/engine/SCons/Action.py | 3 +- src/engine/SCons/EnvironmentTests.py | 3 +- src/engine/SCons/Node/__init__.py | 38 +-- src/engine/SCons/Script/Main.py | 6 +- src/engine/SCons/Script/SConscript.py | 4 +- src/engine/SCons/Tool/cyglink.py | 37 ++- src/engine/SCons/Tool/f08.py | 4 +- src/engine/SCons/Tool/msvs.py | 136 ++++---- src/engine/SCons/Tool/swig.py | 5 +- src/engine/SCons/compat/six.py | 4 +- src/engine/SCons/compat/sixTests.py | 3 +- src/engine/SCons/cppTests.py | 4 +- src/script/scons.py | 2 + src/setup.py | 2 + src/test_interrupts.py | 2 + test/LINK/VersionedLib.py | 574 +++++++++++++++++----------------- test/option/debug-multiple.py | 16 +- test/site_scons/sysdirs.py | 6 +- 21 files changed, 509 insertions(+), 478 deletions(-) diff --git a/bin/SConsExamples.py b/bin/SConsExamples.py index e3a7502..dd9bfaf 100644 --- a/bin/SConsExamples.py +++ b/bin/SConsExamples.py @@ -1,7 +1,7 @@ # !/usr/bin/env python -# +# # Copyright (c) 2010 The SCons Foundation -# +# # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -9,10 +9,10 @@ # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: -# +# # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -21,18 +21,18 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# +# +# # This script looks for some XML tags that describe SCons example # configurations and commands to execute in those configurations, and # uses TestCmd.py to execute the commands and insert the output from # those commands into the XML that we output. This way, we can run a # script and update all of our example documentation output without # a lot of laborious by-hand checking. -# +# # An "SCons example" looks like this, and essentially describes a set of # input files (program source files as well as SConscript files): -# +# # # # env = Environment() @@ -42,7 +42,7 @@ # int main() { printf("foo.c\n"); } # # -# +# # The contents within the tag will get written # into a temporary directory whenever example output needs to be # generated. By default, the contents are not inserted into text @@ -50,41 +50,43 @@ # in which case they will get inserted within a tag. # This makes it easy to define the example at the appropriate # point in the text where you intend to show the SConstruct file. -# +# # Note that you should usually give the a "name" # attribute so that you can refer to the example configuration later to # run SCons and generate output. -# +# # If you just want to show a file's contents without worry about running # SCons, there's a shorter tag: -# +# # # env = Environment() # env.Program('foo') # -# +# # This is essentially equivalent to , # but it's more straightforward. -# +# # SCons output is generated from the following sort of tag: -# +# # # scons -Q foo # scons -Q foo # -# +# # You tell it which example to use with the "example" attribute, and then # give it a list of tags to execute. You can also # supply an "os" tag, which specifies the type of operating system this # example is intended to show; if you omit this, default value is "posix". -# +# # The generated XML will show the command line (with the appropriate # command-line prompt for the operating system), execute the command in # a temporary directory with the example files, capture the standard # output from SCons, and insert it into the text as appropriate. # Error output gets passed through to your error output so you # can see if there are any problems executing the command. -# +# + +from __future__ import print_function import os import re @@ -94,9 +96,9 @@ import time import SConsDoc from SConsDoc import tf as stf -# +# # The available types for ExampleFile entries -# +# FT_FILE = 0 # a physical file (=) FT_FILEREF = 1 # a reference (=) @@ -106,7 +108,7 @@ class ExampleFile: self.name = '' self.content = '' self.chmod = '' - + def isFileRef(self): return self.type == FT_FILEREF @@ -130,19 +132,19 @@ class ExampleOutput: self.preserve = None self.suffix = '' self.commands = [] - + class ExampleInfo: def __init__(self): self.name = '' self.files = [] self.folders = [] self.outputs = [] - + def getFileContents(self, fname): for f in self.files: if fname == f.name and not f.isFileRef(): return f.content - + return '' def readExampleInfos(fpath, examples): @@ -150,10 +152,10 @@ def readExampleInfos(fpath, examples): global dictionary examples. """ - # Create doctree + # Create doctree t = SConsDoc.SConsDocTree() t.parseXmlFile(fpath) - + # Parse scons_examples for e in stf.findAll(t.root, "scons_example", SConsDoc.dbxid, t.xpath_context, t.nsmap): @@ -164,7 +166,7 @@ def readExampleInfos(fpath, examples): i = ExampleInfo() i.name = n examples[n] = i - + # Parse file and directory entries for f in stf.findAll(e, "file", SConsDoc.dbxid, t.xpath_context, t.nsmap): @@ -199,8 +201,8 @@ def readExampleInfos(fpath, examples): fi.chmod = stf.getAttribute(f, 'chmod') fi.content = stf.getText(f) examples[e].files.append(fi) - - + + # Parse scons_output for o in stf.findAll(t.root, "scons_output", SConsDoc.dbxid, t.xpath_context, t.nsmap): @@ -238,7 +240,7 @@ def readExampleInfos(fpath, examples): examples[n].outputs.append(eout) def readAllExampleInfos(dpath): - """ Scan for XML files in the given directory and + """ Scan for XML files in the given directory and collect together all relevant infos (files/folders, output commands) in a map, which gets returned. """ @@ -249,13 +251,13 @@ def readAllExampleInfos(dpath): fpath = os.path.join(path, f) if SConsDoc.isSConsXml(fpath): readExampleInfos(fpath, examples) - + return examples generated_examples = os.path.join('doc', 'generated', 'examples') def ensureExampleOutputsExist(dpath): - """ Scan for XML files in the given directory and + """ Scan for XML files in the given directory and ensure that for every example output we have a corresponding output file in the 'generated/examples' folder. @@ -263,7 +265,7 @@ def ensureExampleOutputsExist(dpath): # Ensure that the output folder exists if not os.path.isdir(generated_examples): os.mkdir(generated_examples) - + examples = readAllExampleInfos(dpath) for key, value in examples.items(): # Process all scons_output tags @@ -276,7 +278,7 @@ def ensureExampleOutputsExist(dpath): stf.setText(s, "NO OUTPUT YET! Run the script to generate/update all examples.") # Write file stf.writeTree(s, cpath) - + # Process all scons_example_file tags for r in value.files: if r.isFileRef(): @@ -292,14 +294,14 @@ def ensureExampleOutputsExist(dpath): perc = "%" def createAllExampleOutputs(dpath): - """ Scan for XML files in the given directory and + """ Scan for XML files in the given directory and creates all output files for every example in the 'generated/examples' folder. """ # Ensure that the output folder exists if not os.path.isdir(generated_examples): os.mkdir(generated_examples) - + examples = readAllExampleInfos(dpath) total = len(examples) idx = 0 @@ -307,7 +309,7 @@ def createAllExampleOutputs(dpath): # Process all scons_output tags print("%.2f%s (%d/%d) %s" % (float(idx + 1) * 100.0 / float(total), perc, idx + 1, total, key)) - + create_scons_output(value) # Process all scons_example_file tags for r in value.files: @@ -329,10 +331,10 @@ def collectSConsExampleNames(fpath): suffixes = {} failed_suffixes = False - # Create doctree + # Create doctree t = SConsDoc.SConsDocTree() t.parseXmlFile(fpath) - + # Parse it for e in stf.findAll(t.root, "scons_example", SConsDoc.dbxid, t.xpath_context, t.nsmap): @@ -346,7 +348,7 @@ def collectSConsExampleNames(fpath): else: print("Error: Example in file '%s' is missing a name!" % fpath) failed_suffixes = True - + for o in stf.findAll(t.root, "scons_output", SConsDoc.dbxid, t.xpath_context, t.nsmap): n = '' @@ -355,29 +357,29 @@ def collectSConsExampleNames(fpath): else: print("Error: scons_output in file '%s' is missing an example name!" % fpath) failed_suffixes = True - + if n not in suffixes: print("Error: scons_output in file '%s' is referencing non-existent example '%s'!" % (fpath, n)) failed_suffixes = True continue - + s = '' if stf.hasAttribute(o, 'suffix'): s = stf.getAttribute(o, 'suffix') else: print("Error: scons_output in file '%s' (example '%s') is missing a suffix!" % (fpath, n)) failed_suffixes = True - + if s not in suffixes[n]: suffixes[n].append(s) else: print("Error: scons_output in file '%s' (example '%s') is using a duplicate suffix '%s'!" % (fpath, n, s)) failed_suffixes = True - + return names, failed_suffixes def exampleNamesAreUnique(dpath): - """ Scan for XML files in the given directory and + """ Scan for XML files in the given directory and check whether the scons_example names are unique. """ unique = True @@ -394,19 +396,19 @@ def exampleNamesAreUnique(dpath): if i: print("Not unique in %s are: %s" % (fpath, ', '.join(i))) unique = False - + allnames |= names - + return unique # ############################################################### -# +# # In the second half of this module (starting here) # we define the variables and functions that are required # to actually run the examples, collect their output and # write it into the files in doc/generated/examples... # which then get included by our UserGuide. -# +# # ############################################################### sys.path.append(os.path.join(os.getcwd(), 'QMTest')) @@ -430,7 +432,7 @@ Prompt = { } # The magick SCons hackery that makes this work. -# +# # So that our examples can still use the default SConstruct file, we # actually feed the following into SCons via stdin and then have it # SConscript() the SConstruct file. This stdin wrapper creates a set @@ -438,7 +440,7 @@ Prompt = { # Surrogates print output like the real tools and behave like them # without actually having to be on the right platform or have the right # tool installed. -# +# # The upshot: The wrapper transparently changes the world out from # under the top-level SConstruct file in an example just so we can get # the command output. @@ -765,7 +767,7 @@ def ExecuteCommand(args, c, t, dict): def create_scons_output(e): # The real raison d'etre for this script, this is where we # actually execute SCons to fetch the output. - + # Loop over all outputs for the example for o in e.outputs: # Create new test directory @@ -774,19 +776,19 @@ def create_scons_output(e): t.preserve() t.subdir('ROOT', 'WORK') t.rootpath = t.workpath('ROOT').replace('\\', '\\\\') - + for d in e.folders: dir = t.workpath('WORK', d.name) if not os.path.exists(dir): os.makedirs(dir) - + for f in e.files: if f.isFileRef(): continue - # + # # Left-align file's contents, starting on the first # non-empty line - # + # data = f.content.split('\n') i = 0 # Skip empty lines @@ -813,26 +815,26 @@ def create_scons_output(e): if hasattr(f, 'chmod'): if len(f.chmod): os.chmod(path, int(f.chmod, 0)) - + # Regular expressions for making the doc output consistent, # regardless of reported addresses or Python version. - + # Massage addresses in object repr strings to a constant. address_re = re.compile(r' at 0x[0-9a-fA-F]*\>') - + # Massage file names in stack traces (sometimes reported as absolute # paths) to a consistent relative path. engine_re = re.compile(r' File ".*/src/engine/SCons/') - + # Python 2.5 changed the stack trace when the module is read # from standard input from read "... line 7, in ?" to # "... line 7, in ". file_re = re.compile(r'^( *File ".*", line \d+, in) \?$', re.M) - + # Python 2.6 made UserList a new-style class, which changes the # AttributeError message generated by our NodeList subclass. nodelist_re = re.compile(r'(AttributeError:) NodeList instance (has no attribute \S+)') - + # Root element for our subtree sroot = stf.newEtreeNode("screen", True) curchild = None @@ -881,7 +883,7 @@ def create_scons_output(e): curchild.tail = content else: sroot.text = content - + # Construct filename fpath = os.path.join(generated_examples, e.name + '_' + o.suffix + '.xml') diff --git a/bin/memlogs.py b/bin/memlogs.py index 6e68ce0..b450939 100644 --- a/bin/memlogs.py +++ b/bin/memlogs.py @@ -20,7 +20,8 @@ # 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 print_function + +from __future__ import print_function import getopt import sys diff --git a/bin/memoicmp.py b/bin/memoicmp.py index 1106ac3..7f0369e 100644 --- a/bin/memoicmp.py +++ b/bin/memoicmp.py @@ -2,7 +2,8 @@ # # A script to compare the --debug=memoizer output found in # two different files. -from future import print_function + +from __future__ import print_function import sys @@ -46,7 +47,7 @@ def memoize_cmp(filea, fileb): mab.sort() ma_o.sort() mb_o.sort() - + for k in mab: hits = cfmt%(ma[k][0], mb[k][0], mb[k][0]-ma[k][0]) miss = cfmt%(ma[k][1], mb[k][1], mb[k][1]-ma[k][1]) @@ -63,7 +64,7 @@ def memoize_cmp(filea, fileb): print('%-24s %-24s %s'%(hits, miss, k)) print('-'*(24+24+1+20)) - + if __name__ == "__main__": if len(sys.argv) != 3: diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index d11f30d..a4e75f3 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -101,7 +101,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import dis import os -# compat layer imports "cPickle" for us if it's available. import pickle import re import sys @@ -272,7 +271,7 @@ def _function_contents(func): contents.append(b',()') # The function contents depends on the closure captured cell values. - closure = func.func_closure or [] + closure = func.__closure__ or [] #xxx = [_object_contents(x.cell_contents) for x in closure] try: diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 99d169a..4b57763 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -1868,7 +1869,7 @@ def generate(env): # test for pull request #150 env = self.TestEnvironment() env._dict.pop('BUILDERS') - assert env.has_key('BUILDERS') is False + assert ('BUILDERS' in env) is False env2 = env.Clone() def test_Copy(self): diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 85e30c2..1a76b60 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -19,6 +19,8 @@ be able to depend on any other type of "thing." """ +from __future__ import print_function + # # __COPYRIGHT__ # @@ -151,7 +153,7 @@ def exists_file(node): # The source file does not exist. Make sure no old # copy remains in the variant directory. if print_duplicate: - print "dup: no src for %s, unlinking old variant copy"%self + print("dup: no src for %s, unlinking old variant copy"%self) if exists_base(node) or node.islink(): node.fs.unlink(node.get_internal_path()) # Return None explicitly because the Base.exists() call @@ -205,13 +207,13 @@ def get_contents_dir(node): contents.append('%s %s\n' % (n.get_csig(), n.name)) return ''.join(contents) -def get_contents_file(node): +def get_contents_file(node): if not node.rexists(): return '' fname = node.rfile().get_abspath() try: contents = open(fname, "rb").read() - except EnvironmentError, e: + except EnvironmentError as e: if not e.filename: e.filename = fname raise @@ -407,21 +409,21 @@ class NodeInfoBase(object): for name in getattr(obj,'__slots__',()): if hasattr(self, name): state[name] = getattr(self, name) - + state['_version_id'] = self.current_version_id try: del state['__weakref__'] except KeyError: pass return state - + def __setstate__(self, state): """ Restore the attributes from a pickled state. The version is discarded. """ # TODO check or discard version del state['_version_id'] - + for key, value in state.items(): if key not in ('__weakref__',): setattr(self, key, value) @@ -456,7 +458,7 @@ class BuildInfoBase(object): """ state = other.__getstate__() self.__setstate__(state) - + def __getstate__(self): """ Return all fields that shall be pickled. Walk the slots in the class @@ -536,7 +538,7 @@ class Node(object): class Attrs(object): __slots__ = ('shared', '__dict__') - + def __init__(self): if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node') @@ -588,7 +590,7 @@ class Node(object): self._func_rexists = 1 self._func_get_contents = 0 self._func_target_from_source = 0 - + self.clear_memoized_values() # Let the interface in which the build engine is embedded @@ -776,16 +778,16 @@ class Node(object): def release_target_info(self): """Called just after this node has been marked up-to-date or was built completely. - + This is where we try to release as many target node infos as possible for clean builds and update runs, in order to minimize the overall memory consumption. - + By purging attributes that aren't needed any longer after a Node (=File) got built, we don't have to care that much how many KBytes a Node actually requires...as long as we free the memory shortly afterwards. - + @see: built() and File.release_target_info() """ pass @@ -934,7 +936,7 @@ class Node(object): node = nodes.pop(0) scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw) - + if not scanner: continue @@ -958,14 +960,14 @@ class Node(object): else: # handle explicit scanner case scanner = initial_scanner.select(self) - + if not scanner: # no scanner could be found for the given node's scanner key; # thus, make an attempt at using a default. scanner = root_node_scanner - + return scanner - + def get_env_scanner(self, env, kw={}): return env.get_scanner(self.scanner_key()) @@ -1422,14 +1424,14 @@ class Node(object): any difference, but we now rely on checking every dependency to make sure that any necessary Node information (for example, the content signature of an #included .h file) is updated. - + The allowcache option was added for supporting the early release of the executor/builder structures, right after a File target was built. When set to true, the return value of this changed method gets cached for File nodes. Like this, the executor isn't needed any longer for subsequent calls to changed(). - + @see: FS.File.changed(), FS.File.release_target_info() """ t = 0 diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 71d64fc..7cc7d47 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,6 +10,8 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ +from __future__ import print_function + unsupported_python_version = (2, 6, 0) deprecated_python_version = (2, 7, 0) @@ -354,13 +356,13 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): for t in self._get_files_to_clean(): try: removed = t.remove() - except OSError, e: + except OSError as e: # An OSError may indicate something like a permissions # issue, an IOError would indicate something like # the file not existing. In either case, print a # message and keep going to try to remove as many # targets as possible. - print("scons: Could not remove '{}':".format(str(t)), e.strerror) + print(("scons: Could not remove '{}':".format(str(t)), e.strerror)) else: if removed: display("Removed " + str(t)) diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index ab032be..6480ace 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -5,6 +5,8 @@ files. """ +from __future__ import print_function + # # __COPYRIGHT__ # @@ -68,7 +70,7 @@ def get_calling_namespaces(): """Return the locals and globals for the function that called into this module in the current call stack.""" try: 1//0 - except ZeroDivisionError: + except ZeroDivisionError: # Don't start iterating with the current stack-frame to # prevent creating reference cycles (f_back is safe). frame = sys.exc_info()[2].tb_frame.f_back diff --git a/src/engine/SCons/Tool/cyglink.py b/src/engine/SCons/Tool/cyglink.py index 2f54a17..f69b886 100644 --- a/src/engine/SCons/Tool/cyglink.py +++ b/src/engine/SCons/Tool/cyglink.py @@ -7,6 +7,9 @@ It will usually be imported through the generic SCons.Tool.Tool() selection method. """ + +from __future__ import absolute_import, print_function + import re import os @@ -15,8 +18,8 @@ import SCons.Util import SCons.Tool #MAYBE: from . import gnulink -import gnulink -import link +from . import gnulink +from . import link def _lib_generator(target, source, env, for_signature, **kw): try: cmd = kw['cmd'] @@ -59,7 +62,7 @@ def _lib_emitter(target, source, env, **kw): Verbose = False if Verbose: - print "_lib_emitter: target[0]=%r" % target[0].get_path() + print("_lib_emitter: target[0]=%r" % target[0].get_path()) try: vp = kw['varprefix'] except KeyError: vp = 'SHLIB' @@ -71,7 +74,7 @@ def _lib_emitter(target, source, env, **kw): no_import_lib = env.get('no_import_lib', 0) if Verbose: - print "_lib_emitter: dll=%r" % dll.get_path() + print("_lib_emitter: dll=%r" % dll.get_path()) if not dll or len(target) > 1: raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$%sSUFFIX" % vp)) @@ -82,14 +85,14 @@ def _lib_emitter(target, source, env, **kw): dll.name = pre + dll.name[len(pre)+3:] if Verbose: - print "_lib_emitter: dll.name=%r" % dll.name + print("_lib_emitter: dll.name=%r" % dll.name) orig_target = target target = [env.fs.File(dll)] target[0].attributes.shared = 1 if Verbose: - print "_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path() + print("_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path()) # Append an import lib target if not no_import_lib: @@ -98,11 +101,11 @@ def _lib_emitter(target, source, env, **kw): '%sPREFIX' % vp, '%sSUFFIX' % vp, 'IMPLIBPREFIX', 'IMPLIBSUFFIX') if Verbose: - print "_lib_emitter: target_strings=%r" % target_strings + print("_lib_emitter: target_strings=%r" % target_strings) implib_target = env.fs.File(target_strings) if Verbose: - print "_lib_emitter: implib_target=%r" % implib_target.get_path() + print("_lib_emitter: implib_target=%r" % implib_target.get_path()) implib_target.attributes.shared = 1 target.append(implib_target) @@ -110,7 +113,7 @@ def _lib_emitter(target, source, env, **kw): implib_libtype=libtype, generator_libtype=libtype+'ImpLib') if Verbose: - print "_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) + print("_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks)) if symlinks: SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target, clean_targets = target[0]) implib_target.attributes.shliblinks = symlinks @@ -128,13 +131,13 @@ def _versioned_lib_suffix(env, suffix, version): If suffix='.dll', and version='0.1.2', then it returns '-0-1-2.dll'""" Verbose = False if Verbose: - print "_versioned_lib_suffix: suffix= ", suffix - print "_versioned_lib_suffix: version= ", version + print("_versioned_lib_suffix: suffix= ", suffix) + print("_versioned_lib_suffix: version= ", version) cygversion = re.sub('\.', '-', version) if not suffix.startswith('-' + cygversion): suffix = '-' + cygversion + suffix if Verbose: - print "_versioned_lib_suffix: return suffix= ", suffix + print("_versioned_lib_suffix: return suffix= ", suffix) return suffix def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw): @@ -150,8 +153,8 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): Verbose = False if Verbose: - print "_versioned_implib_symlinks: libnode=%r" % libnode.get_path() - print "_versioned_implib_symlinks: version=%r" % version + print("_versioned_implib_symlinks: libnode=%r" % libnode.get_path()) + print("_versioned_implib_symlinks: version=%r" % version) try: libtype = kw['libtype'] except KeyError: libtype = 'ShLib' @@ -159,13 +162,13 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): linkdir = os.path.dirname(libnode.get_path()) if Verbose: - print "_versioned_implib_symlinks: linkdir=%r" % linkdir + print("_versioned_implib_symlinks: linkdir=%r" % linkdir) name = SCons.Tool.ImpLibNameGenerator(env, libnode, implib_libtype=libtype, generator_libtype=libtype+'ImpLib') if Verbose: - print "_versioned_implib_symlinks: name=%r" % name + print("_versioned_implib_symlinks: name=%r" % name) major = version.split('.')[0] @@ -173,7 +176,7 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): symlinks = [(link0, libnode)] if Verbose: - print "_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks) + print("_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks)) return symlinks diff --git a/src/engine/SCons/Tool/f08.py b/src/engine/SCons/Tool/f08.py index a45a61d..7fa5872 100644 --- a/src/engine/SCons/Tool/f08.py +++ b/src/engine/SCons/Tool/f08.py @@ -8,6 +8,8 @@ selection method. """ +from __future__ import absolute_import + # # __COPYRIGHT__ # @@ -36,7 +38,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Defaults import SCons.Tool import SCons.Util -import fortran +from . import fortran from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env compilers = ['f08'] diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index efdc8a1..c3c8164 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -29,6 +29,7 @@ selection method. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -39,7 +40,6 @@ import base64 import hashlib import ntpath import os -# compat layer imports "cPickle" for us if it's available. import pickle import re import sys @@ -71,7 +71,7 @@ def xmlify(s): # Returns a tuple of nodes. def processIncludes(includes, env, target, source): return SCons.PathList.PathList(includes).subst_path(env, target, source) - + external_makefile_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' @@ -169,15 +169,15 @@ class _UserGenerator(object): Base class for .dsp.user file generator ''' # Default instance values. - # Ok ... a bit defensive, but it does not seem reasonable to crash the + # Ok ... a bit defensive, but it does not seem reasonable to crash the # build for a workspace user file. :-) usrhead = None - usrdebg = None + usrdebg = None usrconf = None - createfile = False + createfile = False def __init__(self, dspfile, source, env): # DebugSettings should be a list of debug dictionary sorted in the same order - # as the target list and variants + # as the target list and variants if 'variant' not in env: raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\ "'Release') to create an MSVSProject.") @@ -185,7 +185,7 @@ class _UserGenerator(object): variants = [env['variant']] elif SCons.Util.is_List(env['variant']): variants = env['variant'] - + if 'DebugSettings' not in env or env['DebugSettings'] == None: dbg_settings = [] elif SCons.Util.is_Dict(env['DebugSettings']): @@ -201,12 +201,12 @@ class _UserGenerator(object): dbg_settings.append({}) else: dbg_settings = [] - + if len(dbg_settings) == 1: dbg_settings = dbg_settings * len(variants) - + self.createfile = self.usrhead and self.usrdebg and self.usrconf and \ - dbg_settings and bool([ds for ds in dbg_settings if ds]) + dbg_settings and bool([ds for ds in dbg_settings if ds]) if self.createfile: dbg_settings = dict(zip(variants, dbg_settings)) @@ -216,22 +216,22 @@ class _UserGenerator(object): for key in [k for k in self.usrdebg.keys() if k in src]: trg[key] = str(src[key]) self.configs[var].debug = trg - + def UserHeader(self): encoding = self.env.subst('$MSVSENCODING') versionstr = self.versionstr self.usrfile.write(self.usrhead % locals()) - + def UserProject(self): pass - + def Build(self): if not self.createfile: return try: filename = self.dspabs +'.user' self.usrfile = open(filename, 'w') - except IOError, detail: + except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + filename + '" for writing:' + str(detail)) else: self.UserHeader() @@ -291,7 +291,7 @@ class _GenerateV7User(_UserGenerator): self.usrconf = V9UserConfiguration self.usrdebg = V9DebugSettings _UserGenerator.__init__(self, dspfile, source, env) - + def UserProject(self): confkeys = sorted(self.configs.keys()) for kind in confkeys: @@ -299,8 +299,8 @@ class _GenerateV7User(_UserGenerator): platform = self.configs[kind].platform debug = self.configs[kind].debug if debug: - debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) - for key, value in debug.items() + debug_settings = '\n'.join(['\t\t\t\t%s="%s"' % (key, xmlify(value)) + for key, value in debug.items() if value is not None]) self.usrfile.write(self.usrconf % locals()) self.usrfile.write('\t\n') @@ -346,7 +346,7 @@ V10DebugSettings = { class _GenerateV10User(_UserGenerator): """Generates a Project'user file for MSVS 2010""" - + def __init__(self, dspfile, source, env): self.versionstr = '4.0' self.usrhead = V10UserHeader @@ -361,8 +361,8 @@ class _GenerateV10User(_UserGenerator): platform = self.configs[kind].platform debug = self.configs[kind].debug if debug: - debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) - for key, value in debug.items() + debug_settings = '\n'.join(['\t\t<%s>%s' % (key, xmlify(value), key) + for key, value in debug.items() if value is not None]) self.usrfile.write(self.usrconf % locals()) self.usrfile.write('') @@ -458,7 +458,7 @@ class _DSPGenerator(object): runfile.append(s) self.sconscript = env['MSVSSCONSCRIPT'] - + if 'cmdargs' not in env or env['cmdargs'] == None: cmdargs = [''] * len(variants) elif SCons.Util.is_String(env['cmdargs']): @@ -468,7 +468,7 @@ class _DSPGenerator(object): raise SCons.Errors.InternalError("Sizes of 'cmdargs' and 'variant' lists must be the same.") else: cmdargs = env['cmdargs'] - + self.env = env if 'name' in self.env: @@ -550,16 +550,16 @@ V6DSPHeader = """\ CFG=%(name)s - Win32 %(confkey)s !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "%(name)s.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "%(name)s.mak" CFG="%(name)s - Win32 %(confkey)s" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE """ class _GenerateV6DSP(_DSPGenerator): @@ -818,7 +818,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.dspheader = V7DSPHeader self.dspconfiguration = V7DSPConfiguration self.file = None - + _GenerateV7User.__init__(self, dspfile, source, env) def PrintHeader(self): @@ -895,7 +895,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): preprocdefs = xmlify(';'.join(processDefines(self.env.get('CPPDEFINES', [])))) includepath_Dirs = processIncludes(self.env.get('CPPPATH', []), self.env, None, None) includepath = xmlify(';'.join([str(x) for x in includepath_Dirs])) - + if not env_has_buildtarget: del self.env['MSVSBUILDTARGET'] @@ -1044,7 +1044,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.PrintHeader() self.PrintProject() self.file.close() - + _GenerateV7User.Build(self) V10DSPHeader = """\ @@ -1101,7 +1101,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): self.dspheader = V10DSPHeader self.dspconfiguration = V10DSPProjectConfiguration self.dspglobals = V10DSPGlobals - + _GenerateV10User.__init__(self, dspfile, source, env) def PrintHeader(self): @@ -1132,27 +1132,27 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t%s\n' % (scc_project_name, scc_local_path_legacy)) else: self.dspglobals = self.dspglobals.replace('%(scc_attrs)s', '') - + self.file.write(self.dspheader % locals()) - + self.file.write('\t\n') - + confkeys = sorted(self.configs.keys()) for kind in confkeys: variant = self.configs[kind].variant platform = self.configs[kind].platform self.file.write(self.dspconfiguration % locals()) - + self.file.write('\t\n') - + self.file.write(self.dspglobals % locals()) - + def PrintProject(self): name = self.name confkeys = sorted(self.configs.keys()) - + self.file.write('\t\n') - + toolset = '' if 'MSVC_VERSION' in self.env: version_num, suite = msvs_parse_version(self.env['MSVC_VERSION']) @@ -1165,16 +1165,16 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): self.file.write('\t\n') self.file.write('\t\n') self.file.write('\t\n') - + for kind in confkeys: variant = self.configs[kind].variant platform = self.configs[kind].platform self.file.write(V10DSPImportGroupCondition % locals()) - + self.file.write('\t\n') self.file.write('\t\n') self.file.write('\t<_ProjectFileVersion>10.0.30319.1\n') - + for kind in confkeys: variant = self.configs[kind].variant platform = self.configs[kind].platform @@ -1182,7 +1182,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): buildtarget = self.configs[kind].buildtarget runfile = self.configs[kind].runfile cmdargs = self.configs[kind].cmdargs - + env_has_buildtarget = 'MSVSBUILDTARGET' in self.env if not env_has_buildtarget: self.env['MSVSBUILDTARGET'] = buildtarget @@ -1207,29 +1207,29 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): del self.env['MSVSBUILDTARGET'] self.file.write(V10DSPCommandLine % locals()) - + self.file.write('\t\n') - + #filter settings in MSVS 2010 are stored in separate file self.filtersabs = self.dspabs + '.filters' try: self.filters_file = open(self.filtersabs, 'w') except IOError as detail: raise SCons.Errors.InternalError('Unable to open "' + self.filtersabs + '" for writing:' + str(detail)) - + self.filters_file.write('\n' '\n') - + self.PrintSourceFiles() - + self.filters_file.write('') self.filters_file.close() - + self.file.write('\t\n' '\t\n' '\t\n' '\n') - + if self.nokeep == 0: # now we pickle some data and add it to the file -- MSDEV will ignore it. pdata = pickle.dumps(self.configs,1) @@ -1241,7 +1241,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): def printFilters(self, hierarchy, name): sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) - + for key, value in sorteditems: if SCons.Util.is_Dict(value): filter_name = name + '\\' + key @@ -1249,14 +1249,14 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\t%s\n' '\t\t\n' % (filter_name, _generateGUID(self.dspabs, filter_name))) self.printFilters(value, filter_name) - + def printSources(self, hierarchy, kind, commonprefix, filter_name): keywords = {'Source Files': 'ClCompile', 'Header Files': 'ClInclude', 'Local Headers': 'ClInclude', 'Resource Files': 'None', 'Other Files': 'None'} - + sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) # First folders, then files @@ -1270,7 +1270,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): if commonprefix: file = os.path.join(commonprefix, value) file = os.path.normpath(file) - + self.file.write('\t\t<%s Include="%s" />\n' % (keywords[kind], file)) self.filters_file.write('\t\t<%s Include="%s">\n' '\t\t\t%s\n' @@ -1282,10 +1282,10 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): 'Local Headers': 'h;hpp;hxx;hm;inl', 'Resource Files': 'r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe', 'Other Files': ''} - + cats = sorted([k for k in categories.keys() if self.sources[k]], key = lambda a: a.lower()) - + # print vcxproj.filters file first self.filters_file.write('\t\n') for kind in cats: @@ -1293,7 +1293,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\t{7b42d31d-d53c-4868-8b92-ca2bc9fc052f}\n' '\t\t\t%s\n' '\t\t\n' % (kind, categories[kind])) - + # First remove any common prefix sources = self.sources[kind] commonprefix = None @@ -1306,17 +1306,17 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): # +1 because the filename starts after the separator sources = [s[len(cp)+1:] for s in sources] commonprefix = cp - + hierarchy = makeHierarchy(sources) self.printFilters(hierarchy, kind) - + self.filters_file.write('\t\n') - + # then print files and filters for kind in cats: self.file.write('\t\n') self.filters_file.write('\t\n') - + # First remove any common prefix sources = self.sources[kind] commonprefix = None @@ -1329,13 +1329,13 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): # +1 because the filename starts after the separator sources = [s[len(cp)+1:] for s in sources] commonprefix = cp - + hierarchy = makeHierarchy(sources) self.printSources(hierarchy, kind, commonprefix, kind) - + self.file.write('\t\n') self.filters_file.write('\t\n') - + # add the SConscript file outside of the groups self.file.write('\t\n' '\t\t\n' @@ -1354,7 +1354,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): self.PrintHeader() self.PrintProject() self.file.close() - + _GenerateV10User.Build(self) class _DSWGenerator(object): @@ -1462,7 +1462,7 @@ class _GenerateV7DSW(_DSWGenerator): 'SLN_RELATIVE_FOLDER_PATH': dsp_relative_folder_path, 'SLN_RELATIVE_FILE_PATH': dsp_relative_file_path} self.dspfiles_info.append(dspfile_info) - + self.dspfiles_info = [] GenerateProjectFilesInfo(self) @@ -1508,7 +1508,7 @@ class _GenerateV7DSW(_DSWGenerator): self.file.write('# Visual Studio 2008\n') elif self.version_num >= 8.0: self.file.write('# Visual Studio 2005\n') - + for dspinfo in self.dspfiles_info: name = dspinfo['NAME'] base, suffix = SCons.Util.splitext(name) @@ -1970,7 +1970,7 @@ def generate(env): else: env['MSVS']['PROJECTSUFFIX'] = '.vcxproj' env['MSVS']['SOLUTIONSUFFIX'] = '.sln' - + if (version_num >= 10.0): env['MSVSENCODING'] = 'utf-8' else: diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py index 9d1965d..fa86174 100644 --- a/src/engine/SCons/Tool/swig.py +++ b/src/engine/SCons/Tool/swig.py @@ -7,6 +7,7 @@ It will usually be imported through the generic SCons.Tool.Tool() selection method. """ +from __future__ import print_function # # __COPYRIGHT__ @@ -144,10 +145,10 @@ def _get_swig_version(env, swig): out = pipe.stdout.read() match = re.search(r'SWIG Version\s+(\S+).*', out, re.MULTILINE) if match: - if verbose: print "Version is:%s"%match.group(1) + if verbose: print("Version is:%s"%match.group(1)) return match.group(1) else: - if verbose: print "Unable to detect version: [%s]"%out + if verbose: print("Unable to detect version: [%s]"%out) def generate(env): """Add Builders and construction variables for swig to an Environment.""" diff --git a/src/engine/SCons/compat/six.py b/src/engine/SCons/compat/six.py index 019130f..0e8850c 100755 --- a/src/engine/SCons/compat/six.py +++ b/src/engine/SCons/compat/six.py @@ -43,7 +43,7 @@ if PY3: else: string_types = basestring, integer_types = (int, long) - class_types = (type, types.ClassType) + class_types = (type, type) text_type = unicode binary_type = str @@ -462,7 +462,7 @@ if PY3: Iterator = object else: def get_unbound_function(unbound): - return unbound.im_func + return unbound.__func__ def create_bound_method(func, obj): return types.MethodType(func, obj, obj.__class__) diff --git a/src/engine/SCons/compat/sixTests.py b/src/engine/SCons/compat/sixTests.py index f8c1979..71df78d 100644 --- a/src/engine/SCons/compat/sixTests.py +++ b/src/engine/SCons/compat/sixTests.py @@ -1,3 +1,4 @@ +from __future__ import print_function # # __COPYRIGHT__ # @@ -28,7 +29,7 @@ class sixTestCase(unittest.TestCase): def test_import(self): """Test that six imports correctly.""" import sys - print sys.path + print(sys.path) from SCons.compat.six import PY2, PY3 self.assertTrue(PY2 or PY3) diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 9f4b875..28a1f5e 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -21,6 +21,8 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +from __future__ import absolute_import + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import atexit @@ -29,7 +31,7 @@ import unittest import TestUnit -import cpp +from . import cpp diff --git a/src/script/scons.py b/src/script/scons.py index b5476b9..0595717 100644 --- a/src/script/scons.py +++ b/src/script/scons.py @@ -23,6 +23,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 print_function + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" __version__ = "__VERSION__" diff --git a/src/setup.py b/src/setup.py index c036fb0..9a02b25 100644 --- a/src/setup.py +++ b/src/setup.py @@ -32,6 +32,8 @@ NOTE: Installed SCons is not importable like usual Python packages. It is below is dedicated to make it happen on various platforms. """ +from __future__ import print_function + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import os diff --git a/src/test_interrupts.py b/src/test_interrupts.py index de3a0db..b81ef3f 100644 --- a/src/test_interrupts.py +++ b/src/test_interrupts.py @@ -21,6 +21,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 print_function + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ diff --git a/test/LINK/VersionedLib.py b/test/LINK/VersionedLib.py index 3f4a912..468e3e5 100644 --- a/test/LINK/VersionedLib.py +++ b/test/LINK/VersionedLib.py @@ -1,286 +1,288 @@ -#!/usr/bin/env python -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" - -import os -import sys -import TestSCons - -import SCons.Platform -import SCons.Defaults - -env = SCons.Defaults.DefaultEnvironment() -platform = SCons.Platform.platform_default() -tool_list = SCons.Platform.DefaultToolList(platform, env) - -if 'gnulink' in tool_list: - test_plan = [ - { - 'libversion' : '2', - 'files' : [ 'libtest.so', 'libtest.so.2', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], - }, - { - 'libversion' : '2.5', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], - }, - { - 'libversion' : '2.5.4', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], - }, - { - 'libversion' : '2.5.4.7.8', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], - }, - { - 'libversion' : 'aabf114f', - 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], - }, - { - 'libversion' : '2.dfffa11', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], - }, - ] -elif 'applelink' in tool_list: - # All (?) the files we expect will get created in the current directory - test_plan = [ - { - 'libversion' : '2.5.4', - 'files' : [ 'libtest.dylib', 'libtest.2.5.4.dylib', 'test.os' ], - 'instfiles' : [ 'libtest.dylib', 'libtest.2.5.4.dylib' ], - 'symlinks' : [], - }, - ] -elif 'cyglink' in tool_list: - test_plan = [ - { - 'libversion' : '2', - 'files' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-2.dll.a') ], - }, - { - 'libversion' : '2.5', - 'files' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5.dll.a') ], - }, - { - 'libversion' : '2.5.4', - 'files' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4.dll.a') ], - }, - { - 'libversion' : '2.5.4.7.8', - 'files' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4-7-8.dll.a') ], - }, - { - 'libversion' : 'aabf114f', - 'files' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-aabf114f.dll.a') ], - }, - { - 'libversion' : '2.dfffa11', - 'files' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a', 'test.os' ], - 'instfiles' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a' ], - 'symlinks' : [ ('libtest.dll.a', 'libtest-2-dfffa11.dll.a') ], - }, - ] -elif 'mslink' in tool_list: - test_plan = [ - { - 'libversion' : '2.5.4', - 'files' : [ 'test.dll', 'test.lib', 'test.obj' ], - 'instfiles' : [ 'test.dll', 'test.lib' ], - 'symlinks' : [], - }, - ] -elif 'sunlink' in tool_list: - test_plan = [ - { - 'libversion' : '2', - 'files' : [ 'libtest.so', 'libtest.so.2', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], - }, - { - 'libversion' : '2.5', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], - }, - { - 'libversion' : '2.5.4', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], - }, - { - 'libversion' : '2.5.4.7.8', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], - }, - { - 'libversion' : 'aabf114f', - 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], - }, - { - 'libversion' : '2.dfffa11', - 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'so_test.os' ], - 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], - 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], - }, - ] -else: - test_plan = [ - { - 'libversion' : '2.5.4', - 'files' : [ 'libtest.so', 'test.os' ], - 'instfiles' : [ ], - }, - ] - -test_c_src = """\ -#if _WIN32 -__declspec(dllexport) -#endif -int testlib(int n) { return n+1 ; } -""" - -test_c_src2 = """\ -#if _WIN32 -__declspec(dllexport) -#endif -int testlib(int n) { return n+11 ; } -""" - -testapp_c_src = """\ -#if _WIN32 -__declspec(dllimport) -#endif -int testlib(int n); -#include -int main(int argc, char **argv) -{ -int itest ; - -itest = testlib(2) ; -printf("results: testlib(2) = %d\\n",itest) ; -return 0 ; -} -""" - -for t in test_plan: - - test = TestSCons.TestSCons() - - libversion = t['libversion'] - files = t['files'] - symlinks = t['symlinks'] - instfiles = t['instfiles'] - - test.write('SConstruct', """\ -import os -env = Environment() -objs = env.SharedObject('test.c') -mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '%s') -env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') -env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') -instnode = env.InstallVersionedLib("#/installtest",mylib) -env.Default(instnode) - -# Extra test to ensure that InstallVersionedLib can be called from the DefaultEnvironment -# Ensures orthogonality where InstallVersionedLib wasn't previously available: SCons gave NameError. -instnode = InstallVersionedLib("defaultenv-installtest",mylib) -Default(instnode) - -""" % libversion) - - test.write('test.c', test_c_src) - test.write('testapp1.c', testapp_c_src) - test.write('testapp2.c', testapp_c_src) - - test.run(arguments = ['--tree=all']) - - for f in files: - test.must_exist([ f]) - for f in instfiles: - test.must_exist(['installtest', f]) - test.must_exist(['defaultenv-installtest', f]) - - wrong_symlinks = [] - for (linkname,expected) in symlinks: - try: - endpoint = os.readlink(linkname) - except OSError, err: - print "%s (expected symlink %r -> %r)" % (err, linkname, expected) - wrong_symlinks.append(linkname) - else: - if endpoint != expected: - print "Wrong symlink: %r -> %r (expected symlink: %r -> %r)" % (linkname, endpoint, linkname, expected) - wrong_symlinks.append(linkname) - - if wrong_symlinks: - test.fail_test(wrong_symlinks) - - # modify test.c and make sure it can recompile when links already exist - test.write('test.c', test_c_src2) - - test.run() - - test.run(arguments = ['-c']) - - for f in files: - test.must_not_exist([ f]) - - for f in instfiles: - test.must_not_exist(['installtest', f]) - test.must_not_exist(['defaultenv-installtest', f]) - -test.pass_test() - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: +#!/usr/bin/env python +# +# __COPYRIGHT__ +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +from __future__ import print_function + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os +import sys +import TestSCons + +import SCons.Platform +import SCons.Defaults + +env = SCons.Defaults.DefaultEnvironment() +platform = SCons.Platform.platform_default() +tool_list = SCons.Platform.DefaultToolList(platform, env) + +if 'gnulink' in tool_list: + test_plan = [ + { + 'libversion' : '2', + 'files' : [ 'libtest.so', 'libtest.so.2', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], + }, + ] +elif 'applelink' in tool_list: + # All (?) the files we expect will get created in the current directory + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.dylib', 'libtest.2.5.4.dylib', 'test.os' ], + 'instfiles' : [ 'libtest.dylib', 'libtest.2.5.4.dylib' ], + 'symlinks' : [], + }, + ] +elif 'cyglink' in tool_list: + test_plan = [ + { + 'libversion' : '2', + 'files' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2.dll', 'libtest-2.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2.dll.a') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5.dll', 'libtest-2-5.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5.dll.a') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5-4.dll', 'libtest-2-5-4.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4.dll.a') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-5-4-7-8.dll', 'libtest-2-5-4-7-8.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-5-4-7-8.dll.a') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-aabf114f.dll', 'libtest-aabf114f.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-aabf114f.dll.a') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a', 'test.os' ], + 'instfiles' : [ 'cygtest-2-dfffa11.dll', 'libtest-2-dfffa11.dll.a', 'libtest.dll.a' ], + 'symlinks' : [ ('libtest.dll.a', 'libtest-2-dfffa11.dll.a') ], + }, + ] +elif 'mslink' in tool_list: + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'test.dll', 'test.lib', 'test.obj' ], + 'instfiles' : [ 'test.dll', 'test.lib' ], + 'symlinks' : [], + }, + ] +elif 'sunlink' in tool_list: + test_plan = [ + { + 'libversion' : '2', + 'files' : [ 'libtest.so', 'libtest.so.2', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2') ], + }, + { + 'libversion' : '2.5', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5'), ('libtest.so.2', 'libtest.so.2.5') ], + }, + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4'), ('libtest.so.2', 'libtest.so.2.5.4') ], + }, + { + 'libversion' : '2.5.4.7.8', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.5.4.7.8' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.5.4.7.8'), ('libtest.so.2', 'libtest.so.2.5.4.7.8') ], + }, + { + 'libversion' : 'aabf114f', + 'files' : [ 'libtest.so', 'libtest.so.aabf114f', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.aabf114f' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.aabf114f') ], + }, + { + 'libversion' : '2.dfffa11', + 'files' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11', 'so_test.os' ], + 'instfiles' : [ 'libtest.so', 'libtest.so.2', 'libtest.so.2.dfffa11' ], + 'symlinks' : [ ('libtest.so', 'libtest.so.2.dfffa11'), ('libtest.so.2', 'libtest.so.2.dfffa11') ], + }, + ] +else: + test_plan = [ + { + 'libversion' : '2.5.4', + 'files' : [ 'libtest.so', 'test.os' ], + 'instfiles' : [ ], + }, + ] + +test_c_src = """\ +#if _WIN32 +__declspec(dllexport) +#endif +int testlib(int n) { return n+1 ; } +""" + +test_c_src2 = """\ +#if _WIN32 +__declspec(dllexport) +#endif +int testlib(int n) { return n+11 ; } +""" + +testapp_c_src = """\ +#if _WIN32 +__declspec(dllimport) +#endif +int testlib(int n); +#include +int main(int argc, char **argv) +{ +int itest ; + +itest = testlib(2) ; +printf("results: testlib(2) = %d\\n",itest) ; +return 0 ; +} +""" + +for t in test_plan: + + test = TestSCons.TestSCons() + + libversion = t['libversion'] + files = t['files'] + symlinks = t['symlinks'] + instfiles = t['instfiles'] + + test.write('SConstruct', """\ +import os +env = Environment() +objs = env.SharedObject('test.c') +mylib = env.SharedLibrary('test', objs, SHLIBVERSION = '%s') +env.Program('testapp1.c', LIBS = mylib, LIBPATH='.') +env.Program('testapp2.c', LIBS = ['test'], LIBPATH='.') +instnode = env.InstallVersionedLib("#/installtest",mylib) +env.Default(instnode) + +# Extra test to ensure that InstallVersionedLib can be called from the DefaultEnvironment +# Ensures orthogonality where InstallVersionedLib wasn't previously available: SCons gave NameError. +instnode = InstallVersionedLib("defaultenv-installtest",mylib) +Default(instnode) + +""" % libversion) + + test.write('test.c', test_c_src) + test.write('testapp1.c', testapp_c_src) + test.write('testapp2.c', testapp_c_src) + + test.run(arguments = ['--tree=all']) + + for f in files: + test.must_exist([ f]) + for f in instfiles: + test.must_exist(['installtest', f]) + test.must_exist(['defaultenv-installtest', f]) + + wrong_symlinks = [] + for (linkname,expected) in symlinks: + try: + endpoint = os.readlink(linkname) + except OSError as err: + print("%s (expected symlink %r -> %r)" % (err, linkname, expected)) + wrong_symlinks.append(linkname) + else: + if endpoint != expected: + print("Wrong symlink: %r -> %r (expected symlink: %r -> %r)" % (linkname, endpoint, linkname, expected)) + wrong_symlinks.append(linkname) + + if wrong_symlinks: + test.fail_test(wrong_symlinks) + + # modify test.c and make sure it can recompile when links already exist + test.write('test.c', test_c_src2) + + test.run() + + test.run(arguments = ['-c']) + + for f in files: + test.must_not_exist([ f]) + + for f in instfiles: + test.must_not_exist(['installtest', f]) + test.must_not_exist(['defaultenv-installtest', f]) + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/option/debug-multiple.py b/test/option/debug-multiple.py index f5bbdf0..f121a2c 100644 --- a/test/option/debug-multiple.py +++ b/test/option/debug-multiple.py @@ -21,6 +21,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 print_function + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ @@ -65,16 +67,16 @@ for args in ['--debug=prepare,count', '--debug=count,prepare']: 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", ' '.join(missing) - print "STDOUT ==========" - print stdout + print("Missing the following object lines from '%s' output:" % args) + print("\t", ' '.join(missing)) + print("STDOUT ==========") + print(stdout) test.fail_test(1) if 'Preparing target file.out...' not in stdout: - print "Missing 'Preparing' lines from '%s' output:" % args - print "STDOUT ==========" - print stdout + print("Missing 'Preparing' lines from '%s' output:" % args) + print("STDOUT ==========") + print(stdout) test.fail_test(1) test.pass_test() diff --git a/test/site_scons/sysdirs.py b/test/site_scons/sysdirs.py index 663700b..60b4f0b 100644 --- a/test/site_scons/sysdirs.py +++ b/test/site_scons/sysdirs.py @@ -22,6 +22,8 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +from __future__ import print_function + __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import TestSCons @@ -54,10 +56,10 @@ else: dir_to_check_for='.scons' if 'Loading site dir' not in test.stdout(): - print test.stdout() + print(test.stdout()) test.fail_test() if dir_to_check_for not in test.stdout(): - print test.stdout() + print(test.stdout()) test.fail_test() test.pass_test() -- cgit v0.12 From 85aa9baee353e5a7710cb34932ea7ed09a847e39 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 14:00:42 +0000 Subject: Amend some missed print functions. --- QMTest/TestCommon.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py index 7387e18..f878636 100644 --- a/QMTest/TestCommon.py +++ b/QMTest/TestCommon.py @@ -92,6 +92,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 print_function __author__ = "Steven Knight " @@ -307,10 +308,10 @@ class TestCommon(TestCmd): if find(output, input) is None: if title is None: title = 'output' - print 'Missing expected input from %s:' % title - print input - print self.banner(title + ' ') - print output + print('Missing expected input from {}:'.format(title)) + print(input) + print(self.banner(title + ' ')) + print(output) self.fail_test() def must_contain_all_lines(self, output, lines, title=None, find=None): -- cgit v0.12 From e9989979ac3411919935afe3a8c8c70ebbc4fd58 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 15:01:27 +0000 Subject: Some more print statements to functions. --- SConstruct | 5 +++-- doc/SConscript | 3 ++- src/engine/SCons/SConsign.py | 10 +++++----- src/engine/SCons/compat/sixTests.py | 4 ++-- src/engine/SCons/dblite.py | 1 - src/script/sconsign.py | 3 ++- test/ARGLIST.py | 2 +- test/Actions/pre-post.py | 22 +++++++++++----------- test/AddMethod.py | 8 ++++---- test/AddOption/basic.py | 4 ++-- test/CC/CFLAGS.py | 10 +++++----- .../convenience-functions/image/SConstruct | 5 +++-- 12 files changed, 40 insertions(+), 37 deletions(-) diff --git a/SConstruct b/SConstruct index 8734c2e..1616fc2 100644 --- a/SConstruct +++ b/SConstruct @@ -2,6 +2,7 @@ # SConstruct file to build scons packages during development. # # See the README.rst file for an overview of how SCons is built and tested. + from __future__ import print_function copyright_years = '2001 - 2015' @@ -162,7 +163,7 @@ import distutils.command no_winpack_templates = not os.path.exists(os.path.join(os.path.split(distutils.command.__file__)[0],'wininst-9.0.exe')) skip_win_packages = ARGUMENTS.get('SKIP_WIN_PACKAGES',False) or no_winpack_templates if skip_win_packages: - print "Skipping the build of Windows packages..." + print("Skipping the build of Windows packages...") python_ver = sys.version[0:3] @@ -1049,7 +1050,7 @@ for p in [ scons ]: # The built deb is called just x.y.z, not x.y.z.final.0 so strip those off: deb_version = '.'.join(version.split('.')[0:3]) deb = os.path.join(build_dir, 'dist', "%s_%s_all.deb" % (pkg, deb_version)) - # print "Building deb into %s (version=%s)"%(deb, deb_version) + # print("Building deb into %s (version=%s)"%(deb, deb_version)) for d in p['debian_deps']: b = env.SCons_revision(os.path.join(build, d), d) env.Depends(deb, b) diff --git a/doc/SConscript b/doc/SConscript index 6dbf33d..7e6aaeb 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -23,6 +23,7 @@ # 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 print_function import os.path @@ -52,7 +53,7 @@ fop = whereis('fop') xep = whereis('xep') if not fop and not xep: - print "doc: No PDF renderer found (fop|xep)!" + print("doc: No PDF renderer found (fop|xep)!") skip_doc = True # diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index 970c35c..cb089aa 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -26,6 +26,7 @@ Writing and reading information to the .sconsign file or 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -33,7 +34,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.compat import os -# compat layer imports "cPickle" for us if it's available. import pickle import SCons.dblite @@ -125,16 +125,16 @@ class SConsignEntry(object): """ __slots__ = ("binfo", "ninfo", "__weakref__") current_version_id = 2 - + def __init__(self): # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. #_version_id = self.current_version_id pass - + def convert_to_sconsign(self): self.binfo.convert_to_sconsign() - + def convert_from_sconsign(self, dir, name): self.binfo.convert_from_sconsign(dir, name) @@ -156,7 +156,7 @@ class SConsignEntry(object): for key, value in state.items(): if key not in ('_version_id','__weakref__'): setattr(self, key, value) - + class Base(object): """ This is the controlling class for the signatures for the collection of diff --git a/src/engine/SCons/compat/sixTests.py b/src/engine/SCons/compat/sixTests.py index 71df78d..8be3572 100644 --- a/src/engine/SCons/compat/sixTests.py +++ b/src/engine/SCons/compat/sixTests.py @@ -1,4 +1,3 @@ -from __future__ import print_function # # __COPYRIGHT__ # @@ -22,6 +21,8 @@ from __future__ import print_function # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # +from __future__ import print_function + import unittest class sixTestCase(unittest.TestCase): @@ -32,4 +33,3 @@ class sixTestCase(unittest.TestCase): print(sys.path) from SCons.compat.six import PY2, PY3 self.assertTrue(PY2 or PY3) - diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py index 3be6cb2..b12d320 100644 --- a/src/engine/SCons/dblite.py +++ b/src/engine/SCons/dblite.py @@ -5,7 +5,6 @@ from __future__ import print_function import SCons.compat import os -# compat layer imports "cPickle" for us if it's available. import pickle import shutil import time diff --git a/src/script/sconsign.py b/src/script/sconsign.py index 1a4caf7..daf088e 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -22,6 +22,7 @@ # 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 print_function from SCons.compat.six import PY2, PY3 @@ -185,7 +186,7 @@ sys.path = libs + sys.path # END STANDARD SCons SCRIPT HEADER ############################################################################## -import SCons.compat # so pickle will import cPickle instead +import SCons.compat if PY2: import whichdb diff --git a/test/ARGLIST.py b/test/ARGLIST.py index 186ad06..e246ba3 100644 --- a/test/ARGLIST.py +++ b/test/ARGLIST.py @@ -31,7 +31,7 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ i = 0 for key, value in ARGLIST: - print "%d: %s = %s" % (i, key, value) + print("%d: %s = %s" % (i, key, value)) i = i + 1 """) diff --git a/test/Actions/pre-post.py b/test/Actions/pre-post.py index e09ee02..179e914 100644 --- a/test/Actions/pre-post.py +++ b/test/Actions/pre-post.py @@ -118,14 +118,14 @@ def b(target, source, env): env1 = Environment(X='111') env2 = Environment(X='222') B = Builder(action = b, env = env1, multi=1) -print "B =", B -print "B.env =", B.env +print("B =", B) +print("B.env =", B.env) env1.Append(BUILDERS = {'B' : B}) env2.Append(BUILDERS = {'B' : B}) env3 = env1.Clone(X='333') -print "env1 =", env1 -print "env2 =", env2 -print "env3 =", env3 +print("env1 =", env1) +print("env2 =", env2) +print("env3 =", env3) f1 = env1.B(File('file1.out'), []) f2 = env2.B('file2.out', []) f3 = env3.B('file3.out', []) @@ -133,12 +133,12 @@ def do_nothing(env, target, source): pass AddPreAction(f2[0], do_nothing) AddPostAction(f3[0], do_nothing) -print "f1[0].builder =", f1[0].builder -print "f2[0].builder =", f2[0].builder -print "f3[0].builder =", f3[0].builder -print "f1[0].env =", f1[0].env -print "f2[0].env =", f2[0].env -print "f3[0].env =", f3[0].env +print("f1[0].builder =", f1[0].builder) +print("f2[0].builder =", f2[0].builder) +print("f3[0].builder =", f3[0].builder) +print("f1[0].env =", f1[0].env) +print("f2[0].env =", f2[0].env) +print("f3[0].env =", f3[0].env) """) test.run(chdir='work2', arguments = '.') diff --git a/test/AddMethod.py b/test/AddMethod.py index af84cb3..6049ae2 100644 --- a/test/AddMethod.py +++ b/test/AddMethod.py @@ -40,10 +40,10 @@ def foo(self): AddMethod(Environment, foo) env = Environment(FOO = '111') -print env.foo() +print(env.foo()) env = Environment(FOO = '222') -print env.foo() +print(env.foo()) env.AddMethod(foo, 'bar') env['FOO'] = '333' @@ -51,8 +51,8 @@ env['FOO'] = '333' e = env.Clone() e['FOO'] = '444' -print env.bar() -print e.bar() +print(env.bar()) +print(e.bar()) """) expect = """\ diff --git a/test/AddOption/basic.py b/test/AddOption/basic.py index a1bb7b3..b1b8f2e 100644 --- a/test/AddOption/basic.py +++ b/test/AddOption/basic.py @@ -48,8 +48,8 @@ AddOption('--prefix', f = GetOption('force') if f: f = "True" -print f -print GetOption('prefix') +print(f) +print(GetOption('prefix')) """) test.run('-Q -q .', diff --git a/test/CC/CFLAGS.py b/test/CC/CFLAGS.py index 6ea87ad..590d6b5 100644 --- a/test/CC/CFLAGS.py +++ b/test/CC/CFLAGS.py @@ -32,10 +32,10 @@ test = TestSCons.TestSCons() # Make sure CFLAGS is not passed to CXX by just expanding CXXCOM test.write('SConstruct', """ env = Environment(CFLAGS='-xyz', CCFLAGS='-abc') -print env.subst('$CXXCOM') -print env.subst('$CXXCOMSTR') -print env.subst('$SHCXXCOM') -print env.subst('$SHCXXCOMSTR') +print(env.subst('$CXXCOM')) +print(env.subst('$CXXCOMSTR')) +print(env.subst('$SHCXXCOM')) +print(env.subst('$SHCXXCOMSTR')) """) test.run(arguments = '.') test.must_not_contain_any_line(test.stdout(), ["-xyz"]) @@ -46,7 +46,7 @@ _obj = TestSCons._obj # Test passing CFLAGS to C compiler by actually compiling programs if sys.platform == 'win32': import SCons.Tool.MSCommon as msc - + if not msc.msvc_exists(): fooflags = '-DFOO' barflags = '-DBAR' diff --git a/test/packaging/convenience-functions/image/SConstruct b/test/packaging/convenience-functions/image/SConstruct index 461961e..f35c3e3 100644 --- a/test/packaging/convenience-functions/image/SConstruct +++ b/test/packaging/convenience-functions/image/SConstruct @@ -1,3 +1,4 @@ +from __future__ import print_function env = Environment(tools=['default', 'packaging']) prog = env.Install( 'bin/', ["f1", "f2"] ) @@ -6,5 +7,5 @@ env.File( "f3" ) src_files = sorted(map(str, env.FindSourceFiles())) oth_files = sorted(map(str, env.FindInstalledFiles())) -print src_files -print oth_files +print(src_files) +print(oth_files) -- cgit v0.12 From 7b68ccb54e7b4d2200f8ac813eb6f8b2ae3654eb Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 15:23:41 +0000 Subject: Some more print statements to functions. --- test/Actions/actions.py | 10 +++--- test/AddOption/optional-arg.py | 2 +- test/CPPDEFINES/append.py | 52 ++++++++++++++++---------------- test/CPPDEFINES/basic.py | 6 ++-- test/CPPDEFINES/undefined.py | 4 +-- test/CacheDir/scanner-target.py | 2 +- test/CacheDir/source-scanner.py | 2 +- test/Climb/filename--D.py | 4 +-- test/Climb/filename--U.py | 4 +-- test/Climb/filename-u.py | 4 +-- test/Clone-compatibility.py | 4 +-- test/Configure/Streamer1.py | 2 +- test/Configure/cache-not-ok.py | 2 +- test/ConstructionEnvironment.py | 2 +- test/Deprecated/Options/BoolOption.py | 4 +-- test/Deprecated/Options/Options.py | 26 ++++++++-------- test/Deprecated/Options/PackageOption.py | 2 +- test/Deprecated/Options/PathOption.py | 16 +++++----- test/Deprecated/Options/chdir.py | 2 +- test/Deprecated/Options/help.py | 6 ++-- test/Deprecated/Options/import.py | 2 +- test/Dir/Dir.py | 12 ++++---- 22 files changed, 85 insertions(+), 85 deletions(-) diff --git a/test/Actions/actions.py b/test/Actions/actions.py index 03d67a0..785a0cb 100644 --- a/test/Actions/actions.py +++ b/test/Actions/actions.py @@ -70,7 +70,7 @@ import os def func(env, target, source): cmd = r'%(_python_)s build.py %%s 3 %%s' %% (' '.join(map(str, target)), ' '.join(map(str, source))) - print cmd + print(cmd) return os.system(cmd) B = Builder(action = func) env = Environment(BUILDERS = { 'B' : B }) @@ -91,7 +91,7 @@ class bld(object): self.cmd = r'%(_python_)s build.py %%s 4 %%s' def __call__(self, env, target, source): cmd = self.get_contents(env, target, source) - print cmd + print(cmd) return os.system(cmd) def get_contents(self, env, target, source): return self.cmd %% (' '.join(map(str, target)), @@ -114,9 +114,9 @@ def func(env, target, source): env = Environment(S = Action('foo'), F = Action(func), L = Action(['arg1', 'arg2'])) -print env.subst('$S') -print env.subst('$F') -print env.subst('$L') +print(env.subst('$S')) +print(env.subst('$F')) +print(env.subst('$L')) """) test.run(arguments = '-Q .', stdout = """\ diff --git a/test/AddOption/optional-arg.py b/test/AddOption/optional-arg.py index f976ad9..b88b796 100644 --- a/test/AddOption/optional-arg.py +++ b/test/AddOption/optional-arg.py @@ -43,7 +43,7 @@ AddOption('--install', type='string', metavar='DIR', help='installation directory') -print GetOption('install') +print(GetOption('install')) """) test.run('-Q -q', diff --git a/test/CPPDEFINES/append.py b/test/CPPDEFINES/append.py index 6e69d09..432ab64 100644 --- a/test/CPPDEFINES/append.py +++ b/test/CPPDEFINES/append.py @@ -40,17 +40,17 @@ test.write('SConstruct', """\ env_1738_2 = Environment(CPPDEFPREFIX='-D') env_1738_2['CPPDEFINES'] = ['FOO'] env_1738_2.Append(CPPDEFINES={'value' : '1'}) -print env_1738_2.subst('$_CPPDEFFLAGS') +print(env_1738_2.subst('$_CPPDEFFLAGS')) #env_1738_2.Object('test_1738_2', 'main.c') # http://scons.tigris.org/issues/show_bug.cgi?id=2300 env_2300_1 = Environment(CPPDEFINES = 'foo', CPPDEFPREFIX='-D') env_2300_1.Append(CPPDEFINES='bar') -print env_2300_1.subst('$_CPPDEFFLAGS') +print(env_2300_1.subst('$_CPPDEFFLAGS')) env_2300_2 = Environment(CPPDEFINES = ['foo'], CPPDEFPREFIX='-D') # note the list env_2300_2.Append(CPPDEFINES='bar') -print env_2300_2.subst('$_CPPDEFFLAGS') +print(env_2300_2.subst('$_CPPDEFFLAGS')) # http://scons.tigris.org/issues/show_bug.cgi?id=1152 # http://scons.tigris.org/issues/show_bug.cgi?id=2900 @@ -62,18 +62,18 @@ cases=[('string', 'FOO'), for (t1, c1) in cases: for (t2, c2) in cases: - print "==== Testing CPPDEFINES, appending a %s to a %s"%(t2, t1) - print " orig = %s, append = %s"%(c1, c2) + print("==== Testing CPPDEFINES, appending a %s to a %s"%(t2, t1)) + print(" orig = %s, append = %s"%(c1, c2)) env=Environment(CPPDEFINES = c1, CPPDEFPREFIX='-D') env.Append(CPPDEFINES = c2) final=env.subst('$_CPPDEFFLAGS',source="src", target="tgt") - print 'Append: \\n\\tresult=%s\\n\\tfinal=%s'%\\ - (env['CPPDEFINES'], final) + print('Append: \\n\\tresult=%s\\n\\tfinal=%s'%\\ + (env['CPPDEFINES'], final)) env=Environment(CPPDEFINES = c1, CPPDEFPREFIX='-D') env.AppendUnique(CPPDEFINES = c2) final=env.subst('$_CPPDEFFLAGS',source="src", target="tgt") - print 'AppendUnique:\\n\\tresult=%s\\n\\tfinal=%s'%\\ - (env['CPPDEFINES'], final) + print('AppendUnique:\\n\\tresult=%s\\n\\tfinal=%s'%\\ + (env['CPPDEFINES'], final)) """) @@ -83,7 +83,7 @@ expect_print_output="""\ -Dfoo -Dbar ==== Testing CPPDEFINES, appending a string to a string orig = FOO, append = FOO -Append: +Append: result=['FOO', 'FOO'] final=-DFOO -DFOO AppendUnique: @@ -91,7 +91,7 @@ AppendUnique: final=-DFOO ==== Testing CPPDEFINES, appending a list to a string orig = FOO, append = ['NAME1', 'NAME2'] -Append: +Append: result=['FOO', 'NAME1', 'NAME2'] final=-DFOO -DNAME1 -DNAME2 AppendUnique: @@ -99,7 +99,7 @@ AppendUnique: final=-DFOO -DNAME1 -DNAME2 ==== Testing CPPDEFINES, appending a list-of-2lists to a string orig = FOO, append = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']] -Append: +Append: result=['FOO', ('NAME1', 'VAL1'), ['NAME2', 'VAL2']] final=-DFOO -DNAME1=VAL1 -DNAME2=VAL2 AppendUnique: @@ -107,7 +107,7 @@ AppendUnique: final=-DFOO -DNAME1=VAL1 -DNAME2=VAL2 ==== Testing CPPDEFINES, appending a dict to a string orig = FOO, append = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} -Append: +Append: result=['FOO', {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}] final=-DFOO -DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 AppendUnique: @@ -115,7 +115,7 @@ AppendUnique: final=-DFOO -DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 ==== Testing CPPDEFINES, appending a string to a list orig = ['NAME1', 'NAME2'], append = FOO -Append: +Append: result=['NAME1', 'NAME2', 'FOO'] final=-DNAME1 -DNAME2 -DFOO AppendUnique: @@ -123,7 +123,7 @@ AppendUnique: final=-DNAME1 -DNAME2 -DFOO ==== Testing CPPDEFINES, appending a list to a list orig = ['NAME1', 'NAME2'], append = ['NAME1', 'NAME2'] -Append: +Append: result=['NAME1', 'NAME2', 'NAME1', 'NAME2'] final=-DNAME1 -DNAME2 -DNAME1 -DNAME2 AppendUnique: @@ -131,7 +131,7 @@ AppendUnique: final=-DNAME1 -DNAME2 ==== Testing CPPDEFINES, appending a list-of-2lists to a list orig = ['NAME1', 'NAME2'], append = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']] -Append: +Append: result=['NAME1', 'NAME2', ('NAME1', 'VAL1'), ['NAME2', 'VAL2']] final=-DNAME1 -DNAME2 -DNAME1=VAL1 -DNAME2=VAL2 AppendUnique: @@ -139,7 +139,7 @@ AppendUnique: final=-DNAME1 -DNAME2 -DNAME1=VAL1 -DNAME2=VAL2 ==== Testing CPPDEFINES, appending a dict to a list orig = ['NAME1', 'NAME2'], append = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} -Append: +Append: result=['NAME1', 'NAME2', {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}] final=-DNAME1 -DNAME2 -DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 AppendUnique: @@ -147,7 +147,7 @@ AppendUnique: final=-DNAME1 -DNAME2 -DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 ==== Testing CPPDEFINES, appending a string to a list-of-2lists orig = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']], append = FOO -Append: +Append: result=[('NAME1', 'VAL1'), ['NAME2', 'VAL2'], 'FOO'] final=-DNAME1=VAL1 -DNAME2=VAL2 -DFOO AppendUnique: @@ -155,7 +155,7 @@ AppendUnique: final=-DNAME1=VAL1 -DNAME2=VAL2 -DFOO ==== Testing CPPDEFINES, appending a list to a list-of-2lists orig = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']], append = ['NAME1', 'NAME2'] -Append: +Append: result=[('NAME1', 'VAL1'), ['NAME2', 'VAL2'], 'NAME1', 'NAME2'] final=-DNAME1=VAL1 -DNAME2=VAL2 -DNAME1 -DNAME2 AppendUnique: @@ -163,7 +163,7 @@ AppendUnique: final=-DNAME1=VAL1 -DNAME2=VAL2 -DNAME1 -DNAME2 ==== Testing CPPDEFINES, appending a list-of-2lists to a list-of-2lists orig = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']], append = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']] -Append: +Append: result=[('NAME1', 'VAL1'), ['NAME2', 'VAL2'], ('NAME1', 'VAL1'), ['NAME2', 'VAL2']] final=-DNAME1=VAL1 -DNAME2=VAL2 -DNAME1=VAL1 -DNAME2=VAL2 AppendUnique: @@ -171,7 +171,7 @@ AppendUnique: final=-DNAME1=VAL1 -DNAME2=VAL2 ==== Testing CPPDEFINES, appending a dict to a list-of-2lists orig = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']], append = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} -Append: +Append: result=[('NAME1', 'VAL1'), ['NAME2', 'VAL2'], {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}] final=-DNAME1=VAL1 -DNAME2=VAL2 -DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 AppendUnique: @@ -179,7 +179,7 @@ AppendUnique: final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 ==== Testing CPPDEFINES, appending a string to a dict orig = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}, append = FOO -Append: +Append: result={'FOO': None, 'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} final=-DFOO -DNAME1=VAL1 -DNAME2=VAL2 -DNAME3 AppendUnique: @@ -187,7 +187,7 @@ AppendUnique: final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 -DFOO ==== Testing CPPDEFINES, appending a list to a dict orig = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}, append = ['NAME1', 'NAME2'] -Append: +Append: result=[('NAME2', 'VAL2'), ('NAME3',), ('NAME1', 'VAL1'), 'NAME1', 'NAME2'] final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 -DNAME1 -DNAME2 AppendUnique: @@ -195,7 +195,7 @@ AppendUnique: final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 -DNAME1 -DNAME2 ==== Testing CPPDEFINES, appending a list-of-2lists to a dict orig = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}, append = [('NAME1', 'VAL1'), ['NAME2', 'VAL2']] -Append: +Append: result=[('NAME2', 'VAL2'), ('NAME3',), ('NAME1', 'VAL1'), ('NAME1', 'VAL1'), ['NAME2', 'VAL2']] final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 -DNAME1=VAL1 -DNAME2=VAL2 AppendUnique: @@ -203,7 +203,7 @@ AppendUnique: final=-DNAME2=VAL2 -DNAME3 -DNAME1=VAL1 ==== Testing CPPDEFINES, appending a dict to a dict orig = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'}, append = {'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} -Append: +Append: result={'NAME2': 'VAL2', 'NAME3': None, 'NAME1': 'VAL1'} final=-DNAME1=VAL1 -DNAME2=VAL2 -DNAME3 AppendUnique: @@ -213,7 +213,7 @@ AppendUnique: build_output="scons: `.' is up to date.\n" -expect = test.wrap_stdout(build_str=build_output, +expect = test.wrap_stdout(build_str=build_output, read_str = expect_print_output) test.run(arguments = '.', stdout=expect) test.pass_test() diff --git a/test/CPPDEFINES/basic.py b/test/CPPDEFINES/basic.py index b54a421..57d7260 100644 --- a/test/CPPDEFINES/basic.py +++ b/test/CPPDEFINES/basic.py @@ -41,13 +41,13 @@ test_list = [ ] for i in test_list: env = Environment(CPPDEFPREFIX='-D', CPPDEFSUFFIX='', INTEGER=0) - print env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) for i in test_list: env = Environment(CPPDEFPREFIX='|', CPPDEFSUFFIX='|', INTEGER=1) - print env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS') + print(env.Clone(CPPDEFINES=i).subst('$_CPPDEFFLAGS')) """) -expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", +expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", read_str = """\ -Dxyz -Dx -Dy -Dz diff --git a/test/CPPDEFINES/undefined.py b/test/CPPDEFINES/undefined.py index 47825b6..b26b05a 100644 --- a/test/CPPDEFINES/undefined.py +++ b/test/CPPDEFINES/undefined.py @@ -34,10 +34,10 @@ test = TestSCons.TestSCons() test.write('SConstruct', """\ env = Environment() -print env.subst('$_CPPDEFFLAGS') +print(env.subst('$_CPPDEFFLAGS')) """) -expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", +expect = test.wrap_stdout(build_str="scons: `.' is up to date.\n", read_str = "\n") test.run(arguments = '.', stdout=expect) diff --git a/test/CacheDir/scanner-target.py b/test/CacheDir/scanner-target.py index 645b597..c39042e 100644 --- a/test/CacheDir/scanner-target.py +++ b/test/CacheDir/scanner-target.py @@ -52,7 +52,7 @@ def docopy(target,source,env): f.close() def sillyScanner(node, env, dirs): - print 'This is never called (unless we build file.out)' + print('This is never called (unless we build file.out)') return [] SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) diff --git a/test/CacheDir/source-scanner.py b/test/CacheDir/source-scanner.py index e7db5e9..2359872 100644 --- a/test/CacheDir/source-scanner.py +++ b/test/CacheDir/source-scanner.py @@ -54,7 +54,7 @@ def docopy(target,source,env): f.close() def sillyScanner(node, env, dirs): - print 'This is never called (unless we build file.out)' + print('This is never called (unless we build file.out)') return [] SillyScanner = SCons.Scanner.Base(function = sillyScanner, skeys = ['.res']) diff --git a/test/Climb/filename--D.py b/test/Climb/filename--D.py index 06d95e7..6fea9bc 100644 --- a/test/Climb/filename--D.py +++ b/test/Climb/filename--D.py @@ -36,12 +36,12 @@ test = TestSCons.TestSCons() test.subdir('subdir', 'other') test.write('main.scons', """\ -print "main.scons" +print("main.scons") SConscript('subdir/sub.scons') """) test.write(['subdir', 'sub.scons'], """\ -print "subdir/sub.scons" +print("subdir/sub.scons") """) diff --git a/test/Climb/filename--U.py b/test/Climb/filename--U.py index 7f2e60d..49ccc0a 100644 --- a/test/Climb/filename--U.py +++ b/test/Climb/filename--U.py @@ -36,12 +36,12 @@ test = TestSCons.TestSCons() test.subdir('subdir', 'other') test.write('main.scons', """\ -print "main.scons" +print("main.scons") SConscript('subdir/sub.scons') """) test.write(['subdir', 'sub.scons'], """\ -print "subdir/sub.scons" +print("subdir/sub.scons") """) read_str = """\ diff --git a/test/Climb/filename-u.py b/test/Climb/filename-u.py index 7bae153..4485c4b 100644 --- a/test/Climb/filename-u.py +++ b/test/Climb/filename-u.py @@ -36,12 +36,12 @@ test = TestSCons.TestSCons() test.subdir('subdir', 'other') test.write('main.scons', """\ -print "main.scons" +print("main.scons") SConscript('subdir/sub.scons') """) test.write(['subdir', 'sub.scons'], """\ -print "subdir/sub.scons" +print("subdir/sub.scons") """) read_str = """\ diff --git a/test/Clone-compatibility.py b/test/Clone-compatibility.py index 089b7a4..a2f6362 100644 --- a/test/Clone-compatibility.py +++ b/test/Clone-compatibility.py @@ -48,8 +48,8 @@ except AttributeError: env1 = Environment(X = 1) env2 = env1.Clone(X = 2) -print env1['X'] -print env2['X'] +print(env1['X']) +print(env2['X']) """) test.run(arguments = '-q -Q', stdout = "1\n2\n") diff --git a/test/Configure/Streamer1.py b/test/Configure/Streamer1.py index 8f35308..318a936 100644 --- a/test/Configure/Streamer1.py +++ b/test/Configure/Streamer1.py @@ -45,7 +45,7 @@ test.write('SConstruct', """ def hello(target, source, env): import traceback try: - print 'hello!\\n' # this breaks the script + print('hello!\\n') # this breaks the script with open(env.subst('$TARGET', target = target),'w') as f: f.write('yes') except: diff --git a/test/Configure/cache-not-ok.py b/test/Configure/cache-not-ok.py index ccbb7d5..7502f7a 100644 --- a/test/Configure/cache-not-ok.py +++ b/test/Configure/cache-not-ok.py @@ -53,7 +53,7 @@ r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error r2 = conf.CheckLib( 'no_c_library_SAFFDG' ) # leads to link error env = conf.Finish() if not (not r1 and not r2): - print "FAIL: ", r1, r2 + print("FAIL: ", r1, r2) Exit(1) """) diff --git a/test/ConstructionEnvironment.py b/test/ConstructionEnvironment.py index bec46b9..e25f86a 100644 --- a/test/ConstructionEnvironment.py +++ b/test/ConstructionEnvironment.py @@ -38,7 +38,7 @@ import SCons.Defaults SCons.Defaults.ConstructionEnvironment.update({ 'XXX' : 777, }) -print DefaultEnvironment()['XXX'] +print(DefaultEnvironment()['XXX']) """) expect = test.wrap_stdout(read_str = "777\n", diff --git a/test/Deprecated/Options/BoolOption.py b/test/Deprecated/Options/BoolOption.py index 563939b..5d12fc6 100644 --- a/test/Deprecated/Options/BoolOption.py +++ b/test/Deprecated/Options/BoolOption.py @@ -55,8 +55,8 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['warnings'] -print env['profile'] +print(env['warnings']) +print(env['profile']) Default(env.Alias('dummy', None)) """) diff --git a/test/Deprecated/Options/Options.py b/test/Deprecated/Options/Options.py index 61a12f3..e435b9e 100644 --- a/test/Deprecated/Options/Options.py +++ b/test/Deprecated/Options/Options.py @@ -30,8 +30,8 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) test.write('SConstruct', """ env = Environment() -print env['CC'] -print " ".join(env['CCFLAGS']) +print(env['CC']) +print(" ".join(env['CCFLAGS'])) Default(env.Alias('dummy', None)) """) test.run() @@ -99,12 +99,12 @@ env = Environment(options=opts, tools=['default', test_tool]) Help('Variables settable in custom.py or on the command line:\\n' + opts.GenerateHelpText(env)) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] -print env['CC'] -print " ".join(env['CCFLAGS']) -print env['VALIDATE'] -print env['valid_key'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) +print(env['CC']) +print(" ".join(env['CCFLAGS'])) +print(env['VALIDATE']) +print(env['valid_key']) # unspecified options should not be set: assert 'UNSPECIFIED' not in env @@ -226,8 +226,8 @@ opts.Add('UNSPECIFIED', env = Environment(options = opts) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) opts.Save('options.saved', env) """) @@ -282,9 +282,9 @@ opts.Add('LISTOPTION_TEST', env = Environment(options = opts) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] -print env['LISTOPTION_TEST'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) +print(env['LISTOPTION_TEST']) opts.Save('options.saved', env) """) diff --git a/test/Deprecated/Options/PackageOption.py b/test/Deprecated/Options/PackageOption.py index 424e5a7..ec8990c 100644 --- a/test/Deprecated/Options/PackageOption.py +++ b/test/Deprecated/Options/PackageOption.py @@ -59,7 +59,7 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['x11'] +print(env['x11']) Default(env.Alias('dummy', None)) """) diff --git a/test/Deprecated/Options/PathOption.py b/test/Deprecated/Options/PathOption.py index 4701420..0e6949c 100644 --- a/test/Deprecated/Options/PathOption.py +++ b/test/Deprecated/Options/PathOption.py @@ -25,7 +25,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" """ -Test the PathOption canned option type, with tests for its +Test the PathOption canned option type, with tests for its various canned validators. """ @@ -65,9 +65,9 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['qtdir'] -print env['qt_libraries'] -print env.subst('$qt_libraries') +print(env['qtdir']) +print(env['qt_libraries']) +print(env.subst('$qt_libraries')) Default(env.Alias('dummy', None)) """ % (workpath, os.path.join('$qtdir', 'lib') )) @@ -144,7 +144,7 @@ opts.AddOptions( env = Environment(options=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) @@ -177,7 +177,7 @@ opts.AddOptions( env = Environment(options=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_file) @@ -218,7 +218,7 @@ opts.AddOptions( env = Environment(options=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) @@ -263,7 +263,7 @@ opts.AddOptions( env = Environment(options=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) diff --git a/test/Deprecated/Options/chdir.py b/test/Deprecated/Options/chdir.py index a8fb6c6..977a351 100644 --- a/test/Deprecated/Options/chdir.py +++ b/test/Deprecated/Options/chdir.py @@ -46,7 +46,7 @@ SConscript_contents = """\ Import("opts") env = Environment() opts.Update(env) -print "VARIABLE =", repr(env['VARIABLE']) +print("VARIABLE =", repr(env['VARIABLE'])) """ test.write(['bin', 'opts.cfg'], """\ diff --git a/test/Deprecated/Options/help.py b/test/Deprecated/Options/help.py index 8c240e3..ad8a96b 100644 --- a/test/Deprecated/Options/help.py +++ b/test/Deprecated/Options/help.py @@ -49,7 +49,7 @@ libdirvar_re = re.escape(libdirvar) test.subdir(qtpath) test.subdir(libpath) - + test.write('SConstruct', """ from SCons.Options import BoolOption, EnumOption, ListOption, \ PackageOption, PathOption @@ -86,8 +86,8 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['warnings'] -print env['profile'] +print(env['warnings']) +print(env['profile']) Default(env.Alias('dummy', None)) """ % locals()) diff --git a/test/Deprecated/Options/import.py b/test/Deprecated/Options/import.py index a4d56b2..b93e6a2 100644 --- a/test/Deprecated/Options/import.py +++ b/test/Deprecated/Options/import.py @@ -48,7 +48,7 @@ SConscript_contents = """\ Import("opts") env = Environment() opts.Update(env) -print "VARIABLE =", env.get('VARIABLE') +print("VARIABLE =", env.get('VARIABLE')) """ test.write(['bin', 'opts.cfg'], """\ diff --git a/test/Dir/Dir.py b/test/Dir/Dir.py index af0a10b..2e8204c 100644 --- a/test/Dir/Dir.py +++ b/test/Dir/Dir.py @@ -36,12 +36,12 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment(FOO = 'fff', BAR = 'bbb') -print Dir('ddd') -print Dir('$FOO') -print Dir('${BAR}_$BAR') -print env.Dir('eee') -print env.Dir('$FOO') -print env.Dir('${BAR}_$BAR') +print(Dir('ddd')) +print(Dir('$FOO')) +print(Dir('${BAR}_$BAR')) +print(env.Dir('eee')) +print(env.Dir('$FOO')) +print(env.Dir('${BAR}_$BAR')) """) test.run(stdout = test.wrap_stdout(read_str = """\ -- cgit v0.12 From 3f637329635c089bdca30bb4b0e23334d12866b3 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 15:59:23 +0000 Subject: Some more statement to function transforms. --- test/CPPDEFINES/pkg-config.py | 12 +++---- test/Deprecated/Options/EnumOption.py | 6 ++-- test/Deprecated/Options/ListOption.py | 16 ++++----- test/Entry.py | 12 +++---- test/Environment.py | 4 +-- test/Errors/Exception.py | 2 +- test/ExecuteInvalidateCache.py | 4 +-- test/Exit.py | 12 +++---- test/File.py | 16 ++++----- test/FindFile.py | 8 ++--- test/Flatten.py | 8 ++--- test/GetBuildFailures/parallel.py | 6 ++-- test/GetBuildFailures/serial.py | 4 +-- test/GetOption/help.py | 4 +-- test/Libs/SharedLibraryIxes.py | 16 ++++----- test/Mkdir.py | 2 +- test/NodeOps.py | 4 +-- test/ParseConfig.py | 32 +++++++++--------- test/Platform.py | 16 ++++----- test/QT/QTFLAGS.py | 8 ++--- test/QT/manual.py | 6 ++-- test/tool_args.py | 8 ++--- test/toolpath/basic.py | 62 +++++++++++++++++------------------ 23 files changed, 134 insertions(+), 134 deletions(-) diff --git a/test/CPPDEFINES/pkg-config.py b/test/CPPDEFINES/pkg-config.py index 1b308d3..4e81dec 100644 --- a/test/CPPDEFINES/pkg-config.py +++ b/test/CPPDEFINES/pkg-config.py @@ -60,26 +60,26 @@ test.write('SConstruct', """\ # Passing test cases env_1 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST']) env_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug') -print env_1.subst('$_CPPDEFFLAGS') +print(env_1.subst('$_CPPDEFFLAGS')) env_2 = Environment(CPPDEFINES=[('DEBUG','1'), 'TEST']) env_2.MergeFlags('-DSOMETHING -DVARIABLE=2') -print env_2.subst('$_CPPDEFFLAGS') +print(env_2.subst('$_CPPDEFFLAGS')) # Failing test cases env_3 = Environment(CPPDEFINES={'DEBUG':1, 'TEST':None}) env_3.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags bug') -print env_3.subst('$_CPPDEFFLAGS') +print(env_3.subst('$_CPPDEFFLAGS')) env_4 = Environment(CPPDEFINES={'DEBUG':1, 'TEST':None}) env_4.MergeFlags('-DSOMETHING -DVARIABLE=2') -print env_4.subst('$_CPPDEFFLAGS') +print(env_4.subst('$_CPPDEFFLAGS')) # http://scons.tigris.org/issues/show_bug.cgi?id=1738 env_1738_1 = Environment(tools=['default']) env_1738_1.ParseConfig('PKG_CONFIG_PATH=. %(pkg_config_path)s --cflags --libs bug') env_1738_1.Append(CPPDEFINES={'value' : '1'}) -print env_1738_1.subst('$_CPPDEFFLAGS') +print(env_1738_1.subst('$_CPPDEFFLAGS')) """%locals() ) expect_print_output="""\ @@ -92,7 +92,7 @@ expect_print_output="""\ build_output="scons: `.' is up to date.\n" -expect = test.wrap_stdout(build_str=build_output, +expect = test.wrap_stdout(build_str=build_output, read_str = expect_print_output) test.run(arguments = '.', stdout=expect) test.pass_test() diff --git a/test/Deprecated/Options/EnumOption.py b/test/Deprecated/Options/EnumOption.py index 57ae7eb..2b3ed47 100644 --- a/test/Deprecated/Options/EnumOption.py +++ b/test/Deprecated/Options/EnumOption.py @@ -66,9 +66,9 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['debug'] -print env['guilib'] -print env['some'] +print(env['debug']) +print(env['guilib'] +print(env['some']) Default(env.Alias('dummy', None)) """) diff --git a/test/Deprecated/Options/ListOption.py b/test/Deprecated/Options/ListOption.py index bb3775b..ad804f2 100644 --- a/test/Deprecated/Options/ListOption.py +++ b/test/Deprecated/Options/ListOption.py @@ -67,15 +67,15 @@ env = Environment(options=opts) opts.Save(optsfile, env) Help(opts.GenerateHelpText(env)) -print env['shared'] -if 'ical' in env['shared']: print '1' -else: print '0' +print(env['shared']) +if 'ical' in env['shared']: print('1') +else: print('0') for x in env['shared']: - print x, -print -print env.subst('$shared') + print(x, end='') +print() +print(env.subst('$shared')) # Test subst_path() because it's used in $CPPDEFINES expansions. -print env.subst_path('$shared') +print(env.subst_path('$shared')) Default(env.Alias('dummy', None)) """) @@ -169,7 +169,7 @@ opts.AddOptions( env = Environment(options=opts) Help(opts.GenerateHelpText(env)) -print env['gpib'] +print(env['gpib']) Default(env.Alias('dummy', None)) """) diff --git a/test/Entry.py b/test/Entry.py index 3767cc5..3d3255d 100644 --- a/test/Entry.py +++ b/test/Entry.py @@ -36,12 +36,12 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment(FOO = 'fff', BAR = 'bbb') -print Entry('ddd') -print Entry('$FOO') -print Entry('${BAR}_$BAR') -print env.Entry('eee') -print env.Entry('$FOO') -print env.Entry('${BAR}_$BAR') +print(Entry('ddd')) +print(Entry('$FOO')) +print(Entry('${BAR}_$BAR')) +print(env.Entry('eee')) +print(env.Entry('$FOO')) +print(env.Entry('${BAR}_$BAR')) """) test.run(stdout = test.wrap_stdout(read_str = """\ diff --git a/test/Environment.py b/test/Environment.py index 52b6488..6810979 100644 --- a/test/Environment.py +++ b/test/Environment.py @@ -42,8 +42,8 @@ assert Dir('.') == Dir('.').Dir('.') assert target == target.File('foo.out') e2 = env.Environment(XXX='$BAR', YYY='$BLAT') -print e2['XXX'] -print e2['YYY'] +print(e2['XXX']) +print(e2['YYY']) """ % locals()) test.write('build.py', """ diff --git a/test/Errors/Exception.py b/test/Errors/Exception.py index cc36035..30404fc 100644 --- a/test/Errors/Exception.py +++ b/test/Errors/Exception.py @@ -30,7 +30,7 @@ test = TestSCons.TestSCons(match = TestSCons.match_re_dotall) test.write('SConstruct', """\ def foo(env, target, source): - print str(target[0]) + print(str(target[0])) open(str(target[0]), 'wt').write('foo') def exit(env, target, source): diff --git a/test/ExecuteInvalidateCache.py b/test/ExecuteInvalidateCache.py index a22c5ea..6d8063e 100644 --- a/test/ExecuteInvalidateCache.py +++ b/test/ExecuteInvalidateCache.py @@ -40,9 +40,9 @@ subfn = os.path.join('sub', 'foo') test.write('SConstruct', """\ def exists(node): if node.exists(): - print str(node), "exists" + print(str(node), "exists") else: - print str(node), "does not exist" + print(str(node), "does not exist") Execute(Delete('abc')) n1 = File('abc') diff --git a/test/Exit.py b/test/Exit.py index 877a0b6..394ee2f 100644 --- a/test/Exit.py +++ b/test/Exit.py @@ -40,7 +40,7 @@ subdir_foo_in = os.path.join('subdir', 'foo.in') subdir_foo_out = os.path.join('subdir', 'foo.out') test.write('SConstruct', """\ -print "SConstruct, Exit()" +print("SConstruct, Exit()") Exit() """) @@ -51,7 +51,7 @@ SConstruct, Exit() test.write('SConstruct', """\ env = Environment() -print "SConstruct, env.Exit()" +print("SConstruct, env.Exit()") env.Exit() """) @@ -61,7 +61,7 @@ SConstruct, env.Exit() """) test.write('SConstruct', """\ -print "SConstruct" +print("SConstruct") Exit(7) """) @@ -71,12 +71,12 @@ SConstruct """) test.write('SConstruct', """\ -print "SConstruct" +print("SConstruct") SConscript('subdir/SConscript') """) test.write(['subdir', 'SConscript'], """\ -print "subdir/SConscript" +print("subdir/SConscript") Exit() """) @@ -87,7 +87,7 @@ subdir/SConscript """) test.write(['subdir', 'SConscript'], """\ -print "subdir/SConscript" +print("subdir/SConscript") Exit(17) """) diff --git a/test/File.py b/test/File.py index d919884..ec148b2 100644 --- a/test/File.py +++ b/test/File.py @@ -38,16 +38,16 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment(FOO = 'fff', BAR = 'bbb') -print File('ddd') -print File('$FOO') -print File('${BAR}_$BAR') -print env.File('eee') -print env.File('$FOO') -print env.File('${BAR}_$BAR') +print(File('ddd')) +print(File('$FOO')) +print(File('${BAR}_$BAR')) +print(env.File('eee')) +print(env.File('$FOO')) +print(env.File('${BAR}_$BAR')) f1 = env.File('f1') -print f1 +print(f1) f2 = f1.File('f2') -print f2 +print(f2) """) expect = test.wrap_stdout(read_str = """\ diff --git a/test/FindFile.py b/test/FindFile.py index 5d198ac..e878172 100644 --- a/test/FindFile.py +++ b/test/FindFile.py @@ -40,13 +40,13 @@ test.write(['bar', 'baz', 'testfile2'], 'test 4\n') test.write('SConstruct', """ env = Environment(FILE = 'file', BAR = 'bar') file1 = FindFile('testfile1', [ 'foo', '.', 'bar', 'bar/baz' ]) -print open(str(file1), 'r').read() +print(open(str(file1), 'r').read()) file2 = env.FindFile('test${FILE}1', [ 'bar', 'foo', '.', 'bar/baz' ]) -print open(str(file2), 'r').read() +print(open(str(file2), 'r').read()) file3 = FindFile('testfile2', [ 'foo', '.', 'bar', 'bar/baz' ]) -print open(str(file3), 'r').read() +print(open(str(file3), 'r').read()) file4 = env.FindFile('testfile2', [ '$BAR/baz', 'foo', '.', 'bar' ]) -print open(str(file4), 'r').read() +print(open(str(file4), 'r').read()) """) expect = test.wrap_stdout(read_str = """test 1 diff --git a/test/Flatten.py b/test/Flatten.py index b41c4fe..fd9943d 100644 --- a/test/Flatten.py +++ b/test/Flatten.py @@ -44,15 +44,15 @@ def cat(env, source, target): env = Environment(BUILDERS={'Cat':Builder(action=cat)}) f1 = env.Cat('../file1.out', 'file1.in') f2 = env.Cat('../file2.out', ['file2a.in', 'file2b.in']) -print list(map(str, Flatten(['begin', f1, 'middle', f2, 'end']))) -print list(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") """) test.write(['work', 'SConscript'], """ Import("env") -print Flatten([1, [2, 3], 4]) -print env.Flatten([[[[1], 2], 3], 4]) +print(Flatten([1, [2, 3], 4])) +print(env.Flatten([[[[1], 2], 3], 4])) """) test.write('file1.in', "file1.in\n") diff --git a/test/GetBuildFailures/parallel.py b/test/GetBuildFailures/parallel.py index e746d53..ee0e831 100644 --- a/test/GetBuildFailures/parallel.py +++ b/test/GetBuildFailures/parallel.py @@ -81,7 +81,7 @@ Command('f6', 'f6.in', r'@%(_python_)s mypass.py f5 - $TARGET $SOURCE') def print_build_failures(): from SCons.Script import GetBuildFailures for bf in sorted(GetBuildFailures(), key=lambda t: t.filename): - print "%%s failed: %%s" %% (bf.node, bf.errstr) + print("%%s failed: %%s" %% (bf.node, bf.errstr)) import atexit atexit.register(print_build_failures) @@ -96,7 +96,7 @@ test.run(arguments = '-Q -j 4 .', status = 2, stderr = None) -f4_error = "scons: *** [f4] Error 1\n" +f4_error = "scons: *** [f4] Error 1\n" f5_error = "scons: *** [f5] Error 1\n" error_45 = f4_error + f5_error @@ -129,7 +129,7 @@ if test.stdout() not in [failed_45, failed_54]: test.must_match(test.workpath('f3'), 'f3.in\n') test.must_not_exist(test.workpath('f4')) test.must_not_exist(test.workpath('f5')) -test.must_match(test.workpath('f6'), 'f6.in\n') +test.must_match(test.workpath('f6'), 'f6.in\n') diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py index 9c56bb1..fb59c7c 100644 --- a/test/GetBuildFailures/serial.py +++ b/test/GetBuildFailures/serial.py @@ -91,9 +91,9 @@ def print_build_failures(): from SCons.Script import GetBuildFailures for bf in sorted(GetBuildFailures(), key=lambda t: str(t.node)): assert( isinstance(bf, SCons.Errors.BuildError) ) - print "BF: %%s failed (%%s): %%s" %% (bf.node, bf.status, bf.errstr) + print("BF: %%s failed (%%s): %%s" %% (bf.node, bf.status, bf.errstr)) if bf.command: - print "BF: %%s" %% " ".join(Flatten(bf.command)) + print("BF: %%s" %% " ".join(Flatten(bf.command))) import atexit atexit.register(print_build_failures) diff --git a/test/GetOption/help.py b/test/GetOption/help.py index e2eeef7..4f15fe6 100644 --- a/test/GetOption/help.py +++ b/test/GetOption/help.py @@ -34,9 +34,9 @@ test = TestSCons.TestSCons() test.write('SConstruct', """\ if GetOption('help'): - print "GetOption('help') set" + print("GetOption('help') set") else: - print "no help for you" + print("no help for you") """) test.run(arguments = '-q -Q', stdout = "no help for you\n") diff --git a/test/Libs/SharedLibraryIxes.py b/test/Libs/SharedLibraryIxes.py index 6924769..93d67ea 100644 --- a/test/Libs/SharedLibraryIxes.py +++ b/test/Libs/SharedLibraryIxes.py @@ -102,7 +102,7 @@ def nameInLib(source, lib, libname): # When using non-standard prefixes and suffixes, one has to # provide the full name of the library since scons can not know # which of the non-standard extension to use. - # + # # Note that this is not necessarily SHLIBPREFIX and # SHLIBSUFFIX. These are the ixes of the target library, not the # ixes of the library that we are linking against. @@ -130,7 +130,7 @@ def buildAndlinkAgainst(builder, target, source, method, lib, libname, **kw): # for the linker command line... if (isMingw or isCygwin) and len(lib) > 1: lib = lib[1:] - + # Apply the naming method to be tested and call the specified Builder. (source, LIBS) = method(source, lib, libname) #build = builder(target=target, source=source, LIBS=LIBS, **kw) @@ -153,8 +153,8 @@ def buildAndlinkAgainst(builder, target, source, method, lib, libname, **kw): (list(map(str,lib)), list(map(str, build[0].children())), method.__name__, libname, shlibsuffix) return build -def prog(i, - goomethod, goolibprefix, goolibsuffix, +def prog(i, + goomethod, goolibprefix, goolibsuffix, foomethod, foolibprefix, foolibsuffix): '''Build a program @@ -166,7 +166,7 @@ def prog(i, foo_name = foolibprefix+'foo'+str(i)+foolibsuffix prog_name = progprefix+'prog'+str(i)+progsuffix - print 'Prog: %d, %s, %s, %s' % (i, goo_name, foo_name, prog_name) + print('Prog: %d, %s, %s, %s' % (i, goo_name, foo_name, prog_name)) # On Windows, we have to link against the .lib file. if isWindows: @@ -179,7 +179,7 @@ def prog(i, goo_lib = env.SharedLibrary( goo_name, goo_obj, SHLIBSUFFIX=goolibsuffix) foo_lib = buildAndlinkAgainst( - env.SharedLibrary, foo_name, foo_obj, + env.SharedLibrary, foo_name, foo_obj, goomethod, goo_lib, goo_libname, SHLIBSUFFIX=foolibsuffix) prog = buildAndlinkAgainst(env.Program, prog_name, prog_obj, foomethod, foo_lib, foo_libname) @@ -199,8 +199,8 @@ for foolibprefix in prefixes: for goolibsuffix in suffixes: for goomethod in libmethods: tests.append( - (i, - goomethod, goolibprefix, goolibsuffix, + (i, + goomethod, goolibprefix, goolibsuffix, foomethod, foolibprefix, foolibsuffix)) i = i + 1 diff --git a/test/Mkdir.py b/test/Mkdir.py index 4d309bb..8ace476 100644 --- a/test/Mkdir.py +++ b/test/Mkdir.py @@ -178,7 +178,7 @@ test.write(['work3', 'sub1', 'sub11', 'SConscript'], """\ #/sub1/sub11/SConscript------------------------- Import('env test1') test11 = test1 + '/test11' -print 'test11 = ' + test11 +print('test11 = ' + test11) env.Command(Dir(test11), '', Mkdir('$TARGET')) """) diff --git a/test/NodeOps.py b/test/NodeOps.py index 5062b72..1f856c3 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -43,7 +43,7 @@ _lib = TestSCons._lib _obj = TestSCons._obj dll_ = TestSCons.dll_ _dll = TestSCons._dll - + if os.name == 'posix': os.environ['LD_LIBRARY_PATH'] = '.' if sys.platform.find('irix') > -1: @@ -71,7 +71,7 @@ if %(_E)s: exists = [N.exists() for N in Nodes] real2 = [os.path.exists(str(N)) for N in Nodes] for N,D,R,E,F in zip(Nodes, derived, real1, exists, real2): - print '%%s: %%s %%s %%s %%s'%%(N,D,R,E,F) + print('%%s: %%s %%s %%s %%s'%%(N,D,R,E,F)) foo.SharedLibrary(target = 'foo', source = 'foo%(_obj)s') bar.SharedLibrary(target = 'bar', source = 'bar%(_obj)s') diff --git a/test/ParseConfig.py b/test/ParseConfig.py index 9bcc440..efb3a75 100644 --- a/test/ParseConfig.py +++ b/test/ParseConfig.py @@ -38,17 +38,17 @@ test_config3 = test.workpath('test-config3') # File node. # It used to be returned as the 'static_libs' output of ParseConfig. test.write(test_config1, """\ -print "-I/usr/include/fum -Ibar -X -arch i386" -print "-L/usr/fax -Lfoo -lxxx abc" +print("-I/usr/include/fum -Ibar -X -arch i386") +print("-L/usr/fax -Lfoo -lxxx abc") """) test.write(test_config2, """\ -print "-L foo -L lib_dir" +print("-L foo -L lib_dir") """) # This is like what wxWidgets does on OSX w/ Universal Binaries test.write(test_config3, """\ -print "-L foo -L lib_dir -isysroot /tmp -arch ppc -arch i386" +print("-L foo -L lib_dir -isysroot /tmp -arch ppc -arch i386") """) test.write('SConstruct1', """ @@ -56,10 +56,10 @@ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '-pipe -Wall') 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 [str(x) for x in env['LIBS']] -print env['CCFLAGS'] +print(env['CPPPATH']) +print(env['LIBPATH']) +print([str(x) for x in env['LIBS']]) +print(env['CCFLAGS']) """ % locals()) test.write('SConstruct2', """ @@ -68,10 +68,10 @@ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], PYTHON = r'%(_python_)s') 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 [str(x) for x in env['LIBS']] -print env['CCFLAGS'] +print(env['CPPPATH']) +print(env['LIBPATH']) +print([str(x) for x in env['LIBS']]) +print(env['CCFLAGS']) """ % locals()) test.write('SConstruct3', """ @@ -79,10 +79,10 @@ env = Environment(CPPPATH = [], LIBPATH = [], LIBS = [], CCFLAGS = '-pipe -Wall', PYTHON = r'%(_python_)s') env.ParseConfig(r"$PYTHON %(test_config3)s --libs --cflags") -print env['CPPPATH'] -print env['LIBPATH'] -print [str(x) for x in env['LIBS']] -print env['CCFLAGS'] +print(env['CPPPATH']) +print(env['LIBPATH']) +print([str(x) for x in env['LIBS']]) +print(env['CCFLAGS']) """ % locals()) good_stdout = """\ diff --git a/test/Platform.py b/test/Platform.py index 23068c4..924dbc7 100644 --- a/test/Platform.py +++ b/test/Platform.py @@ -31,27 +31,27 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment() Platform('cygwin')(env) -print "'%s'" % env['PROGSUFFIX'] +print("'%s'" % env['PROGSUFFIX']) assert env['SHELL'] == 'sh' Platform('os2')(env) -print "'%s'" % env['PROGSUFFIX'] +print("'%s'" % env['PROGSUFFIX']) env.Platform('posix') -print "'%s'" % env['PROGSUFFIX'] +print("'%s'" % env['PROGSUFFIX']) Platform('win32')(env) -print "'%s'" % env['PROGSUFFIX'] +print("'%s'" % env['PROGSUFFIX']) SConscript('SConscript') """) test.write('SConscript', """ env = Environment() Platform('cygwin')(env) -print "'%s'" % env['LIBSUFFIX'] +print("'%s'" % env['LIBSUFFIX']) Platform('os2')(env) -print "'%s'" % env['LIBSUFFIX'] +print("'%s'" % env['LIBSUFFIX']) env.Platform('posix') -print "'%s'" % env['LIBSUFFIX'] +print("'%s'" % env['LIBSUFFIX']) Platform('win32')(env) -print "'%s'" % env['LIBSUFFIX'] +print("'%s'" % env['LIBSUFFIX']) """) expect = test.wrap_stdout(read_str = """'.exe' diff --git a/test/QT/QTFLAGS.py b/test/QT/QTFLAGS.py index 008397a..f6aa00f 100644 --- a/test/QT/QTFLAGS.py +++ b/test/QT/QTFLAGS.py @@ -136,7 +136,7 @@ int main() { """) test.run(chdir = 'work1', arguments = "mytest" + _exe) - + test.must_exist(['work1', 'mmmmocFromH.cxx'], ['work1', 'mocmocFromCpp.inl'], ['work1', 'an_ui_file.cxx'], @@ -168,15 +168,15 @@ env1 = Environment(tools=['qt'], cpppath = env1.subst('$CPPPATH') if os.path.normpath(cpppath) != os.path.join(r'%(QTDIR)s', 'h64'): - print cpppath + print(cpppath) Exit(1) libpath = env1.subst('$LIBPATH') if os.path.normpath(libpath) != os.path.join(r'%(QTDIR)s', 'lib64'): - print libpath + print(libpath) Exit(2) qt_moc = env1.subst('$QT_MOC') if os.path.normpath(qt_moc) != os.path.join(r'%(QTDIR)s', 'bin64', 'moc'): - print qt_moc + print(qt_moc) Exit(3) env2 = Environment(tools=['default', 'qt'], diff --git a/test/QT/manual.py b/test/QT/manual.py index d911fb3..1f140ae 100644 --- a/test/QT/manual.py +++ b/test/QT/manual.py @@ -58,7 +58,7 @@ env.Ignore( moc, moc ) sources.extend(env.Uic(['include/uic_fff.hpp', 'fff.cpp', 'fff.moc.cpp'], 'ui/fff.ui')[1:]) -print list(map(str,sources)) +print(list(map(str,sources))) env.Program(target='aaa', source=sources, CPPPATH=['$CPPPATH', './include'], @@ -68,7 +68,7 @@ env.Program(target='aaa', test.write('aaa.cpp', r""" #include "aaa.h" """) - + test.write(['include', 'aaa.h'], r""" #include "my_qobject.h" void aaa(void) Q_OBJECT; @@ -91,7 +91,7 @@ void ccc(void) test.write('ddd.cpp', r""" #include "ddd.h" """) - + test.write(['include', 'ddd.h'], r""" #include "my_qobject.h" void ddd(void) Q_OBJECT; diff --git a/test/tool_args.py b/test/tool_args.py index 692f6a5..b0f69ef 100644 --- a/test/tool_args.py +++ b/test/tool_args.py @@ -38,13 +38,13 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ # Test passing kw args to Tool constructor env1 = Environment(tools=[Tool('FooTool', toolpath=['.'], kw1='kw1val')]) -print "env1['TOOL_FOO'] =", env1.get('TOOL_FOO') -print "env1['kw1'] =", env1.get('kw1') +print("env1['TOOL_FOO'] =", env1.get('TOOL_FOO')) +print("env1['kw1'] =", env1.get('kw1')) # Test apply_tools taking a list of (name, kwargs_dict) env2 = Environment(tools=[('FooTool', {'kw2':'kw2val'})], toolpath=['.']) -print "env2['TOOL_FOO'] =", env2.get('TOOL_FOO') -print "env2['kw2'] =", env2.get('kw2') +print("env2['TOOL_FOO'] =", env2.get('TOOL_FOO')) +print("env2['kw2'] =", env2.get('kw2')) """) diff --git a/test/toolpath/basic.py b/test/toolpath/basic.py index e1e6f3c..eedd06e 100644 --- a/test/toolpath/basic.py +++ b/test/toolpath/basic.py @@ -33,63 +33,63 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ def foo(env): env['TOOL_FOO'] = 1 - + env1 = Environment(tools=[foo, 'bar'], toolpath=['tools']) -print "env1['TOOL_FOO'] =", env1.get('TOOL_FOO') -print "env1['TOOL_BAR'] =", env1.get('TOOL_BAR') +print("env1['TOOL_FOO'] =", env1.get('TOOL_FOO')) +print("env1['TOOL_BAR'] =", env1.get('TOOL_BAR')) # pick a built-in tool with pretty simple behavior env2 = Environment(tools=['SCCS']) -print "env2['SCCS'] =", env2.get('SCCS') -print "env2['TOOL_SCCS1'] =", env2.get('TOOL_SCCS1') -print "env2['TOOL_SCCS2'] =", env2.get('TOOL_SCCS2') +print("env2['SCCS'] =", env2.get('SCCS') +print("env2['TOOL_SCCS1'] =", env2.get('TOOL_SCCS1')) +print("env2['TOOL_SCCS2'] =", env2.get('TOOL_SCCS2')) env3 = Environment(tools=['SCCS'], toolpath=['.']) -print "env3['SCCS'] =", env3.get('SCCS') -print "env3['TOOL_SCCS1'] =", env3.get('TOOL_SCCS1') -print "env3['TOOL_SCCS2'] =", env3.get('TOOL_SCCS2') +print("env3['SCCS'] =", env3.get('SCCS') +print("env3['TOOL_SCCS1'] =", env3.get('TOOL_SCCS1')) +print("env3['TOOL_SCCS2'] =", env3.get('TOOL_SCCS2')) env4 = Environment(tools=['SCCS'], toolpath=['tools']) -print "env4['SCCS'] =", env4.get('SCCS') -print "env4['TOOL_SCCS1'] =", env4.get('TOOL_SCCS1') -print "env4['TOOL_SCCS2'] =", env4.get('TOOL_SCCS2') +print("env4['SCCS'] =", env4.get('SCCS')) +print("env4['TOOL_SCCS1'] =", env4.get('TOOL_SCCS1')) +print("env4['TOOL_SCCS2'] =", env4.get('TOOL_SCCS2')) env5 = Environment(tools=['SCCS'], toolpath=['tools', '.']) -print "env5['SCCS'] =", env5.get('SCCS') -print "env5['TOOL_SCCS1'] =", env5.get('TOOL_SCCS1') -print "env5['TOOL_SCCS2'] =", env5.get('TOOL_SCCS2') +print("env5['SCCS'] =", env5.get('SCCS')) +print("env5['TOOL_SCCS1'] =", env5.get('TOOL_SCCS1')) +print("env5['TOOL_SCCS2'] =", env5.get('TOOL_SCCS2')) env6 = Environment(tools=['SCCS'], toolpath=['.', 'tools']) -print "env6['SCCS'] =", env6.get('SCCS') -print "env6['TOOL_SCCS1'] =", env6.get('TOOL_SCCS1') -print "env6['TOOL_SCCS2'] =", env6.get('TOOL_SCCS2') +print("env6['SCCS'] =", env6.get('SCCS')) +print("env6['TOOL_SCCS1'] =", env6.get('TOOL_SCCS1')) +print("env6['TOOL_SCCS2'] =", env6.get('TOOL_SCCS2')) env7 = Environment(TOOLPATH="tools", tools=['SCCS'], toolpath=['$TOOLPATH']) -print "env7['SCCS'] =", env7.get('SCCS') -print "env7['TOOL_SCCS1'] =", env7.get('TOOL_SCCS1') -print "env7['TOOL_SCCS2'] =", env7.get('TOOL_SCCS2') +print("env7['SCCS'] =", env7.get('SCCS')) +print("env7['TOOL_SCCS1'] =", env7.get('TOOL_SCCS1')) +print("env7['TOOL_SCCS2'] =", env7.get('TOOL_SCCS2')) env8 = Environment(tools=[]) env8.Tool('SCCS', toolpath=['tools']) -print "env8['SCCS'] =", env8.get('SCCS') -print "env8['TOOL_SCCS1'] =", env8.get('TOOL_SCCS1') -print "env8['TOOL_SCCS2'] =", env8.get('TOOL_SCCS2') +print("env8['SCCS'] =", env8.get('SCCS')) +print("env8['TOOL_SCCS1'] =", env8.get('TOOL_SCCS1')) +print("env8['TOOL_SCCS2'] =", env8.get('TOOL_SCCS2')) env9 = Environment(tools=[]) Tool('SCCS', toolpath=['tools'])(env9) -print "env9['SCCS'] =", env9.get('SCCS') -print "env9['TOOL_SCCS1'] =", env9.get('TOOL_SCCS1') -print "env9['TOOL_SCCS2'] =", env9.get('TOOL_SCCS2') +print("env9['SCCS'] =", env9.get('SCCS')) +print("env9['TOOL_SCCS1'] =", env9.get('TOOL_SCCS1')) +print("env9['TOOL_SCCS2'] =", env9.get('TOOL_SCCS2')) env0 = Environment(TOOLPATH='tools', tools=[]) env0.Tool('SCCS', toolpath=['$TOOLPATH']) -print "env0['SCCS'] =", env0.get('SCCS') -print "env0['TOOL_SCCS1'] =", env0.get('TOOL_SCCS1') -print "env0['TOOL_SCCS2'] =", env0.get('TOOL_SCCS2') +print("env0['SCCS'] =", env0.get('SCCS')) +print("env0['TOOL_SCCS1'] =", env0.get('TOOL_SCCS1')) +print("env0['TOOL_SCCS2'] =", env0.get('TOOL_SCCS2')) base = Environment(tools=[], toolpath=['tools']) derived = base.Clone(tools=['bar']) -print "derived['TOOL_BAR'] =", derived.get('TOOL_BAR') +print("derived['TOOL_BAR'] =", derived.get('TOOL_BAR')) """) test.write('SCCS.py', r"""\ -- cgit v0.12 From 7a6018983cf716374f2c7bf3b48e3f386bcaadd9 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Fri, 1 Jan 2016 16:21:10 +0000 Subject: Some more statement to function transforms. --- QMTest/TestSCons.py | 12 ++++++------ test/Repository/Default.py | 2 +- test/Repository/Local.py | 4 ++-- test/Repository/VariantDir.py | 2 +- test/Repository/option-c.py | 2 +- test/Repository/option-n.py | 2 +- test/Repository/targets.py | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index d98b155..3857da5 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -929,7 +929,7 @@ if ARGUMENTS.get('variant_dir', 0): else: builddir = 'build' VariantDir(builddir, '.', duplicate=dup) - print builddir, dup + print(builddir, dup) sconscript = Dir(builddir).File('SConscript') else: sconscript = File('SConscript') @@ -1142,12 +1142,12 @@ except AttributeError: try: import distutils.sysconfig exec_prefix = distutils.sysconfig.EXEC_PREFIX - print distutils.sysconfig.get_python_inc() - print os.path.join(exec_prefix, 'libs') + print(distutils.sysconfig.get_python_inc()) + print(os.path.join(exec_prefix, 'libs')) except: - print os.path.join(sys.prefix, 'include', py_ver) - print os.path.join(sys.prefix, 'lib', py_ver, 'config') -print py_ver + print(os.path.join(sys.prefix, 'include', py_ver) + print(os.path.join(sys.prefix, 'lib', py_ver, 'config')) +print(py_ver) """) return [python] + self.stdout().strip().split('\n') diff --git a/test/Repository/Default.py b/test/Repository/Default.py index 127c29a..44aecfb 100644 --- a/test/Repository/Default.py +++ b/test/Repository/Default.py @@ -46,7 +46,7 @@ test.write(['repository', 'SConstruct'], r""" def copy(env, source, target): source = str(source[0]) target = str(target[0]) - print 'copy() < %s > %s' % (source, target) + print('copy() < %s > %s' % (source, target)) open(target, "wb").write(open(source, "rb").read()) Build = Builder(action=copy) diff --git a/test/Repository/Local.py b/test/Repository/Local.py index 1b63345..ea03281 100644 --- a/test/Repository/Local.py +++ b/test/Repository/Local.py @@ -48,7 +48,7 @@ test.write(['repository', 'SConstruct'], r""" def copy(env, source, target): source = str(source[0]) target = str(target[0]) - print 'copy() < %s > %s' % (source, target) + print('copy() < %s > %s' % (source, target)) open(target, "wb").write(open(source, "rb").read()) Build = Builder(action=copy) @@ -65,7 +65,7 @@ SConscript('build/SConscript') test.write(['repository', 'src', 'SConscript'], r""" def bbb_copy(env, source, target): target = str(target[0]) - print 'bbb_copy()' + print('bbb_copy()') open(target, "wb").write(open('build/bbb.1', "rb").read()) Import("env") diff --git a/test/Repository/VariantDir.py b/test/Repository/VariantDir.py index ec723c8..0258ff5 100644 --- a/test/Repository/VariantDir.py +++ b/test/Repository/VariantDir.py @@ -48,7 +48,7 @@ test.write(['repository', 'src', 'SConscript'], r""" def cat(env, source, target): target = str(target[0]) source = list(map(str, source)) - print 'cat(%s) > %s' % (source, target) + print('cat(%s) > %s' % (source, target)) f = open(target, "wb") for src in source: f.write(open(src, "rb").read()) diff --git a/test/Repository/option-c.py b/test/Repository/option-c.py index ea989c2..c06c7d8 100644 --- a/test/Repository/option-c.py +++ b/test/Repository/option-c.py @@ -65,7 +65,7 @@ test.write(['repository', 'SConstruct'], r""" def copy(env, source, target): source = str(source[0]) target = str(target[0]) - print 'copy() < %s > %s' % (source, target) + print('copy() < %s > %s' % (source, target)) open(target, "wb").write(open(source, "rb").read()) Build = Builder(action=copy) diff --git a/test/Repository/option-n.py b/test/Repository/option-n.py index 220baad..2a0ae5d 100644 --- a/test/Repository/option-n.py +++ b/test/Repository/option-n.py @@ -48,7 +48,7 @@ test.write(['repository', 'SConstruct'], r""" def copy(env, source, target): source = str(source[0]) target = str(target[0]) - print 'copy() < %s > %s' % (source, target) + print('copy() < %s > %s' % (source, target)) open(target, "wb").write(open(source, "rb").read()) Build = Builder(action=copy) diff --git a/test/Repository/targets.py b/test/Repository/targets.py index 62f4785..0fbc896 100644 --- a/test/Repository/targets.py +++ b/test/Repository/targets.py @@ -43,7 +43,7 @@ test.write(['repository', 'SConstruct'], """ def cat(env, source, target): target = str(target[0]) source = list(map(str, source)) - print 'cat(%s) > %s' % (source, target) + print('cat(%s) > %s' % (source, target)) f = open(target, "wb") for src in source: f.write(open(src, "rb").read()) -- cgit v0.12 From 543495e2fe3353396225b973e7fe64fb8e566f64 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 10 Jan 2016 15:21:22 +0000 Subject: Remove relative import. --- src/engine/SCons/cppTests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py index 28a1f5e..40236e4 100644 --- a/src/engine/SCons/cppTests.py +++ b/src/engine/SCons/cppTests.py @@ -31,7 +31,7 @@ import unittest import TestUnit -from . import cpp +import cpp -- cgit v0.12 From 2bffdfc4addbc1565c2f21f35b73ab09ef4f3105 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 10 Jan 2016 15:29:55 +0000 Subject: Remove spurious space causing test fail. --- test/CPPDEFINES/append.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CPPDEFINES/append.py b/test/CPPDEFINES/append.py index 432ab64..14ea7b3 100644 --- a/test/CPPDEFINES/append.py +++ b/test/CPPDEFINES/append.py @@ -67,7 +67,7 @@ for (t1, c1) in cases: env=Environment(CPPDEFINES = c1, CPPDEFPREFIX='-D') env.Append(CPPDEFINES = c2) final=env.subst('$_CPPDEFFLAGS',source="src", target="tgt") - print('Append: \\n\\tresult=%s\\n\\tfinal=%s'%\\ + print('Append:\\n\\tresult=%s\\n\\tfinal=%s'%\\ (env['CPPDEFINES'], final)) env=Environment(CPPDEFINES = c1, CPPDEFPREFIX='-D') env.AppendUnique(CPPDEFINES = c2) -- cgit v0.12 From 31c24bc7e328fb2e8d75893c675f63e37dc2e6dc Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 10 Jan 2016 15:55:12 +0000 Subject: Refactor of test, but it still fails due to missing output from SCons. --- test/Clean/mkfifo.py | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/test/Clean/mkfifo.py b/test/Clean/mkfifo.py index 0ef7662..01e4d98 100644 --- a/test/Clean/mkfifo.py +++ b/test/Clean/mkfifo.py @@ -38,35 +38,40 @@ test = TestSCons.TestSCons() if not hasattr(os, 'mkfifo'): test.skip_test('No os.mkfifo() function; skipping test\n') +test_dir_name = 'testdir' +pipe_path = os.path.join(test_dir_name, 'namedpipe') + test.write('SConstruct', """\ -Execute(Mkdir("testdir")) -dir = Dir("testdir") -Clean(dir, 'testdir') -""") +Execute(Mkdir("{0}")) +dir = Dir("{0}") +Clean(dir, '{0}') +""".format(test_dir_name)) + +test.run(arguments='-Q -q', stdout='Mkdir("{0}")\n'.format(test_dir_name)) -test.run(arguments='-Q -q', stdout='Mkdir("testdir")\n') +os.mkfifo(pipe_path) -os.mkfifo('testdir/namedpipe') +test.must_exist(test.workpath(pipe_path)) expect1 = """\ -Mkdir("testdir") -Path '%s' exists but isn't a file or directory. -scons: Could not remove 'testdir': Directory not empty -""" % os.path.join('testdir', 'namedpipe') +Mkdir("{0}") +Path '{1}' exists but isn't a file or directory. +scons: Could not remove '{0}': Directory not empty +""".format(test_dir_name, pipe_path) expect2 = """\ -Mkdir("testdir") -Path '%s' exists but isn't a file or directory. -scons: Could not remove 'testdir': File exists -""" % os.path.join('testdir', 'namedpipe') +Mkdir("{0}") +Path '{1}' exists but isn't a file or directory. +scons: Could not remove '{0}': File exists +""".format(test_dir_name, pipe_path) test.run(arguments='-c -Q -q') +test.must_exist(test.workpath(pipe_path)) + if test.stdout() not in [expect1, expect2]: test.diff(expect1, test.stdout(), 'STDOUT ') test.fail_test() - -test.must_exist(test.workpath('testdir/namedpipe')) test.pass_test() -- cgit v0.12 From 82857f4e863cc754cd02e4aee8507d888afc377e Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 10 Jan 2016 17:37:41 +0000 Subject: Amend the message. --- test/D/SharedObjects/Common/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/D/SharedObjects/Common/common.py b/test/D/SharedObjects/Common/common.py index e81cf5b..280c6f2 100644 --- a/test/D/SharedObjects/Common/common.py +++ b/test/D/SharedObjects/Common/common.py @@ -46,7 +46,7 @@ def testForTool(tool): test.skip_test("Required executable for tool '{0}' not found, skipping test.\n".format(tool)) if tool == 'gdc': - test.skip_test('gdc does not, as at version 4.9.1, support shared libraries.\n') + test.skip_test('gdc in GCC distribution does not, as at version 5.3.1, support shared libraries.\n') if tool == 'dmd' and Base()['DC'] == 'gdmd': test.skip_test('gdmd does not recognize the -shared option so cannot support linking of shared objects.\n') -- cgit v0.12 From 79d11adfb4ae11260ab644e8968843058e091ab4 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Sun, 10 Jan 2016 18:07:35 +0000 Subject: Output changed so changed expected results. --- src/engine/SCons/ActionTests.py | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index f56948f..3eee4b6 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -556,7 +556,7 @@ class _ActionActionTestCase(unittest.TestCase): assert isinstance(source, list), type(source) return 9 b = SCons.Action.Action([firstfunc, execfunc, lastfunc]) - + sio = io.StringIO() sys.stdout = sio result = a("out", "in", env) @@ -699,7 +699,7 @@ class _ActionActionTestCase(unittest.TestCase): env['PRINT_CMD_LINE_FUNC'] = my_print_cmd_line a("output", "input", env) assert result == ["execfunc(['output'], ['input'])"], result - + finally: sys.stdout = save_stdout @@ -942,7 +942,7 @@ class CommandActionTestCase(unittest.TestCase): act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES', cmdstr='cmdstr\t$TARGETS\n$SOURCES ') - + s = act.strfunction([], [], env) assert s == 'cmdstr\t\n ', s s = act.strfunction([t1], [s1], env) @@ -1429,13 +1429,13 @@ class CommandGeneratorActionTestCase(unittest.TestCase): pass func_matches = [ - b"0,0,0,0,(),(),(d\000\000S),(),()", - b"0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", ] - + meth_matches = [ - b"1,1,0,0,(),(),(d\000\000S),(),()", - b"1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1, 1, 0, 0,(),(),(d\000\000S),(),()", + b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()", ] def f_global(target, source, env, for_signature): @@ -1588,13 +1588,13 @@ class FunctionActionTestCase(unittest.TestCase): pass func_matches = [ - b"0,0,0,0,(),(),(d\000\000S),(),()", - b"0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", ] - + meth_matches = [ - b"1,1,0,0,(),(),(d\000\000S),(),()", - b"1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1, 1, 0, 0,(),(),(d\000\000S),(),()", + b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()", ] def factory(act, **kw): @@ -1801,13 +1801,13 @@ class LazyActionTestCase(unittest.TestCase): pass func_matches = [ - b"0,0,0,0,(),(),(d\000\000S),(),()", - b"0,0,0,0,(),(),(d\x00\x00S),(),()", + b"0, 0, 0, 0,(),(),(d\000\000S),(),()", + b"0, 0, 0, 0,(),(),(d\x00\x00S),(),()", ] - + meth_matches = [ - b"1,1,0,0,(),(),(d\000\000S),(),()", - b"1,1,0,0,(),(),(d\x00\x00S),(),()", + b"1, 1, 0, 0,(),(),(d\000\000S),(),()", + b"1, 1, 0, 0,(),(),(d\x00\x00S),(),()", ] def factory(act, **kw): @@ -1999,16 +1999,16 @@ class ActionCompareTestCase(unittest.TestCase): especially two builders that can generate the same suffix, where one of the builders has a suffix dictionary with a None key.""" - + foo = SCons.Builder.Builder(action = '$FOO', suffix = '.foo') bar = SCons.Builder.Builder(action = {}, suffix={None:'.bar'}) bar.add_action('.cow', "$MOO") dog = SCons.Builder.Builder(suffix = '.bar') - + env = Environment( BUILDERS = {'FOO' : foo, 'BAR' : bar, 'DOG' : dog} ) - + assert foo.get_name(env) == 'FOO', foo.get_name(env) assert bar.get_name(env) == 'BAR', bar.get_name(env) assert dog.get_name(env) == 'DOG', dog.get_name(env) -- cgit v0.12 From 36d36e8dbf9e43c412f7a52a38dc1f9d9e8bb078 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Sun, 24 Jan 2016 16:36:12 +0000 Subject: Resolving a batch of failing tests for python 2.7. Note: please evaluate python 3.X compliance. --- src/engine/SCons/Script/Main.py | 6 ++---- test/Split.py | 16 ++++++++-------- test/TARGETS.py | 28 ++++++++++++++-------------- test/Variables/BoolVariable.py | 4 ++-- test/Variables/EnumVariable.py | 6 +++--- test/Variables/PackageVariable.py | 2 +- test/Variables/PathVariable.py | 14 +++++++------- test/Variables/Variables.py | 26 +++++++++++++------------- test/Variables/chdir.py | 2 +- test/Variables/help.py | 4 ++-- test/Variables/import.py | 2 +- test/WhereIs.py | 24 ++++++++++++------------ test/_CPPINCFLAGS.py | 6 +++--- test/custom-concat.py | 2 +- test/exitfns.py | 6 +++--- test/import.py | 7 +++---- test/no-arguments.py | 2 +- test/option--C.py | 6 +++--- test/option--I.py | 4 ++-- test/option-f.py | 8 ++++---- test/overrides.py | 6 +++--- test/preserve-source.py | 2 +- test/site_scons/basic.py | 4 ++-- test/site_scons/no-site-dir.py | 4 ++-- test/site_scons/override.py | 2 +- test/site_scons/site-dir.py | 4 ++-- test/site_scons/site_init.py | 8 ++++---- 27 files changed, 101 insertions(+), 104 deletions(-) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 7cc7d47..997d701 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,8 +10,6 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ -from __future__ import print_function - unsupported_python_version = (2, 6, 0) deprecated_python_version = (2, 7, 0) @@ -330,7 +328,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): except SCons.Errors.UserError as e: print(e) except (IOError, OSError) as e: - print_("scons: Could not remove '%s':" % pathstr, e.strerror) + print("scons: Could not remove '%s':" % pathstr, e.strerror) def _get_files_to_clean(self): result = [] @@ -794,7 +792,7 @@ def _load_all_site_scons_dirs(topdir, verbose=None): dirs=sysdirs + [topdir] for d in dirs: if verbose: # this is used by unit tests. - print_("Loading site dir ", d) + print("Loading site dir ", d) _load_site_scons_dir(d) def test_load_all_site_scons_dirs(d): diff --git a/test/Split.py b/test/Split.py index e98e299..c0533fa 100644 --- a/test/Split.py +++ b/test/Split.py @@ -30,19 +30,19 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment(BBB = 'bbb', CCC = 'ccc') -print Split('aaa') -print Split('aaa $BBB') -print env.Split('bbb $CCC') -print env.Split('$BBB ccc') -print Split(['ddd', 'eee']) +print(Split('aaa')) +print(Split('aaa $BBB')) +print(env.Split('bbb $CCC')) +print(env.Split('$BBB ccc')) +print(Split(['ddd', 'eee'])) SConscript('SConscript') """) test.write('SConscript', """ env = Environment(FFF='fff', JJJ='jjj') -print env.Split('${FFF}.f') -print Split('ggg hhh') -print env.Split(['iii', '$JJJ']) +print(env.Split('${FFF}.f')) +print(Split('ggg hhh')) +print(env.Split(['iii', '$JJJ'])) """) expect = """\ diff --git a/test/TARGETS.py b/test/TARGETS.py index 5b36c49..0ffc3b6 100644 --- a/test/TARGETS.py +++ b/test/TARGETS.py @@ -35,11 +35,11 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ -print COMMAND_LINE_TARGETS -print list(map(str, BUILD_TARGETS)) +print(COMMAND_LINE_TARGETS) +print(list(map(str, BUILD_TARGETS))) Default('.') -print COMMAND_LINE_TARGETS -print list(map(str, BUILD_TARGETS)) +print(COMMAND_LINE_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 list(map(str, DEFAULT_TARGETS)) -print list(map(str, BUILD_TARGETS)) +print(list(map(str, DEFAULT_TARGETS))) +print(list(map(str, BUILD_TARGETS))) Default('aaa') -print list(map(str, DEFAULT_TARGETS)) -print list(map(str, BUILD_TARGETS)) +print(list(map(str, DEFAULT_TARGETS))) +print(list(map(str, BUILD_TARGETS))) env.Default('bbb') -print list(map(str, DEFAULT_TARGETS)) -print list(map(str, BUILD_TARGETS)) +print(list(map(str, DEFAULT_TARGETS))) +print(list(map(str, BUILD_TARGETS))) env.Default(None) -print list(map(str, DEFAULT_TARGETS)) -print list(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 list(map(str, BUILD_TARGETS)) +print(list(map(str, BUILD_TARGETS))) SConscript('SConscript') -print list(map(str, BUILD_TARGETS)) +print(list(map(str, BUILD_TARGETS))) """) test.write('SConscript', """\ diff --git a/test/Variables/BoolVariable.py b/test/Variables/BoolVariable.py index 365567e..d259984 100644 --- a/test/Variables/BoolVariable.py +++ b/test/Variables/BoolVariable.py @@ -57,8 +57,8 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['warnings'] -print env['profile'] +print(env['warnings']) +print(env['profile']) Default(env.Alias('dummy', None)) """) diff --git a/test/Variables/EnumVariable.py b/test/Variables/EnumVariable.py index c04b396..cf35b9b 100644 --- a/test/Variables/EnumVariable.py +++ b/test/Variables/EnumVariable.py @@ -66,9 +66,9 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['debug'] -print env['guilib'] -print env['some'] +print(env['debug']) +print(env['guilib']) +print(env['some']) Default(env.Alias('dummy', None)) """) diff --git a/test/Variables/PackageVariable.py b/test/Variables/PackageVariable.py index 322bc9b..b3fd10a 100644 --- a/test/Variables/PackageVariable.py +++ b/test/Variables/PackageVariable.py @@ -59,7 +59,7 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['x11'] +print(env['x11']) Default(env.Alias('dummy', None)) """) diff --git a/test/Variables/PathVariable.py b/test/Variables/PathVariable.py index bfe82ba..753aa11 100644 --- a/test/Variables/PathVariable.py +++ b/test/Variables/PathVariable.py @@ -64,9 +64,9 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['qtdir'] -print env['qt_libraries'] -print env.subst('$qt_libraries') +print(env['qtdir']) +print(env['qt_libraries']) +print(env.subst('$qt_libraries')) Default(env.Alias('dummy', None)) """ % (workpath, os.path.join('$qtdir', 'lib') )) @@ -132,7 +132,7 @@ opts.AddVariables( env = Environment(variables=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) @@ -165,7 +165,7 @@ opts.AddVariables( env = Environment(variables=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_file) @@ -211,7 +211,7 @@ opts.AddVariables( env = Environment(variables=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) @@ -259,7 +259,7 @@ opts.AddVariables( env = Environment(variables=opts) -print env['X'] +print(env['X']) Default(env.Alias('dummy', None)) """ % default_subdir) diff --git a/test/Variables/Variables.py b/test/Variables/Variables.py index d0bf432..1c60635 100644 --- a/test/Variables/Variables.py +++ b/test/Variables/Variables.py @@ -30,8 +30,8 @@ test = TestSCons.TestSCons() test.write('SConstruct', """ env = Environment() -print env['CC'] -print " ".join(env['CCFLAGS']) +print(env['CC']) +print(" ".join(env['CCFLAGS'])) Default(env.Alias('dummy', None)) """) test.run() @@ -99,12 +99,12 @@ env = Environment(variables=opts, tools=['default', test_tool]) Help('Variables settable in custom.py or on the command line:\\n' + opts.GenerateHelpText(env)) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] -print env['CC'] -print " ".join(env['CCFLAGS']) -print env['VALIDATE'] -print env['valid_key'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) +print(env['CC']) +print(" ".join(env['CCFLAGS'])) +print(env['VALIDATE']) +print(env['valid_key']) # unspecified variables should not be set: assert 'UNSPECIFIED' not in env @@ -220,8 +220,8 @@ opts.Add('UNSPECIFIED', env = Environment(variables = opts) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) opts.Save('variables.saved', env) """) @@ -276,9 +276,9 @@ opts.Add('LISTOPTION_TEST', env = Environment(variables = opts) -print env['RELEASE_BUILD'] -print env['DEBUG_BUILD'] -print env['LISTOPTION_TEST'] +print(env['RELEASE_BUILD']) +print(env['DEBUG_BUILD']) +print(env['LISTOPTION_TEST']) opts.Save('variables.saved', env) """) diff --git a/test/Variables/chdir.py b/test/Variables/chdir.py index 621e166..2d097d5 100644 --- a/test/Variables/chdir.py +++ b/test/Variables/chdir.py @@ -46,7 +46,7 @@ SConscript_contents = """\ Import("opts") env = Environment() opts.Update(env) -print "VARIABLE =", repr(env['VARIABLE']) +print("VARIABLE =", repr(env['VARIABLE'])) """ test.write(['bin', 'opts.cfg'], """\ diff --git a/test/Variables/help.py b/test/Variables/help.py index f04f962..bee6011 100644 --- a/test/Variables/help.py +++ b/test/Variables/help.py @@ -81,8 +81,8 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['warnings'] -print env['profile'] +print(env['warnings']) +print(env['profile']) Default(env.Alias('dummy', None)) """ % locals()) diff --git a/test/Variables/import.py b/test/Variables/import.py index 7cdd274..2da670a 100644 --- a/test/Variables/import.py +++ b/test/Variables/import.py @@ -48,7 +48,7 @@ SConscript_contents = """\ Import("opts") env = Environment() opts.Update(env) -print "VARIABLE =", env.get('VARIABLE') +print("VARIABLE =", env.get('VARIABLE')) """ test.write(['bin', 'opts.cfg'], """\ diff --git a/test/WhereIs.py b/test/WhereIs.py index 07c3f6c..c765848 100644 --- a/test/WhereIs.py +++ b/test/WhereIs.py @@ -67,14 +67,14 @@ pathdirs_1243 = [ test.workpath('sub1'), test.write('SConstruct', """ SConscript('%s') env = Environment() -print WhereIs('xxx.exe') -print WhereIs('xxx.exe', %s) -print env.WhereIs('xxx.exe', %s) -print WhereIs('xxx.exe', %s) -print WhereIs('xxx.exe', %s) -print WhereIs('xxx.exe', %s, reject=%s) +print(WhereIs('xxx.exe')) +print(WhereIs('xxx.exe', %s)) +print(env.WhereIs('xxx.exe', %s)) +print(WhereIs('xxx.exe', %s)) +print(WhereIs('xxx.exe', %s)) +print(WhereIs('xxx.exe', %s, reject=%s)) env.Replace( XXXNAME='xxx.exe' ) -print env.WhereIs( '$XXXNAME', %s ) +print(env.WhereIs( '$XXXNAME', %s )) """ % (subdir_SConscript, repr(os.pathsep.join(pathdirs_1234)), repr(os.pathsep.join(pathdirs_1243)), @@ -87,11 +87,11 @@ print env.WhereIs( '$XXXNAME', %s ) test.write(subdir_SConscript, """ env = Environment() -print WhereIs('xxx.exe') -print WhereIs('xxx.exe', %s) -print env.WhereIs('xxx.exe', %s) -print WhereIs('xxx.exe', %s) -print WhereIs('xxx.exe', %s) +print(WhereIs('xxx.exe')) +print(WhereIs('xxx.exe', %s)) +print(env.WhereIs('xxx.exe', %s)) +print(WhereIs('xxx.exe', %s)) +print(WhereIs('xxx.exe', %s)) """ % (repr(os.pathsep.join(pathdirs_1234)), repr(os.pathsep.join(pathdirs_1243)), repr(pathdirs_1234), diff --git a/test/_CPPINCFLAGS.py b/test/_CPPINCFLAGS.py index ccf5e79..c5096ba 100644 --- a/test/_CPPINCFLAGS.py +++ b/test/_CPPINCFLAGS.py @@ -39,9 +39,9 @@ env=Environment(CPPPATH=['tmp'], INCPREFIX='-I') d=Entry('foo.d') e=Entry('foo.e') f=File('foo.f') -print env.subst('$_CPPINCFLAGS', target=e, source=f) -print env.subst('$_CPPINCFLAGS', target=d, source=f) -print env.subst('$_CPPINCFLAGS', target=f, source=d) +print(env.subst('$_CPPINCFLAGS', target=e, source=f)) +print(env.subst('$_CPPINCFLAGS', target=d, source=f)) +print(env.subst('$_CPPINCFLAGS', target=f, source=d)) """) expect = """\ diff --git a/test/custom-concat.py b/test/custom-concat.py index 56c7f64..730e6cd 100644 --- a/test/custom-concat.py +++ b/test/custom-concat.py @@ -44,7 +44,7 @@ env1 = Environment(MYFLAGS=myflags, _concat = my_concat1, MYPREFIX='p', MYSUFFIX='s', STRIPPREFIX='xxx', STRIPSUFFIX='yyy', LIST=['a', 'xxxb', 'cyyy', 'd']) -print env1.subst('$MYFLAGS') +print(env1.subst('$MYFLAGS')) """) expect = test.wrap_stdout(read_str = "mypas1 mypbs1 mypcs1 mypds1\n", diff --git a/test/exitfns.py b/test/exitfns.py index f64969b..d1bda3a 100644 --- a/test/exitfns.py +++ b/test/exitfns.py @@ -32,11 +32,11 @@ sconstruct = """ from SCons.exitfuncs import * def x1(): - print "running x1" + print("running x1") def x2(n): - print "running x2(%s)" % repr(n) + print("running x2(%s)" % repr(n)) def x3(n, kwd=None): - print "running x3(%s, kwd=%s)" % (repr(n), repr(kwd)) + print("running x3(%s, kwd=%s)" % (repr(n), repr(kwd))) register(x3, "no kwd args") register(x1) diff --git a/test/import.py b/test/import.py index d1e1ecf..c23657a 100644 --- a/test/import.py +++ b/test/import.py @@ -21,7 +21,6 @@ # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -64,7 +63,7 @@ platforms = [ for platform in platforms: test.write('SConstruct', """ -print "Platform %(platform)s" +print("Platform %(platform)s") env = Environment(platform = '%(platform)s') import SCons.Platform.%(platform)s x = SCons.Platform.%(platform)s.generate @@ -151,7 +150,7 @@ error_output = { # An SConstruct for importing Tool names that have illegal characters # for Python variable names. indirect_import = """\ -print "Tool %(tool)s (indirect)" +print("Tool %(tool)s (indirect)") env = Environment(tools = ['%(tool)s']) SCons = __import__('SCons.Tool.%(tool)s', globals(), locals(), []) @@ -162,7 +161,7 @@ m.generate(env) # An SConstruct for importing Tool names "normally." direct_import = """\ -print "Tool %(tool)s (direct)" +print("Tool %(tool)s (direct)") env = Environment(tools = ['%(tool)s']) import SCons.Tool.%(tool)s diff --git a/test/no-arguments.py b/test/no-arguments.py index e447ff6..953d827 100644 --- a/test/no-arguments.py +++ b/test/no-arguments.py @@ -40,7 +40,7 @@ test.write('SConstruct', r""" def cat(env, source, target): target = str(target[0]) source = list(map(str, source)) - print 'cat(%s) > %s' % (source, target) + print('cat(%s) > %s' % (source, target)) f = open(target, "wb") for src in source: f.write(open(src, "rb").read()) diff --git a/test/option--C.py b/test/option--C.py index 27f4950..1df3c1a 100644 --- a/test/option--C.py +++ b/test/option--C.py @@ -51,18 +51,18 @@ test.subdir('sub', ['sub', 'dir']) test.write('SConstruct', """ import os -print "SConstruct", os.getcwd() +print("SConstruct", os.getcwd()) """) test.write(['sub', 'SConstruct'], """ import os -print GetBuildPath('..') +print(GetBuildPath('..')) """) test.write(['sub', 'dir', 'SConstruct'], """ import os env = Environment(FOO='foo', BAR='bar') -print env.GetBuildPath('../$FOO/$BAR') +print(env.GetBuildPath('../$FOO/$BAR')) """) test.run(arguments = '-C sub .', diff --git a/test/option--I.py b/test/option--I.py index d65349a..0ca262d 100644 --- a/test/option--I.py +++ b/test/option--I.py @@ -44,9 +44,9 @@ variable = "sub2/bar" test.write('SConstruct', """ import foo -print foo.variable +print(foo.variable) import bar -print bar.variable +print(bar.variable) """) test.run(arguments = '-I sub1 -I sub2 .', diff --git a/test/option-f.py b/test/option-f.py index 2a238d3..9fd1a57 100644 --- a/test/option-f.py +++ b/test/option-f.py @@ -36,17 +36,17 @@ subdir_BuildThis = os.path.join('subdir', 'Buildthis') test.write('SConscript', """ import os -print "SConscript " + os.getcwd() +print("SConscript " + os.getcwd()) """) test.write(subdir_BuildThis, """ import os -print "subdir/BuildThis", os.getcwd() +print("subdir/BuildThis", os.getcwd()) """) test.write('Build2', """ import os -print "Build2", os.getcwd() +print("Build2", os.getcwd()) """) wpath = test.workpath() @@ -85,7 +85,7 @@ test.run(arguments = '--sconstruct=%s .' % subdir_BuildThis, test.run(arguments = '-f - .', stdin = """ import os -print "STDIN " + os.getcwd() +print("STDIN " + os.getcwd()) """, stdout = test.wrap_stdout(read_str = 'STDIN %s\n' % wpath, build_str = "scons: `.' is up to date.\n")) diff --git a/test/overrides.py b/test/overrides.py index d706ab7..69d5207 100644 --- a/test/overrides.py +++ b/test/overrides.py @@ -35,9 +35,9 @@ _python_ = TestSCons._python_ test.write('SConstruct', """ env = Environment(CCFLAGS='-DFOO', LIBS=['a']) def build(target, source, env): - print "env['CC'] =", env['CC'] - print "env['CCFLAGS'] =", env['CCFLAGS'] - print "env['LIBS'] =", env['LIBS'] + print("env['CC'] =", env['CC']) + print("env['CCFLAGS'] =", env['CCFLAGS']) + print("env['LIBS'] =", env['LIBS']) builder = Builder(action=build, CC='buildcc', LIBS='buildlibs') env['BUILDERS']['Build'] = builder diff --git a/test/preserve-source.py b/test/preserve-source.py index 6e09073..b7eccd1 100644 --- a/test/preserve-source.py +++ b/test/preserve-source.py @@ -35,7 +35,7 @@ test.write('SConstruct', r""" def cat(env, source, target): target = str(target[0]) source = list(map(str, source)) - print 'cat(%s) > %s' % (source, target) + print('cat(%s) > %s' % (source, target)) f = open(target, "wb") for src in source: f.write(open(src, "rb").read()) diff --git a/test/site_scons/basic.py b/test/site_scons/basic.py index 1868723..b3ae9f2 100644 --- a/test/site_scons/basic.py +++ b/test/site_scons/basic.py @@ -40,7 +40,7 @@ test.subdir('site_scons', ['site_scons', 'site_tools']) test.write(['site_scons', 'site_init.py'], """ from SCons.Script import * -print "Hi there, I am in site_scons/site_init.py!" +print("Hi there, I am in site_scons/site_init.py!") """) test.write(['site_scons', 'site_tools', 'mytool.py'], """ @@ -54,7 +54,7 @@ def exists(env): test.write('SConstruct', """ e=Environment(tools=['default', 'mytool']) -print e.subst('My site tool is $MYTOOL') +print(e.subst('My site tool is $MYTOOL')) """) test.run(arguments = '-Q .', diff --git a/test/site_scons/no-site-dir.py b/test/site_scons/no-site-dir.py index d01d419..c31ec94 100644 --- a/test/site_scons/no-site-dir.py +++ b/test/site_scons/no-site-dir.py @@ -37,7 +37,7 @@ test.subdir('site_scons', ['site_scons', 'site_tools']) test.write(['site_scons', 'site_init.py'], """ from SCons.Script import * -print "Hi there, I am in site_scons/site_init.py!" +print("Hi there, I am in site_scons/site_init.py!") """) test.write(['site_scons', 'site_tools', 'mytool.py'], """ @@ -68,7 +68,7 @@ test.run(arguments = '-Q --no-site-dir .', test.write('SConstruct', """ e=Environment() -print e.subst('no site: M4 is $M4, M4_MINE is $M4_MINE') +print(e.subst('no site: M4 is $M4, M4_MINE is $M4_MINE')) """) test.run(arguments = '-Q --no-site-dir .') diff --git a/test/site_scons/override.py b/test/site_scons/override.py index e33bb88..d65c09e 100644 --- a/test/site_scons/override.py +++ b/test/site_scons/override.py @@ -49,7 +49,7 @@ def exists(env): test.write('SConstruct', """ e=Environment(tools=['m4']) -print e.subst('M4 is $M4, M4_MINE is $M4_MINE') +print(e.subst('M4 is $M4, M4_MINE is $M4_MINE')) """) test.run(arguments = '-Q .', stdout = """M4 is my_m4, M4_MINE is 1 diff --git a/test/site_scons/site-dir.py b/test/site_scons/site-dir.py index 8e82e94..d60e7d9 100644 --- a/test/site_scons/site-dir.py +++ b/test/site_scons/site-dir.py @@ -38,7 +38,7 @@ test.subdir('site_scons', ['site_scons', 'site_tools']) test.write(['site_scons', 'site_init.py'], """ from SCons.Script import * -print "Hi there, I am in site_scons/site_init.py!" +print("Hi there, I am in site_scons/site_init.py!") """) test.write(['site_scons', 'site_tools', 'mytool.py'], """ @@ -55,7 +55,7 @@ test.subdir('alt_site', ['alt_site', 'site_tools']) test.write(['alt_site', 'site_init.py'], """ from SCons.Script import * -print "Hi there, I am in alt_site/site_init.py!" +print("Hi there, I am in alt_site/site_init.py!") """) test.write('SConstruct', """ diff --git a/test/site_scons/site_init.py b/test/site_scons/site_init.py index 45201ac..27768a9 100644 --- a/test/site_scons/site_init.py +++ b/test/site_scons/site_init.py @@ -58,10 +58,10 @@ for x in list(globals().keys()): continue special.append(x) -print sorted(special) -print __doc__ -print os.path.realpath(__file__) -print __name__ +print(sorted(special)) +print(__doc__) +print(os.path.realpath(__file__)) +print(__name__) """) test.write('SConstruct', "\n") -- cgit v0.12 From 664c1a40e20c38842a7dc8097ba32638c8925dde Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 25 Jan 2016 07:46:43 +0000 Subject: Add a Shippable build file. --- shippable.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 shippable.yml diff --git a/shippable.yml b/shippable.yml new file mode 100644 index 0000000..b7e363a --- /dev/null +++ b/shippable.yml @@ -0,0 +1,7 @@ +language: python + +python: + - "2.7" + - "3.4" + +script: python runtest.py -a -- cgit v0.12 From 531b6617dcb0bfae3335eead483459651b4a47a0 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 25 Jan 2016 08:16:47 +0000 Subject: Add a dummy file to trigger a Codeship build. --- dummy.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 dummy.txt diff --git a/dummy.txt b/dummy.txt new file mode 100644 index 0000000..e69de29 -- cgit v0.12 From 6a42327dfce9dba97ad9643b519e5c93907a45be Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Mon, 25 Jan 2016 09:06:57 +0000 Subject: Remove dummy file. --- dummy.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dummy.txt diff --git a/dummy.txt b/dummy.txt deleted file mode 100644 index e69de29..0000000 -- cgit v0.12 From 193c96046004369ba13fb9b4fc0e992513cc8f78 Mon Sep 17 00:00:00 2001 From: Russel Winder Date: Tue, 2 Feb 2016 17:56:18 +0000 Subject: Remove all the six stuff. --- QMTest/TestCmd.py | 4 - QMTest/TestCmdTests.py | 12 +- bin/install_scons.py | 8 +- src/engine/SCons/MemoizeTests.py | 1 - src/engine/SCons/Tool/xgettext.py | 6 +- src/engine/SCons/Util.py | 24 +- src/engine/SCons/UtilTests.py | 1 - src/engine/SCons/compat/six.py | 646 ------------------------------------ src/engine/SCons/compat/sixTests.py | 35 -- src/script/sconsign.py | 10 +- 10 files changed, 17 insertions(+), 730 deletions(-) delete mode 100755 src/engine/SCons/compat/six.py delete mode 100644 src/engine/SCons/compat/sixTests.py diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index d645731..f8c4e69 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -287,8 +287,6 @@ version. # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. from __future__ import division, print_function -from SCons.compat.six import PY3 - __author__ = "Steven Knight " __revision__ = "TestCmd.py 1.3.D001 2010/06/03 12:58:27 knight" __version__ = "1.3" @@ -1730,8 +1728,6 @@ class TestCmd(object): exist. The I/O mode for the file may be specified; it must begin with a 'w'. The default is 'wb' (binary write). """ - if PY3: - content = re.sub(r'print (.+)', r'print(\1)', content) file = self.canonicalize(file) if mode[0] != 'w': raise ValueError("mode must begin with 'w'") diff --git a/QMTest/TestCmdTests.py b/QMTest/TestCmdTests.py index a2e7022..cd62d9f 100644 --- a/QMTest/TestCmdTests.py +++ b/QMTest/TestCmdTests.py @@ -19,8 +19,6 @@ AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ -from SCons.compat.six import PY3 - __author__ = "Steven Knight " __revision__ = "TestCmdTests.py 1.3.D001 2010/06/03 12:58:27 knight" @@ -28,19 +26,13 @@ import os import shutil import signal import stat -if PY3: - from io import StringIO -else: - from StringIO import StringIO +from StringIO import StringIO import sys import tempfile import time import types import unittest -if PY3: - from collections import UserList -else: - from UserList import UserList +from UserList import UserList # Strip the current directory so we get the right TestCmd.py module. diff --git a/bin/install_scons.py b/bin/install_scons.py index 55e327d..ac79fd3 100644 --- a/bin/install_scons.py +++ b/bin/install_scons.py @@ -17,19 +17,15 @@ # This was written for a Linux system (specifically Ubuntu) but should # be reasonably generic to any POSIX-style system with a /usr/local # hierarchy. -from __future__ import print_function -from SCons.compat.six import PY3 +from __future__ import print_function import getopt import os import shutil import sys import tarfile -if PY3: - from urllib.request import urlretrieve -else: - from urllib import urlretrieve +from urllib import urlretrieve from Command import CommandRunner, Usage diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py index ba866d2..3ce9a11 100644 --- a/src/engine/SCons/MemoizeTests.py +++ b/src/engine/SCons/MemoizeTests.py @@ -20,7 +20,6 @@ # 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 SCons.compat.six import add_metaclass __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/Tool/xgettext.py b/src/engine/SCons/Tool/xgettext.py index ff45989..e9b49b7 100644 --- a/src/engine/SCons/Tool/xgettext.py +++ b/src/engine/SCons/Tool/xgettext.py @@ -23,7 +23,6 @@ Tool specific initialization of `xgettext` tool. # 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 SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -33,7 +32,7 @@ class _CmdRunner(object): variables. It also provides `strfunction()` method, which shall be used by scons Action objects to print command string. """ - def __init__( self, command, commandstr = None): + def __init__(self, command, commandstr = None): self.out = None self.err = None self.status = None @@ -56,7 +55,8 @@ class _CmdRunner(object): proc = SCons.Action._subproc(env, command, **kw) self.out, self.err = proc.communicate() self.status = proc.wait() - if self.err: sys.stderr.write(u(self.err)) + if self.err: + sys.stderr.write(unicode(self.err)) return self.status def strfunction(self, target, source, env): diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index a66f92a..5b11f83 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -23,7 +23,6 @@ Various utility functions go here. # 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 SCons.compat.six import PY2, PY3, u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -33,16 +32,13 @@ import copy import re import types -if PY3: - from collections import UserDict, UserList, UserString -else: - from UserDict import UserDict - from UserList import UserList - from UserString import UserString +from UserDict import UserDict +from UserList import UserList +from UserString import UserString # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. -InstanceType = types.InstanceType if PY2 else None +InstanceType = types.InstanceType MethodType = types.MethodType FunctionType = types.FunctionType try: unicode @@ -162,7 +158,7 @@ class DisplayEngine(object): return if append_newline: text = text + '\n' try: - sys.stdout.write(u(text)) + sys.stdout.write(unicode(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed @@ -256,7 +252,7 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited=None): ' N = no clean\n' + ' H = no cache\n' + '\n') - sys.stdout.write(u(legend)) + sys.stdout.write(unicode(legend)) tags = ['['] tags.append(' E'[IDX(root.exists())]) @@ -1413,15 +1409,11 @@ def AddMethod(obj, function, name=None): if hasattr(obj, '__class__') and obj.__class__ is not type: # "obj" is an instance, so it gets a bound method. - if PY3: - method = MethodType(function, obj) - else: - method = MethodType(function, obj, obj.__class__) + method = MethodType(function, obj, obj.__class__) setattr(obj, name, method) else: # "obj" is a class, so it gets an unbound method. - if PY2: - function = MethodType(function, None, obj) + function = MethodType(function, None, obj) setattr(obj, name, function) def RenameFunction(function, name): diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 1e56dc0..9ebb924 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -20,7 +20,6 @@ # 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 SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" diff --git a/src/engine/SCons/compat/six.py b/src/engine/SCons/compat/six.py deleted file mode 100755 index 0e8850c..0000000 --- a/src/engine/SCons/compat/six.py +++ /dev/null @@ -1,646 +0,0 @@ -"""Utilities for writing code that runs on Python 2 and 3""" - -# Copyright (c) 2010-2014 Benjamin Peterson -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -import operator -import sys -import types - -__author__ = "Benjamin Peterson " -__version__ = "1.6.1" - - -# Useful for very coarse version differentiation. -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -if PY3: - string_types = str, - integer_types = int, - class_types = type, - text_type = str - binary_type = bytes - - MAXSIZE = sys.maxsize -else: - string_types = basestring, - integer_types = (int, long) - class_types = (type, type) - text_type = unicode - binary_type = str - - if sys.platform.startswith("java"): - # Jython always uses 32 bits. - MAXSIZE = int((1 << 31) - 1) - else: - # It's possible to have sizeof(long) != sizeof(Py_ssize_t). - class X(object): - def __len__(self): - return 1 << 31 - try: - len(X()) - except OverflowError: - # 32-bit - MAXSIZE = int((1 << 31) - 1) - else: - # 64-bit - MAXSIZE = int((1 << 63) - 1) - del X - - -def _add_doc(func, doc): - """Add documentation to a function.""" - func.__doc__ = doc - - -def _import_module(name): - """Import module, returning the module after the last dot.""" - __import__(name) - return sys.modules[name] - - -class _LazyDescr(object): - - def __init__(self, name): - self.name = name - - def __get__(self, obj, tp): - try: - result = self._resolve() - except ImportError: - # See the nice big comment in MovedModule.__getattr__. - raise AttributeError("%s could not be imported " % self.name) - setattr(obj, self.name, result) # Invokes __set__. - # This is a bit ugly, but it avoids running this again. - delattr(obj.__class__, self.name) - return result - - -class MovedModule(_LazyDescr): - - def __init__(self, name, old, new=None): - super(MovedModule, self).__init__(name) - if PY3: - if new is None: - new = name - self.mod = new - else: - self.mod = old - - def _resolve(self): - return _import_module(self.mod) - - def __getattr__(self, attr): - # It turns out many Python frameworks like to traverse sys.modules and - # try to load various attributes. This causes problems if this is a - # platform-specific module on the wrong platform, like _winreg on - # Unixes. Therefore, we silently pretend unimportable modules do not - # have any attributes. See issues #51, #53, #56, and #63 for the full - # tales of woe. - # - # First, if possible, avoid loading the module just to look at __file__, - # __name__, or __path__. - if (attr in ("__file__", "__name__", "__path__") and - self.mod not in sys.modules): - raise AttributeError(attr) - try: - _module = self._resolve() - except ImportError: - raise AttributeError(attr) - value = getattr(_module, attr) - setattr(self, attr, value) - return value - - -class _LazyModule(types.ModuleType): - - def __init__(self, name): - super(_LazyModule, self).__init__(name) - self.__doc__ = self.__class__.__doc__ - - def __dir__(self): - attrs = ["__doc__", "__name__"] - attrs += [attr.name for attr in self._moved_attributes] - return attrs - - # Subclasses should override this - _moved_attributes = [] - - -class MovedAttribute(_LazyDescr): - - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): - super(MovedAttribute, self).__init__(name) - if PY3: - if new_mod is None: - new_mod = name - self.mod = new_mod - if new_attr is None: - if old_attr is None: - new_attr = name - else: - new_attr = old_attr - self.attr = new_attr - else: - self.mod = old_mod - if old_attr is None: - old_attr = name - self.attr = old_attr - - def _resolve(self): - module = _import_module(self.mod) - return getattr(module, self.attr) - - - -class _MovedItems(_LazyModule): - """Lazy loading of moved objects""" - - -_moved_attributes = [ - MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), - MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), - MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), - MovedAttribute("map", "itertools", "builtins", "imap", "map"), - MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "imp", "reload"), - MovedAttribute("reduce", "__builtin__", "functools"), - MovedAttribute("StringIO", "StringIO", "io"), - MovedAttribute("UserString", "UserString", "collections"), - MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), - - MovedModule("builtins", "__builtin__"), - MovedModule("configparser", "ConfigParser"), - MovedModule("copyreg", "copy_reg"), - MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), - MovedModule("http_cookies", "Cookie", "http.cookies"), - MovedModule("html_entities", "htmlentitydefs", "html.entities"), - MovedModule("html_parser", "HTMLParser", "html.parser"), - MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), - MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), - MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), - MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), - MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), - MovedModule("cPickle", "cPickle", "pickle"), - MovedModule("queue", "Queue"), - MovedModule("reprlib", "repr"), - MovedModule("socketserver", "SocketServer"), - MovedModule("_thread", "thread", "_thread"), - MovedModule("tkinter", "Tkinter"), - MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), - MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), - MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), - MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), - MovedModule("tkinter_tix", "Tix", "tkinter.tix"), - MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), - MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), - MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), - MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), - MovedModule("tkinter_font", "tkFont", "tkinter.font"), - MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), - MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), - MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), - MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), - MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), - MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), - MovedModule("xmlrpc_server", "xmlrpclib", "xmlrpc.server"), - MovedModule("winreg", "_winreg"), -] -for attr in _moved_attributes: - setattr(_MovedItems, attr.name, attr) - if isinstance(attr, MovedModule): - sys.modules[__name__ + ".moves." + attr.name] = attr -del attr - -_MovedItems._moved_attributes = _moved_attributes - -moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves") - - -class Module_six_moves_urllib_parse(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_parse""" - - -_urllib_parse_moved_attributes = [ - MovedAttribute("ParseResult", "urlparse", "urllib.parse"), - MovedAttribute("SplitResult", "urlparse", "urllib.parse"), - MovedAttribute("parse_qs", "urlparse", "urllib.parse"), - MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), - MovedAttribute("urldefrag", "urlparse", "urllib.parse"), - MovedAttribute("urljoin", "urlparse", "urllib.parse"), - MovedAttribute("urlparse", "urlparse", "urllib.parse"), - MovedAttribute("urlsplit", "urlparse", "urllib.parse"), - MovedAttribute("urlunparse", "urlparse", "urllib.parse"), - MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), - MovedAttribute("quote", "urllib", "urllib.parse"), - MovedAttribute("quote_plus", "urllib", "urllib.parse"), - MovedAttribute("unquote", "urllib", "urllib.parse"), - MovedAttribute("unquote_plus", "urllib", "urllib.parse"), - MovedAttribute("urlencode", "urllib", "urllib.parse"), - MovedAttribute("splitquery", "urllib", "urllib.parse"), -] -for attr in _urllib_parse_moved_attributes: - setattr(Module_six_moves_urllib_parse, attr.name, attr) -del attr - -Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes - -sys.modules[__name__ + ".moves.urllib_parse"] = sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse") - - -class Module_six_moves_urllib_error(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_error""" - - -_urllib_error_moved_attributes = [ - MovedAttribute("URLError", "urllib2", "urllib.error"), - MovedAttribute("HTTPError", "urllib2", "urllib.error"), - MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), -] -for attr in _urllib_error_moved_attributes: - setattr(Module_six_moves_urllib_error, attr.name, attr) -del attr - -Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes - -sys.modules[__name__ + ".moves.urllib_error"] = sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error") - - -class Module_six_moves_urllib_request(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_request""" - - -_urllib_request_moved_attributes = [ - MovedAttribute("urlopen", "urllib2", "urllib.request"), - MovedAttribute("install_opener", "urllib2", "urllib.request"), - MovedAttribute("build_opener", "urllib2", "urllib.request"), - MovedAttribute("pathname2url", "urllib", "urllib.request"), - MovedAttribute("url2pathname", "urllib", "urllib.request"), - MovedAttribute("getproxies", "urllib", "urllib.request"), - MovedAttribute("Request", "urllib2", "urllib.request"), - MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), - MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), - MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), - MovedAttribute("BaseHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), - MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), - MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), - MovedAttribute("FileHandler", "urllib2", "urllib.request"), - MovedAttribute("FTPHandler", "urllib2", "urllib.request"), - MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), - MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), - MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), - MovedAttribute("urlretrieve", "urllib", "urllib.request"), - MovedAttribute("urlcleanup", "urllib", "urllib.request"), - MovedAttribute("URLopener", "urllib", "urllib.request"), - MovedAttribute("FancyURLopener", "urllib", "urllib.request"), - MovedAttribute("proxy_bypass", "urllib", "urllib.request"), -] -for attr in _urllib_request_moved_attributes: - setattr(Module_six_moves_urllib_request, attr.name, attr) -del attr - -Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes - -sys.modules[__name__ + ".moves.urllib_request"] = sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request") - - -class Module_six_moves_urllib_response(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_response""" - - -_urllib_response_moved_attributes = [ - MovedAttribute("addbase", "urllib", "urllib.response"), - MovedAttribute("addclosehook", "urllib", "urllib.response"), - MovedAttribute("addinfo", "urllib", "urllib.response"), - MovedAttribute("addinfourl", "urllib", "urllib.response"), -] -for attr in _urllib_response_moved_attributes: - setattr(Module_six_moves_urllib_response, attr.name, attr) -del attr - -Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes - -sys.modules[__name__ + ".moves.urllib_response"] = sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response") - - -class Module_six_moves_urllib_robotparser(_LazyModule): - """Lazy loading of moved objects in six.moves.urllib_robotparser""" - - -_urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), -] -for attr in _urllib_robotparser_moved_attributes: - setattr(Module_six_moves_urllib_robotparser, attr.name, attr) -del attr - -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes - -sys.modules[__name__ + ".moves.urllib_robotparser"] = sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser") - - -class Module_six_moves_urllib(types.ModuleType): - """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" - parse = sys.modules[__name__ + ".moves.urllib_parse"] - error = sys.modules[__name__ + ".moves.urllib_error"] - request = sys.modules[__name__ + ".moves.urllib_request"] - response = sys.modules[__name__ + ".moves.urllib_response"] - robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"] - - def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] - - -sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib") - - -def add_move(move): - """Add an item to six.moves.""" - setattr(_MovedItems, move.name, move) - - -def remove_move(name): - """Remove item from six.moves.""" - try: - delattr(_MovedItems, name) - except AttributeError: - try: - del moves.__dict__[name] - except KeyError: - raise AttributeError("no such move, %r" % (name,)) - - -if PY3: - _meth_func = "__func__" - _meth_self = "__self__" - - _func_closure = "__closure__" - _func_code = "__code__" - _func_defaults = "__defaults__" - _func_globals = "__globals__" - - _iterkeys = "keys" - _itervalues = "values" - _iteritems = "items" - _iterlists = "lists" -else: - _meth_func = "im_func" - _meth_self = "im_self" - - _func_closure = "func_closure" - _func_code = "func_code" - _func_defaults = "func_defaults" - _func_globals = "func_globals" - - _iterkeys = "iterkeys" - _itervalues = "itervalues" - _iteritems = "iteritems" - _iterlists = "iterlists" - - -try: - advance_iterator = next -except NameError: - def advance_iterator(it): - return it.next() -next = advance_iterator - - -try: - callable = callable -except NameError: - def callable(obj): - return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) - - -if PY3: - def get_unbound_function(unbound): - return unbound - - create_bound_method = types.MethodType - - Iterator = object -else: - def get_unbound_function(unbound): - return unbound.__func__ - - def create_bound_method(func, obj): - return types.MethodType(func, obj, obj.__class__) - - class Iterator(object): - - def next(self): - return type(self).__next__(self) - - callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") - - -get_method_function = operator.attrgetter(_meth_func) -get_method_self = operator.attrgetter(_meth_self) -get_function_closure = operator.attrgetter(_func_closure) -get_function_code = operator.attrgetter(_func_code) -get_function_defaults = operator.attrgetter(_func_defaults) -get_function_globals = operator.attrgetter(_func_globals) - - -def iterkeys(d, **kw): - """Return an iterator over the keys of a dictionary.""" - return iter(getattr(d, _iterkeys)(**kw)) - -def itervalues(d, **kw): - """Return an iterator over the values of a dictionary.""" - return iter(getattr(d, _itervalues)(**kw)) - -def iteritems(d, **kw): - """Return an iterator over the (key, value) pairs of a dictionary.""" - return iter(getattr(d, _iteritems)(**kw)) - -def iterlists(d, **kw): - """Return an iterator over the (key, [values]) pairs of a dictionary.""" - return iter(getattr(d, _iterlists)(**kw)) - - -if PY3: - def b(s): - return s.encode("latin-1") - def u(s): - return s - unichr = chr - if sys.version_info[1] <= 1: - def int2byte(i): - return bytes((i,)) - else: - # This is about 2x faster than the implementation above on 3.2+ - int2byte = operator.methodcaller("to_bytes", 1, "big") - byte2int = operator.itemgetter(0) - indexbytes = operator.getitem - iterbytes = iter - import io - StringIO = io.StringIO - BytesIO = io.BytesIO -else: - def b(s): - return s - # Workaround for standalone backslash - def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") - unichr = unichr - int2byte = chr - def byte2int(bs): - return ord(bs[0]) - def indexbytes(buf, i): - return ord(buf[i]) - def iterbytes(buf): - return (ord(byte) for byte in buf) - import StringIO - StringIO = BytesIO = StringIO.StringIO -_add_doc(b, """Byte literal""") -_add_doc(u, """Text literal""") - - -if PY3: - exec_ = getattr(moves.builtins, "exec") - - - def reraise(tp, value, tb=None): - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value - -else: - def exec_(_code_, _globs_=None, _locs_=None): - """Execute code in a namespace.""" - if _globs_ is None: - frame = sys._getframe(1) - _globs_ = frame.f_globals - if _locs_ is None: - _locs_ = frame.f_locals - del frame - elif _locs_ is None: - _locs_ = _globs_ - exec("""exec _code_ in _globs_, _locs_""") - - - exec_("""def reraise(tp, value, tb=None): - raise tp, value, tb -""") - - -print_ = getattr(moves.builtins, "print", None) -if print_ is None: - def print_(*args, **kwargs): - """The new-style print function for Python 2.4 and 2.5.""" - fp = kwargs.pop("file", sys.stdout) - if fp is None: - return - def write(data): - if not isinstance(data, basestring): - data = str(data) - # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): - errors = getattr(fp, "errors", None) - if errors is None: - errors = "strict" - data = data.encode(fp.encoding, errors) - fp.write(data) - want_unicode = False - sep = kwargs.pop("sep", None) - if sep is not None: - if isinstance(sep, unicode): - want_unicode = True - elif not isinstance(sep, str): - raise TypeError("sep must be None or a string") - end = kwargs.pop("end", None) - if end is not None: - if isinstance(end, unicode): - want_unicode = True - elif not isinstance(end, str): - raise TypeError("end must be None or a string") - if kwargs: - raise TypeError("invalid keyword arguments to print()") - if not want_unicode: - for arg in args: - if isinstance(arg, unicode): - want_unicode = True - break - if want_unicode: - newline = unicode("\n") - space = unicode(" ") - else: - newline = "\n" - space = " " - if sep is None: - sep = space - if end is None: - end = newline - for i, arg in enumerate(args): - if i: - write(sep) - write(arg) - write(end) - -_add_doc(reraise, """Reraise an exception.""") - - -def with_metaclass(meta, *bases): - """Create a base class with a metaclass.""" - return meta("NewBase", bases, {}) - -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper diff --git a/src/engine/SCons/compat/sixTests.py b/src/engine/SCons/compat/sixTests.py deleted file mode 100644 index 8be3572..0000000 --- a/src/engine/SCons/compat/sixTests.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# __COPYRIGHT__ -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# - -from __future__ import print_function - -import unittest - -class sixTestCase(unittest.TestCase): - - def test_import(self): - """Test that six imports correctly.""" - import sys - print(sys.path) - from SCons.compat.six import PY2, PY3 - self.assertTrue(PY2 or PY3) diff --git a/src/script/sconsign.py b/src/script/sconsign.py index daf088e..6f49858 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -25,8 +25,6 @@ from __future__ import print_function -from SCons.compat.six import PY2, PY3 - __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" __version__ = "__VERSION__" @@ -188,8 +186,7 @@ sys.path = libs + sys.path import SCons.compat -if PY2: - import whichdb +import whichdb import dbm import time import pickle @@ -208,10 +205,7 @@ def my_whichdb(filename): pass return _orig_whichdb(filename) -if PY3: - _orig_whichdb = dbm.whichdb -else: - _orig_whichdb = whichdb.whichdb +_orig_whichdb = whichdb.whichdb dbm.whichdb = my_whichdb def my_import(mname): -- cgit v0.12 From c591da06c1a18873d09323d6700d1469120ad27d Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 8 May 2016 17:21:42 -0700 Subject: Guard checking for subprocess.mswindows by checking if on win32 platform --- QMTest/TestCmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index f8c4e69..8cb6fb9 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -658,7 +658,7 @@ except AttributeError: PIPE = subprocess.PIPE -if subprocess.mswindows: +if sys.platform == 'win32' and subprocess.mswindows: try: from win32file import ReadFile, WriteFile from win32pipe import PeekNamedPipe @@ -720,7 +720,7 @@ class Popen(subprocess.Popen): getattr(self, which).close() setattr(self, which, None) - if subprocess.mswindows: + if sys.platform == 'win32' and subprocess.mswindows: def send(self, input): if not self.stdin: return None -- cgit v0.12 From 36b38cccb12248c106575753a8f2807bfd88c2fa Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 8 May 2016 20:58:39 -0700 Subject: py2/3 compatibility changes. --- src/engine/SCons/Util.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index 5b11f83..a5a92fa 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -32,13 +32,27 @@ import copy import re import types -from UserDict import UserDict -from UserList import UserList -from UserString import UserString +try: + from UserDict import UserDict +except ImportError as e: + from collections import UserDict + +try: + from UserList import UserList +except ImportError as e: + from collections import UserList + +try: + from UserString import UserString +except ImportError as e: + from collections import UserString # Don't "from types import ..." these because we need to get at the # types module later to look for UnicodeType. -InstanceType = types.InstanceType + +# Below not used? +# InstanceType = types.InstanceType + MethodType = types.MethodType FunctionType = types.FunctionType try: unicode -- cgit v0.12 From 70f4e3f26156b33f465fa12ec87b50c5b8f784e4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 8 May 2016 21:23:37 -0700 Subject: Add from future import print_function to fix broken tests under python2.7 --- src/engine/SCons/Script/Main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index 997d701..c0b22a7 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -10,9 +10,13 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ +from __future__ import print_function + + unsupported_python_version = (2, 6, 0) deprecated_python_version = (2, 7, 0) + # __COPYRIGHT__ # # Permission is hereby granted, free of charge, to any person obtaining @@ -36,6 +40,7 @@ deprecated_python_version = (2, 7, 0) __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + import SCons.compat import os @@ -360,7 +365,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # the file not existing. In either case, print a # message and keep going to try to remove as many # targets as possible. - print(("scons: Could not remove '{}':".format(str(t)), e.strerror)) + print("scons: Could not remove '{0}'".format(str(t)), e.strerror) else: if removed: display("Removed " + str(t)) -- cgit v0.12 From 1268203d907a4f653abd2f40299490fca9fc5874 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:00:29 -0700 Subject: Fix missing right parent in print () function in generated SConstruct. --- test/Deprecated/Options/EnumOption.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Deprecated/Options/EnumOption.py b/test/Deprecated/Options/EnumOption.py index 2b3ed47..02afef1 100644 --- a/test/Deprecated/Options/EnumOption.py +++ b/test/Deprecated/Options/EnumOption.py @@ -43,6 +43,7 @@ def check(expect): test.write(SConstruct_path, """\ + from SCons.Options.EnumOption import EnumOption EO = EnumOption @@ -67,7 +68,7 @@ env = Environment(options=opts) Help(opts.GenerateHelpText(env)) print(env['debug']) -print(env['guilib'] +print(env['guilib']) print(env['some']) Default(env.Alias('dummy', None)) -- cgit v0.12 From f4627c480788454ff3e8ab9f2c75966ed999d9cd Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:26:03 -0700 Subject: Fixed usage of linknames which needed to be defined outside of the two methods which share it's value and wasn't. Curious this only fails in python2.7 when __future__ is imported.. --- src/engine/SCons/Tool/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 9606ac1..26caf2f 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -244,6 +244,9 @@ def createStaticLibBuilder(env): return static_lib +# used by the following two methods +linknames = [] + def _call_linker_cb(env, callback, args, result = None): """Returns the result of env['LINKCALLBACKS'][callback](*args) if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback] @@ -268,7 +271,7 @@ def _call_linker_cb(env, callback, args, result = None): if Verbose: print('_call_linker_cb: env["LINKCALLBACKS"][{:r}] found'.format(callback)) print('_call_linker_cb: env["LINKCALLBACKS"][{:r}]={:r}'.format(callback, cbfun)) - if(callable(cbfun)): + if (callable(cbfun)): if Verbose: print("VersionShLibLinkNames: linkname ",linkname, ", target ",libname) linknames.append(linkname) -- cgit v0.12 From b93369681ca5d4fc9a52fecd4d3afafc2dfa7742 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:32:04 -0700 Subject: Fixed embedded SConscript/SConstruct's usage of print. Had no parens. --- test/SConscript/Return.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/SConscript/Return.py b/test/SConscript/Return.py index a810c7c..997de9d 100644 --- a/test/SConscript/Return.py +++ b/test/SConscript/Return.py @@ -39,50 +39,50 @@ x = SConscript('SConscript2') y, z = SConscript('SConscript3') a4, b4 = SConscript('SConscript4') foo, bar = SConscript('SConscript5') -print "x =", x -print "y =", y -print "z =", z -print "a4 =", a4 -print "b4 =", b4 -print "foo =", foo -print "bar =", bar +print ("x =", x) +print ("y =", y) +print ("z =", z) +print ("a4 =", a4) +print ("b4 =", b4) +print ("foo =", foo) +print ("bar =", bar) """) test.write('SConscript1', """\ -print "line 1" +print ("line 1") Return() -print "line 2" +print ("line 2") """) test.write('SConscript2', """\ -print "line 3" +print ("line 3") x = 7 Return('x') -print "line 4" +print ("line 4") """) test.write('SConscript3', """\ -print "line 5" +print ("line 5") y = 8 z = 9 Return('y z') -print "line 6" +print ("line 6") """) test.write('SConscript4', """\ a4 = 'aaa' b4 = 'bbb' -print "line 7" +print ("line 7") Return('a4', 'b4', stop=False) b4 = 'b-after' -print "line 8" +print ("line 8") """) test.write('SConscript5', """\ foo = 'foo' bar = 'bar' Return(["foo", "bar"]) -print "line 9" +print ("line 9") """) expect = """\ -- cgit v0.12 From 144d9dd9bd444d5cfab2b1094775d59ccc758882 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:33:18 -0700 Subject: Fixed embedded SConscript/SConstruct's usage of print. Had no parens. --- test/SConscript/SConscript.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/SConscript/SConscript.py b/test/SConscript/SConscript.py index c8453a7..8bc9127 100644 --- a/test/SConscript/SConscript.py +++ b/test/SConscript/SConscript.py @@ -37,7 +37,7 @@ import foo assert foo.foo == 4 -print "SConstruct", os.getcwd() +print ("SConstruct", os.getcwd()) SConscript('SConscript') x1 = "SConstruct x1" @@ -89,7 +89,7 @@ test.write('SConscript', """\ assert "os" not in globals() import os -print "SConscript " + os.getcwd() +print ("SConscript " + os.getcwd()) """) test.write('SConscript1', """ -- cgit v0.12 From 9cc6b7b615b8b22a2a747fbb2d404d87b4091358 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:36:18 -0700 Subject: Fixed embedded SConscript/SConstruct's usage of print. Had no parens. --- test/SConscript/env.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/SConscript/env.py b/test/SConscript/env.py index 42963ff..a16866c 100644 --- a/test/SConscript/env.py +++ b/test/SConscript/env.py @@ -36,7 +36,7 @@ test.subdir('sub1', 'sub2') test.write("SConstruct", """\ env = Environment(SUB1='sub1', SUB2='sub2') -print "SConstruct" +print("SConstruct") x = 'xxx' y = 'yyy' env.Export(["x", "y"]) @@ -49,15 +49,15 @@ env.SConscript(['s3', 's4']) test.write(['sub1', 'SConscript'], """\ env = Environment() env.Import("x") -print "sub1/SConscript" -print "x =", x +print("sub1/SConscript") +print("x =", x) """) test.write(['sub2', 'SConscript'], """\ env = Environment() env.Import("y") -print "sub2/SConscript" -print "y =", y +print("sub2/SConscript") +print("y =", y) """) test.write('s1', "\n") -- cgit v0.12 From 9e56ee19d57f6ecb32d6cb5cd36809fd02cd34c1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:37:11 -0700 Subject: Fix typo in comment. --- test/SConscript/SConscript.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SConscript/SConscript.py b/test/SConscript/SConscript.py index 8bc9127..d1e09ce 100644 --- a/test/SConscript/SConscript.py +++ b/test/SConscript/SConscript.py @@ -85,7 +85,7 @@ SConscript('SConscript7') test.write('SConscript', """\ -# os should not be automajically imported: +# os should not be automatically imported: assert "os" not in globals() import os -- cgit v0.12 From d3c4aa79b66572dacc4be76fc7c54354c726ae3b Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:38:08 -0700 Subject: Fixed print()'s --- test/SConscript/white-space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SConscript/white-space.py b/test/SConscript/white-space.py index 06acea8..cc8f00e 100644 --- a/test/SConscript/white-space.py +++ b/test/SConscript/white-space.py @@ -38,7 +38,7 @@ SConscript('white space/SConscript') """) test.write(['white space', 'SConscript'], """\ -print "`white space/SConscript'" +print("`white space/SConscript'") """) expect = test.wrap_stdout(read_str = "`white space/SConscript'\n", -- cgit v0.12 From da6d4138160e27aa34f80b6f48ba9e331a69aa77 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:39:27 -0700 Subject: Fixed print()'s --- test/SConstruct.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/SConstruct.py b/test/SConstruct.py index 15e1c1b..9b2807f 100644 --- a/test/SConstruct.py +++ b/test/SConstruct.py @@ -41,7 +41,7 @@ wpath = test.workpath() test.write('sconstruct', """ import os -print "sconstruct", os.getcwd() +print("sconstruct", os.getcwd()) """) test.run(arguments = ".", @@ -51,7 +51,7 @@ test.run(arguments = ".", test.write('Sconstruct', """ import os -print "Sconstruct", os.getcwd() +print("Sconstruct", os.getcwd()) """) test.run(arguments = ".", @@ -60,7 +60,7 @@ test.run(arguments = ".", test.write('SConstruct', """ import os -print "SConstruct", os.getcwd() +print("SConstruct", os.getcwd()) """) test.run(arguments = ".", -- cgit v0.12 From 76aae9b8cb7bbd290fcd82fd6dbaf0c3f51c9bc4 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:41:12 -0700 Subject: Fixed print()'s --- test/SWIG/SWIG.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/SWIG/SWIG.py b/test/SWIG/SWIG.py index d53fa49..38bdc97 100644 --- a/test/SWIG/SWIG.py +++ b/test/SWIG/SWIG.py @@ -48,14 +48,14 @@ for opt, arg in opts: if opt == '-c': pass elif opt == '-o': out = arg elif opt == '-v' and arg == 'ersion': - print "" - print "SWIG Version 0.1.2" - print "" - print "Compiled with g++ [x86_64-pc-linux-gnu]" - print "" - print "Configured options: +pcre" - print "" - print "Please see http://www.swig.org for reporting bugs and further information" + print("") + print("SWIG Version 0.1.2") + print("") + print("Compiled with g++ [x86_64-pc-linux-gnu]") + print("") + print("Configured options: +pcre") + print("") + print("Please see http://www.swig.org for reporting bugs and further information") sys.exit(0) infile = open(args[0], 'rb') outfile = open(out, 'wb') @@ -68,7 +68,7 @@ sys.exit(0) test.write('SConstruct', """ env = Environment(tools=['default', 'swig'], SWIG = [r'%(python)s', 'myswig.py']) -print env.subst("Using SWIG $SWIGVERSION") +print(env.subst("Using SWIG $SWIGVERSION")) env.Program(target = 'test1', source = 'test1.i') env.CFile(target = 'test2', source = 'test2.i') env.Clone(SWIGFLAGS = '-c++').Program(target = 'test3', source = 'test3.i') -- cgit v0.12 From 2efa4c01f3d8010adf98ab2ead5c5a4534544766 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:42:14 -0700 Subject: Fixed print()'s --- test/Scanner/CrossLanguageNoExtension.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Scanner/CrossLanguageNoExtension.py b/test/Scanner/CrossLanguageNoExtension.py index 5bf205f..0016ca5 100644 --- a/test/Scanner/CrossLanguageNoExtension.py +++ b/test/Scanner/CrossLanguageNoExtension.py @@ -45,11 +45,11 @@ def scan(node, env, scanpaths, arg): return includes def kfile_scan(node, env, scanpaths, arg): - print 'kscan: ' + str(node) + print('kscan: ' + str(node)) return scan(node, env, scanpaths, arg) def k2file_scan(node, env, scanpaths, arg): - print 'k2scan: ' + str(node) + print('k2scan: ' + str(node)) return scan(node, env, scanpaths, arg) kscan = Scanner(name = 'kfile', -- cgit v0.12 From ac02a52b31e3e12271a9929e45fbecc10c4113c8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:43:40 -0700 Subject: Fixed print()'s --- test/Scanner/empty-implicit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Scanner/empty-implicit.py b/test/Scanner/empty-implicit.py index 0323240..45fe952 100644 --- a/test/Scanner/empty-implicit.py +++ b/test/Scanner/empty-implicit.py @@ -37,7 +37,7 @@ test.write('SConstruct', r""" import os.path def scan(node, env, envkey, arg): - print 'XScanner: node =', os.path.split(str(node))[1] + print('XScanner: node =', os.path.split(str(node))[1]) return [] def exists_check(node, env): @@ -52,7 +52,7 @@ XScanner = Scanner(name = 'XScanner', def echo(env, target, source): t = os.path.split(str(target[0]))[1] s = os.path.split(str(source[0]))[1] - print 'create %s from %s' % (t, s) + print('create %s from %s' % (t, s)) open(t, 'wb').write(open(s, 'rb').read()) Echo = Builder(action = Action(echo, None), -- cgit v0.12 From dea50d86773e279f7b0f13e22285bb0a10eb5c48 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:44:39 -0700 Subject: Fixed print()'s --- test/Scanner/scan-once.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Scanner/scan-once.py b/test/Scanner/scan-once.py index d68f918..eac1f49 100644 --- a/test/Scanner/scan-once.py +++ b/test/Scanner/scan-once.py @@ -36,7 +36,7 @@ test.write('SConstruct', r""" import os.path def scan(node, env, envkey, arg): - print 'XScanner: node =', os.path.split(str(node))[1] + print('XScanner: node =', os.path.split(str(node))[1]) return [] def exists_check(node, env): @@ -51,7 +51,7 @@ XScanner = Scanner(name = 'XScanner', def echo(env, target, source): t = os.path.split(str(target[0]))[1] s = os.path.split(str(source[0]))[1] - print 'create %s from %s' % (t, s) + print('create %s from %s' % (t, s)) Echo = Builder(action = Action(echo, None), src_suffix = '.x', -- cgit v0.12 From 8db3ac9ab52220be897c562c36599897e43af7ee Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:46:20 -0700 Subject: Fixed print()'s --- test/Subst/AllowSubstExceptions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/Subst/AllowSubstExceptions.py b/test/Subst/AllowSubstExceptions.py index 286f189..7f2a9aa 100644 --- a/test/Subst/AllowSubstExceptions.py +++ b/test/Subst/AllowSubstExceptions.py @@ -52,37 +52,37 @@ assert env.subst_list('${INDEX[999]}') == [[]] AllowSubstExceptions() try: env.subst('$NAME') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst('${NAME}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst('${INDEX[999]}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst_list('$NAME') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst_list('${NAME}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst_list('${INDEX[999]}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst('${1/0}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") try: env.subst_list('${1/0}') -except SCons.Errors.UserError, e: print e +except SCons.Errors.UserError, e: print(e) else: raise Exception("did not catch expected SCons.Errors.UserError") AllowSubstExceptions(ZeroDivisionError) -- cgit v0.12 From b70ce9026da43a0d659fbc60588e2df471cbba77 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:49:39 -0700 Subject: Fixed print()'s. Still some remaining issues. Check later. --- test/Variables/ListVariable.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/Variables/ListVariable.py b/test/Variables/ListVariable.py index e5be625..c6972c1 100644 --- a/test/Variables/ListVariable.py +++ b/test/Variables/ListVariable.py @@ -66,15 +66,15 @@ env = Environment(variables=opts) opts.Save(optsfile, env) Help(opts.GenerateHelpText(env)) -print env['shared'] -if 'ical' in env['shared']: print '1' -else: print '0' +print(env['shared']) +if 'ical' in env['shared']: print('1') +else: print('0') for x in env['shared']: - print x, -print -print env.subst('$shared') + print (x,) +print() +print(env.subst('$shared')) # Test subst_path() because it's used in $CPPDEFINES expansions. -print env.subst_path('$shared') +print(env.subst_path('$shared')) Default(env.Alias('dummy', None)) """) @@ -162,7 +162,7 @@ opts.AddVariables( env = Environment(variables=opts) Help(opts.GenerateHelpText(env)) -print env['gpib'] +print(env['gpib']) Default(env.Alias('dummy', None)) """) -- cgit v0.12 From ef93655b57fcd93cfda0e21439f5fc60df161238 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 9 May 2016 15:51:31 -0700 Subject: Fixed print()'s. Still some remaining issues. Check later. --- test/toolpath/basic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/toolpath/basic.py b/test/toolpath/basic.py index eedd06e..509d4cb 100644 --- a/test/toolpath/basic.py +++ b/test/toolpath/basic.py @@ -40,12 +40,12 @@ print("env1['TOOL_BAR'] =", env1.get('TOOL_BAR')) # pick a built-in tool with pretty simple behavior env2 = Environment(tools=['SCCS']) -print("env2['SCCS'] =", env2.get('SCCS') +print("env2['SCCS'] =", env2.get('SCCS')) print("env2['TOOL_SCCS1'] =", env2.get('TOOL_SCCS1')) print("env2['TOOL_SCCS2'] =", env2.get('TOOL_SCCS2')) env3 = Environment(tools=['SCCS'], toolpath=['.']) -print("env3['SCCS'] =", env3.get('SCCS') +print("env3['SCCS'] =", env3.get('SCCS')) print("env3['TOOL_SCCS1'] =", env3.get('TOOL_SCCS1')) print("env3['TOOL_SCCS2'] =", env3.get('TOOL_SCCS2')) -- cgit v0.12 From 170105963ce92f49eeb7441739b921198dec0505 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 07:48:46 -0700 Subject: copy src/engine/SCons/Tool/__init__.py as the merge had issues at some point in the past the the versioned shared library logic got mangled. Then 2to3 that file. Seems to e working now --- src/engine/SCons/Tool/__init__.py | 175 ++++++++++---------------------------- 1 file changed, 43 insertions(+), 132 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 26caf2f..4cd242b 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -34,7 +34,6 @@ tool definition. # 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 print_function __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" @@ -53,6 +52,7 @@ import SCons.Scanner.D import SCons.Scanner.LaTeX import SCons.Scanner.Prog import SCons.Scanner.SWIG +import collections DefaultToolpath=[] @@ -122,7 +122,7 @@ class Tool(object): if file: file.close() except ImportError as e: - if not str(e).startswith ("No module"): + if str(e)!="No module named %s"%self.name: raise SCons.Errors.EnvironmentError(e) try: import zipimport @@ -152,7 +152,7 @@ class Tool(object): file.close() return module except ImportError as e: - if not str(e).startswith("No module"): + if str(e)!="No module named %s"%self.name: raise SCons.Errors.EnvironmentError(e) try: import zipimport @@ -244,9 +244,6 @@ def createStaticLibBuilder(env): return static_lib -# used by the following two methods -linknames = [] - def _call_linker_cb(env, callback, args, result = None): """Returns the result of env['LINKCALLBACKS'][callback](*args) if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback] @@ -258,109 +255,22 @@ def _call_linker_cb(env, callback, args, result = None): Verbose = False if Verbose: - print('_call_linker_cb: args={:r}'.format(args)) - print('_call_linker_cb: callback={:r}'.format(callback)) - + print('_call_linker_cb: args=%r' % args) + print('_call_linker_cb: callback=%r' % callback) + try: cbfun = env['LINKCALLBACKS'][callback] except (KeyError, TypeError): if Verbose: - print('_call_linker_cb: env["LINKCALLBACKS"][{:r}] not found or can not be used'.format(callback)) + print('_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback) pass else: if Verbose: - print('_call_linker_cb: env["LINKCALLBACKS"][{:r}] found'.format(callback)) - print('_call_linker_cb: env["LINKCALLBACKS"][{:r}]={:r}'.format(callback, cbfun)) - if (callable(cbfun)): - if Verbose: - print("VersionShLibLinkNames: linkname ",linkname, ", target ",libname) - linknames.append(linkname) - # note: no Windows case here (win32 or cygwin); - # MSVC doesn't support this type of versioned shared libs. - # (could probably do something for MinGW though) - return linknames - -def VersionedSharedLibrary(target = None, source= None, env=None): - """Build a shared library. If the environment has SHLIBVERSION -defined make a versioned shared library and create the appropriate -symlinks for the platform we are on""" - Verbose = False - try: - version = env.subst('$SHLIBVERSION') - except KeyError: - version = None - - # libname includes the version number if one was given - libname = target[0].name - platform = env.subst('$PLATFORM') - shlib_suffix = env.subst('$SHLIBSUFFIX') - shlink_flags = SCons.Util.CLVar(env.subst('$SHLINKFLAGS')) - if Verbose: - print("VersionShLib: libname = ",libname) - print("VersionShLib: platform = ",platform) - print("VersionShLib: shlib_suffix = ",shlib_suffix) - print("VersionShLib: target = ",str(target[0])) - - if version: - # set the shared library link flags - if platform == 'posix': - shlink_flags += [ '-Wl,-Bsymbolic' ] - # OpenBSD doesn't usually use SONAME for libraries - if not sys.platform.startswith('openbsd'): - # continue setup of shlink flags for all other POSIX systems - suffix_re = re.escape(shlib_suffix + '.' + version) - (major, age, revision) = version.split(".") - # soname will have only the major version number in it - soname = re.sub(suffix_re, shlib_suffix, libname) + '.' + major - shlink_flags += [ '-Wl,-soname=%s' % soname ] - if Verbose: - print(" soname ",soname,", shlink_flags ",shlink_flags) - elif platform == 'cygwin': - shlink_flags += [ '-Wl,-Bsymbolic', - '-Wl,--out-implib,${TARGET.base}.a' ] - elif platform == 'darwin': - shlink_flags += [ '-current_version', '%s' % version, - '-compatibility_version', '%s' % version, - '-undefined', 'dynamic_lookup' ] - if Verbose: - print("VersionShLib: shlink_flags = ",shlink_flags) - envlink = env.Clone() - envlink['SHLINKFLAGS'] = shlink_flags - else: - envlink = env - - result = SCons.Defaults.ShLinkAction(target, source, envlink) - - if version: - # here we need the full pathname so the links end up in the right directory - libname = target[0].path - linknames = VersionShLibLinkNames(version, libname, env) - if Verbose: - print("VerShLib: linknames ",linknames) - # Here we just need the file name w/o path as the target of the link - lib_ver = target[0].name - # make symlink of adjacent names in linknames - for count in range(len(linknames)): - linkname = linknames[count] - if count > 0: - try: - os.remove(lastlinkname) - except: - pass - os.symlink(os.path.basename(linkname),lastlinkname) - if Verbose: - print("VerShLib: made sym link of %s -> %s" % (lastlinkname,linkname)) - lastlinkname = linkname - # finish chain of sym links with link to the actual library - if len(linknames)>0: - try: - os.remove(lastlinkname) - except: - pass - os.symlink(lib_ver,lastlinkname) + print('_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback) + print('_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun)) + if(isinstance(cbfun, collections.Callable)): if Verbose: - print("VerShLib: made sym link of %s -> %s" % (linkname, lib_ver)) - print('_call_linker_cb: env["LINKCALLBACKS"][{:r}] is callable'.format(callback)) + print('_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback) result = cbfun(env, *args) return result @@ -479,7 +389,7 @@ class _LibInfoGeneratorBase(object): def generate_versioned_lib_info(self, env, args, result = None, **kw): callback = self.get_versioned_lib_info_generator(**kw) - return _call_linker_cb(env, callback, args, result) + return _call_linker_cb(env, callback, args, result) class _LibPrefixGenerator(_LibInfoGeneratorBase): """Library prefix generator, used as target_prefix in SharedLibrary and @@ -498,17 +408,17 @@ class _LibPrefixGenerator(_LibInfoGeneratorBase): prefix = self.get_lib_prefix(env,**kw2) if Verbose: - print("_LibPrefixGenerator: input prefix={:r}".format(prefix)) + print("_LibPrefixGenerator: input prefix=%r" % prefix) version = self.get_lib_version(env, **kw2) if Verbose: - print("_LibPrefixGenerator: version={:r}".format(version)) + print("_LibPrefixGenerator: version=%r" % version) if version: prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2) if Verbose: - print("_LibPrefixGenerator: return prefix={:r}".format(prefix)) + print("_LibPrefixGenerator: return prefix=%r" % prefix) return prefix ShLibPrefixGenerator = _LibPrefixGenerator('ShLib') @@ -532,17 +442,17 @@ class _LibSuffixGenerator(_LibInfoGeneratorBase): suffix = self.get_lib_suffix(env, **kw2) if Verbose: - print("_LibSuffixGenerator: input suffix={:r}".format(suffix)) + print("_LibSuffixGenerator: input suffix=%r" % suffix) version = self.get_lib_version(env, **kw2) if Verbose: - print("_LibSuffixGenerator: version={:r}".format(version)) + print("_LibSuffixGenerator: version=%r" % version) if version: suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2) if Verbose: - print("_LibSuffixGenerator: return suffix={:r}".format(suffix)) + print("_LibSuffixGenerator: return suffix=%r" % suffix) return suffix ShLibSuffixGenerator = _LibSuffixGenerator('ShLib') @@ -565,15 +475,15 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): kw2 = kw if Verbose: - print("_LibSymLinkGenerator: libnode={:r}".format(libnode.get_path())) + print("_LibSymLinkGenerator: libnode=%r" % libnode.get_path()) symlinks = None version = self.get_lib_version(env, **kw2) disable = self.get_lib_noversionsymlinks(env, **kw2) if Verbose: - print('_LibSymlinkGenerator: version={:r}'.format(version)) - print('_LibSymlinkGenerator: disable={:r}'.format(disable)) + print('_LibSymlinkGenerator: version=%r' % version) + print('_LibSymlinkGenerator: disable=%r' % disable) if version and not disable: prefix = self.get_lib_prefix(env,**kw2) @@ -581,7 +491,7 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase): symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2) if Verbose: - print('_LibSymlinkGenerator: return symlinks={:r}'.format(StringizeLibSymlinks(symlinks))) + print('_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks)) return symlinks ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib') @@ -590,7 +500,7 @@ ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib') class _LibNameGenerator(_LibInfoGeneratorBase): """Generates "unmangled" library name from a library file node. - + Generally, it's thought to revert modifications done by prefix/suffix generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library builder. For example, on gnulink the suffix generator used by SharedLibrary @@ -600,7 +510,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase): "$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so", $SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2", the _LibNameGenerator shall return "libfoo.so". Other link tools may - implement it's own way of library name unmangling. + implement it's own way of library name unmangling. """ def __init__(self, libtype): super(_LibNameGenerator, self).__init__(libtype, 'Name') @@ -616,11 +526,11 @@ class _LibNameGenerator(_LibInfoGeneratorBase): kw2 = kw if Verbose: - print("_LibNameGenerator: libnode={:r}".format(libnode.get_path())) + print("_LibNameGenerator: libnode=%r" % libnode.get_path()) version = self.get_lib_version(env, **kw2) if Verbose: - print('_LibNameGenerator: version={:r}'.format(version)) + print('_LibNameGenerator: version=%r' % version) name = None if version: @@ -632,7 +542,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase): name = os.path.basename(libnode.get_path()) if Verbose: - print('_LibNameGenerator: return name={:r}'.format(name)) + print('_LibNameGenerator: return name=%r' % name) return name @@ -641,7 +551,7 @@ LdModNameGenerator = _LibNameGenerator('LdMod') ImpLibNameGenerator = _LibNameGenerator('ImpLib') class _LibSonameGenerator(_LibInfoGeneratorBase): - """Library soname generator. Returns library soname (e.g. libfoo.so.0) for + """Library soname generator. Returns library soname (e.g. libfoo.so.0) for a given node (e.g. /foo/bar/libfoo.so.0.1.2)""" def __init__(self, libtype): super(_LibSonameGenerator, self).__init__(libtype, 'Soname') @@ -657,13 +567,13 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): kw2 = kw if Verbose: - print("_LibSonameGenerator: libnode={:r}".format(libnode.get_path())) + print("_LibSonameGenerator: libnode=%r" % libnode.get_path()) soname = _call_env_subst(env, '$SONAME', **kw2) if not soname: version = self.get_lib_version(env,**kw2) if Verbose: - print("_LibSonameGenerator: version={:r}".format(version)) + print("_LibSonameGenerator: version=%r" % version) if version: prefix = self.get_lib_prefix(env,**kw2) suffix = self.get_lib_suffix(env,**kw2) @@ -673,10 +583,10 @@ class _LibSonameGenerator(_LibInfoGeneratorBase): # fallback to library name (as returned by appropriate _LibNameGenerator) soname = _LibNameGenerator(self.get_libtype())(env, libnode) if Verbose: - print("_LibSonameGenerator: FALLBACK: soname={:r}".format(soname)) + print("_LibSonameGenerator: FALLBACK: soname=%r" % soname) if Verbose: - print("_LibSonameGenerator: return soname={:r}".format(soname)) + print("_LibSonameGenerator: return soname=%r" % soname) return soname @@ -704,39 +614,39 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw): clean_targets = kw.get('clean_targets', []) if not SCons.Util.is_List(clean_targets): clean_targets = [ clean_targets ] - + for link, linktgt in symlinks: env.SideEffect(link, linktgt) if(Verbose): - print("EmitLibSymlinks: SideEffect({:r},{:r})".format(link.get_path(), linktgt.get_path())) - clean_list = filter(lambda x : x != linktgt, nodes) + print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path())) + clean_list = [x for x in nodes if x != linktgt] env.Clean(list(set([linktgt] + clean_targets)), clean_list) if(Verbose): - print("EmitLibSymlinks: Clean({:r},{:r})".format(linktgt.get_path(), map(lambda x : x.get_path(), clean_list))) + print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list])) def CreateLibSymlinks(env, symlinks): """Physically creates symlinks. The symlinks argument must be a list in form [ (link, linktarget), ... ], where link and linktarget are SCons nodes. """ - + Verbose = False for link, linktgt in symlinks: linktgt = link.get_dir().rel_path(linktgt) link = link.get_path() if(Verbose): - print("CreateLibSymlinks: preparing to add symlink {:r} -> {:r}".format(link, linktgt)) + print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt)) # Delete the (previously created) symlink if exists. Let only symlinks # to be deleted to prevent accidental deletion of source files... if env.fs.islink(link): env.fs.unlink(link) if(Verbose): - print("CreateLibSymlinks: removed old symlink {:r}".format(link)) + print("CreateLibSymlinks: removed old symlink %r" % link) # If a file or directory exists with the same name as link, an OSError # will be thrown, which should be enough, I think. env.fs.symlink(linktgt, link) if(Verbose): - print("CreateLibSymlinks: add symlink {:r} -> {:r}".format(link, linktgt)) + print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt)) return 0 def LibSymlinksActionFunction(target, source, env): @@ -761,7 +671,7 @@ def LibSymlinksStrFun(target, source, env, *args): else: cmd += ": %s" % linkstr return cmd - + LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun) @@ -1040,7 +950,7 @@ class ToolInitializer(object): so we no longer copy and re-bind them when the construction environment gets cloned. """ - for method in self.methods.values(): + for method in list(self.methods.values()): env.RemoveMethod(method) def apply_tools(self, env): @@ -1228,3 +1138,4 @@ def tool_list(platform, env): # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: + -- cgit v0.12 From 1d0d856ede1adca42d190ef4a9532df70961da8e Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 15:08:55 -0400 Subject: fix whitespace in generated dsp file to match expected in test harness. Editor or 2to3 was chopping trailing space --- src/engine/SCons/Tool/msvs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index c3c8164..6df4928 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -550,16 +550,16 @@ V6DSPHeader = """\ CFG=%(name)s - Win32 %(confkey)s !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "%(name)s.mak". -!MESSAGE +!MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE +!MESSAGE !MESSAGE NMAKE /f "%(name)s.mak" CFG="%(name)s - Win32 %(confkey)s" -!MESSAGE +!MESSAGE !MESSAGE Possible choices for configuration are: -!MESSAGE +!MESSAGE """ class _GenerateV6DSP(_DSPGenerator): -- cgit v0.12 From e24a73d1a94ac419d3acf6fe0af6d4ce6cfea3c1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 15:10:20 -0400 Subject: remove reference to six package.. unused --- test/option/profile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/option/profile.py b/test/option/profile.py index 93dad91..4d942cf 100644 --- a/test/option/profile.py +++ b/test/option/profile.py @@ -21,7 +21,6 @@ # 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 SCons.compat.six import u __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -- cgit v0.12 From 5dc3cdfd4df03ca7aa4d7db058e2c0b3926d4c10 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 15:39:10 -0400 Subject: fix broken test. 2to3 print changes broke some formatting. Changed output to generate same in a different way --- test/Variables/ListVariable.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/Variables/ListVariable.py b/test/Variables/ListVariable.py index c6972c1..e463840 100644 --- a/test/Variables/ListVariable.py +++ b/test/Variables/ListVariable.py @@ -67,11 +67,14 @@ opts.Save(optsfile, env) Help(opts.GenerateHelpText(env)) print(env['shared']) -if 'ical' in env['shared']: print('1') -else: print('0') -for x in env['shared']: - print (x,) -print() + +if 'ical' in env['shared']: + print('1') +else: + print('0') + +print(" ".join(env['shared'])) + print(env.subst('$shared')) # Test subst_path() because it's used in $CPPDEFINES expansions. print(env.subst_path('$shared')) -- cgit v0.12 From fdd25f581023b3a4a98a4682ee20c64fb7567f90 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 16:41:15 -0400 Subject: fix error where IOError and OSError exceptions were falling through to the wrong case in Errors.py/convert_to_BuildError().. EnvironmentError is now just an alias in Py3 and it looks like the future module is not properly handling the py3 alias'ing and breaking the py2 exception class hierarchy. --- src/engine/SCons/Errors.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py index 54e888c..3cc9c6d 100644 --- a/src/engine/SCons/Errors.py +++ b/src/engine/SCons/Errors.py @@ -144,6 +144,7 @@ def convert_to_BuildError(status, exc_info=None): if not exc_info and isinstance(status, Exception): exc_info = (status.__class__, status, None) + if isinstance(status, BuildError): buildError = status buildError.exitstatus = 2 # always exit with 2 on build errors @@ -161,14 +162,17 @@ def convert_to_BuildError(status, exc_info=None): status=2, exitstatus=2, exc_info=exc_info) - elif isinstance(status, EnvironmentError): + elif isinstance(status, (EnvironmentError, OSError, IOError)): # If an IOError/OSError happens, raise a BuildError. # Report the name of the file or directory that caused the # error, which might be different from the target being built # (for example, failure to create the directory in which the # target file will appear). - try: filename = status.filename - except AttributeError: filename = None + try: + filename = status.filename + except AttributeError: + filename = None + buildError = BuildError( errstr=status.strerror, status=status.errno, -- cgit v0.12 From 254e647fbe03e280af8f595fff9606d8ec003972 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 18:21:29 -0400 Subject: fix print() conversion on test --- test/Deprecated/Options/ListOption.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/Deprecated/Options/ListOption.py b/test/Deprecated/Options/ListOption.py index ad804f2..42af511 100644 --- a/test/Deprecated/Options/ListOption.py +++ b/test/Deprecated/Options/ListOption.py @@ -68,11 +68,14 @@ opts.Save(optsfile, env) Help(opts.GenerateHelpText(env)) print(env['shared']) -if 'ical' in env['shared']: print('1') -else: print('0') -for x in env['shared']: - print(x, end='') -print() + +if 'ical' in env['shared']: + print('1') +else: + print('0') + +print(" ".join(env['shared'])) + print(env.subst('$shared')) # Test subst_path() because it's used in $CPPDEFINES expansions. print(env.subst_path('$shared')) -- cgit v0.12 From af735035cdaff0fa27fc396539cd51e9effe6e6c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 19:05:00 -0400 Subject: Seeems like EnvironmentError is not yielding the proper error output from SCons under __future__. py 3.5 EnvironmentError is an alias for OSError. Changing to OSError makes the test pass --- test/GetBuildFailures/serial.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/GetBuildFailures/serial.py b/test/GetBuildFailures/serial.py index fb59c7c..55a990f 100644 --- a/test/GetBuildFailures/serial.py +++ b/test/GetBuildFailures/serial.py @@ -82,8 +82,8 @@ Command('f08', 'f08.in', raiseExcAction(SCons.Errors.UserError("My User Error")) Command('f09', 'f09.in', returnExcAction(SCons.Errors.UserError("My User Error"))) Command('f10', 'f10.in', raiseExcAction(MyBuildError(errstr="My Build Error", status=7))) Command('f11', 'f11.in', returnExcAction(MyBuildError(errstr="My Build Error", status=7))) -Command('f12', 'f12.in', raiseExcAction(EnvironmentError(123, "My EnvironmentError", "f12"))) -Command('f13', 'f13.in', returnExcAction(EnvironmentError(123, "My EnvironmentError", "f13"))) +Command('f12', 'f12.in', raiseExcAction(OSError(123, "My EnvironmentError", "f12"))) +Command('f13', 'f13.in', returnExcAction(OSError(123, "My EnvironmentError", "f13"))) Command('f14', 'f14.in', raiseExcAction(SCons.Errors.InternalError("My InternalError"))) Command('f15', 'f15.in', returnExcAction(SCons.Errors.InternalError("My InternalError"))) -- cgit v0.12 From ba64112bdae96d643dbe398c0e4b9cd723348fb8 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 12 May 2016 21:39:57 -0400 Subject: fix print statement in embedded string which generates SConstruct --- test/GetBuildFailures/option-k.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/GetBuildFailures/option-k.py b/test/GetBuildFailures/option-k.py index b4e8d54..0ff22e6 100644 --- a/test/GetBuildFailures/option-k.py +++ b/test/GetBuildFailures/option-k.py @@ -65,7 +65,7 @@ Command('f6', 'f6.in', r'@%(_python_)s mypass.py f5 - $TARGET $SOURCE') def print_build_failures(): from SCons.Script import GetBuildFailures for bf in sorted(GetBuildFailures(), key=lambda a: a.filename): - print "%%s failed: %%s" %% (bf.node, bf.errstr) + print("%%s failed: %%s" %% (bf.node, bf.errstr)) import atexit atexit.register(print_build_failures) -- cgit v0.12 From 0a5aa629ffffda4aa6b960399ff19d59b6b76dd6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 13 May 2016 14:51:22 -0400 Subject: Fixed print()'s. --- QMTest/TestSCons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py index 88d0e9c..a515684 100644 --- a/QMTest/TestSCons.py +++ b/QMTest/TestSCons.py @@ -1152,7 +1152,7 @@ try: print(distutils.sysconfig.get_python_inc()) print(os.path.join(exec_prefix, 'libs')) except: - print(os.path.join(sys.prefix, 'include', py_ver) + print(os.path.join(sys.prefix, 'include', py_ver)) print(os.path.join(sys.prefix, 'lib', py_ver, 'config')) print(py_ver) """) -- cgit v0.12 From b8ba51c52564ddf72a4f3dc229c35e081937aafa Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 13 May 2016 16:12:14 -0400 Subject: Restore deleted function _scons_file() in win32.py. This is causing most tests to fail in win32. See if this resolves. --- src/engine/SCons/Platform/win32.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 8ba8218..269007d 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -63,6 +63,13 @@ else: _builtin_file = file _builtin_open = open + class _scons_file(_builtin_file): + def __init__(self, *args, **kw): + _builtin_file.__init__(self, *args, **kw) + win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()), + win32con.HANDLE_FLAG_INHERIT, 0) + + def _scons_open(*args, **kw): fp = _builtin_open(*args, **kw) win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()), -- cgit v0.12 From 9dc0f8feb825d50da88009c84fc274fb489d3a19 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 13 May 2016 16:30:20 -0700 Subject: fixes for print()'s for win32 --- QMTest/TestSConsMSVS.py | 4 ++-- src/engine/SCons/Action.py | 4 ++-- src/engine/SCons/Taskmaster.py | 6 +++++- test/MSVC/query_vcbat.py | 2 +- test/MSVS/vs-8.0-exec.py | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index 7459af0..39dbb5e 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -1037,8 +1037,8 @@ class TestSConsMSVS(TestSCons): input = """\ import SCons import SCons.Tool.MSCommon -print "self.scons_version =", repr(SCons.__%s__) -print "self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions()) +print("self.scons_version =", repr(SCons.__%s__)) +print("self._msvs_versions =", str(SCons.Tool.MSCommon.query_versions())) """ % 'version' self.run(arguments = '-n -q -Q -f -', stdin = input) diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index a4e75f3..7e1f8f1 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -233,8 +233,8 @@ def _code_contents(code): # The code contents depends on the number of local variables # but not their actual names. - contents.append("{}, {}".format(code.co_argcount, len(code.co_varnames))) - contents.append(", {}, {}".format(len(code.co_cellvars), len(code.co_freevars))) + contents.append(b"{}, {}".format(code.co_argcount, len(code.co_varnames))) + contents.append(b", {}, {}".format(len(code.co_cellvars), len(code.co_freevars))) # The code contents depends on any constants accessed by the # function. Note that we have to call _object_contents on each diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 7260071..ddafeb9 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -539,7 +539,11 @@ class Task(object): except ValueError: exc_type, exc_value = exc exc_traceback = None - raise exc_type, exc_value, exc_traceback + # raise exc_type, exc_value, exc_traceback + raise exc_type(exc_value).with_traceback(exc_traceback) + + # raise e.__class__, e.__class__(e), sys.exc_info()[2] + class AlwaysTask(Task): def needs_execute(self): diff --git a/test/MSVC/query_vcbat.py b/test/MSVC/query_vcbat.py index 328345d..428fe56 100644 --- a/test/MSVC/query_vcbat.py +++ b/test/MSVC/query_vcbat.py @@ -49,7 +49,7 @@ DefaultEnvironment(tools = []) # print k, v #MergeMSVSBatFile(env, 9.0) #print env['ENV']['PATH'] -print query_versions() +print(query_versions()) """) test.run(stderr = None) diff --git a/test/MSVS/vs-8.0-exec.py b/test/MSVS/vs-8.0-exec.py index cff7ca2..96c4c29 100644 --- a/test/MSVS/vs-8.0-exec.py +++ b/test/MSVS/vs-8.0-exec.py @@ -55,7 +55,7 @@ if not msvs_version in test.msvs_versions(): test.run(arguments = '-n -q -Q -f -', stdin = """\ env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s') -print "os.environ.update(%%s)" %% repr(env['ENV']) +print("os.environ.update(%%s)" %% repr(env['ENV'])) """ % locals()) exec(test.stdout()) -- cgit v0.12 From 547a704c080c97304425fcde1eb2381d9f395352 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 13 May 2016 20:43:15 -0700 Subject: fix default open mode for test.write() to be wb.. it was changed to just w when six was the plan. it causes many tests to fail on win32 --- QMTest/TestCmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 8cb6fb9..198f586 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1719,7 +1719,7 @@ class TestCmd(object): do_chmod(os.path.join(dirpath, name)) do_chmod(top) - def write(self, file, content, mode = 'w'): + def write(self, file, content, mode = 'wb'): """Writes the specified content text (second argument) to the specified file name (first argument). The file name may be a list, in which case the elements are concatenated with the -- cgit v0.12 From 96ba1793cf7346a6fdbee6bfd843cdbd3efebedf Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 14 May 2016 15:37:00 -0700 Subject: Fix re-raising exception so the syntax will work for both python3 and python2. --- src/engine/SCons/Taskmaster.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index ddafeb9..0f4fd21 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -22,6 +22,8 @@ from __future__ import print_function +import sys + __doc__ = """ Generic Taskmaster module for the SCons build engine. @@ -539,8 +541,11 @@ class Task(object): except ValueError: exc_type, exc_value = exc exc_traceback = None - # raise exc_type, exc_value, exc_traceback - raise exc_type(exc_value).with_traceback(exc_traceback) + + if sys.version_info[0] == 2: + exec("raise exc_type, exc_value, exc_traceback") + else: # sys.version_info[0] == 3: + exec("raise exc_type(exc_value).with_traceback(exc_traceback)") # raise e.__class__, e.__class__(e), sys.exc_info()[2] -- cgit v0.12 From 9f4e808d1b38635151876a6ee513eae279b48c19 Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 14 May 2016 15:41:52 -0700 Subject: Fix print() --- test/MSVS/vs-10.0-exec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/MSVS/vs-10.0-exec.py b/test/MSVS/vs-10.0-exec.py index 86b4042..1a4b59a 100644 --- a/test/MSVS/vs-10.0-exec.py +++ b/test/MSVS/vs-10.0-exec.py @@ -55,7 +55,7 @@ if not msvs_version in test.msvs_versions(): test.run(arguments = '-n -q -Q -f -', stdin = """\ env = Environment(tools = ['msvc'], MSVS_VERSION='%(msvs_version)s') -print "os.environ.update(%%s)" %% repr(env['ENV']) +print("os.environ.update(%%s)" %% repr(env['ENV'])) """ % locals()) exec(test.stdout()) -- cgit v0.12 From df76f938024f9d1ee96166bd9660886acd99f5de Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 14 May 2016 15:42:36 -0700 Subject: Fix print() --- test/Win32/bad-drive.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Win32/bad-drive.py b/test/Win32/bad-drive.py index 4d0d6e9..67a287a 100644 --- a/test/Win32/bad-drive.py +++ b/test/Win32/bad-drive.py @@ -59,7 +59,7 @@ test.write('SConstruct', """ def cat(env, source, target): target = str(target[0]) source = list(map(str, source)) - print 'cat(%%s) > %%s' %% (source, target) + print('cat(%%s) > %%s' %% (source, target)) f = open(target, "wb") for src in source: f.write(open(src, "rb").read()) -- cgit v0.12 From be27b009e8b59ff8b6605459bf39fe8590a37cf0 Mon Sep 17 00:00:00 2001 From: Bill Date: Sat, 14 May 2016 15:43:31 -0700 Subject: Fix print() --- test/Win32/mingw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Win32/mingw.py b/test/Win32/mingw.py index 6b23314..80067bc 100644 --- a/test/Win32/mingw.py +++ b/test/Win32/mingw.py @@ -47,7 +47,7 @@ from SCons.Tool.mingw import exists import sys env = Environment() if exists(env): - print 'mingw exists' + print('mingw exists') sys.exit(0) """) -- cgit v0.12 From 39d873ea2789008bb153026d730c3a6541331be4 Mon Sep 17 00:00:00 2001 From: William Blevins Date: Sun, 15 May 2016 13:13:31 +0100 Subject: Fixed Fortran tests which were throughing missing include directory warning. Warning added in gcc5. --- test/Fortran/F77FLAGS.py | 5 ++++- test/Fortran/FORTRANFLAGS.py | 5 ++++- test/Fortran/SHF77FLAGS.py | 5 ++++- test/Fortran/SHFORTRANFLAGS.py | 5 ++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/Fortran/F77FLAGS.py b/test/Fortran/F77FLAGS.py index b708f9e..342adac 100644 --- a/test/Fortran/F77FLAGS.py +++ b/test/Fortran/F77FLAGS.py @@ -77,6 +77,9 @@ g77 = test.detect_tool(fc) if g77: + directory = 'x' + test.subdir(directory) + test.write("wrapper.py", """import os import sys @@ -87,7 +90,7 @@ os.system(" ".join(sys.argv[1:])) test.write('SConstruct', """ foo = Environment(F77 = '%(fc)s', tools = ['default', 'f77'], F77FILESUFFIXES = [".f"]) f77 = foo.Dictionary('F77') -bar = foo.Clone(F77 = r'%(_python_)s wrapper.py ' + f77, F77FLAGS = '-Ix') +bar = foo.Clone(F77 = r'%(_python_)s wrapper.py ' + f77, F77FLAGS = '-I%(directory)s') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') """ % locals()) diff --git a/test/Fortran/FORTRANFLAGS.py b/test/Fortran/FORTRANFLAGS.py index 8c5e781..150000a 100644 --- a/test/Fortran/FORTRANFLAGS.py +++ b/test/Fortran/FORTRANFLAGS.py @@ -95,6 +95,9 @@ g77 = test.detect_tool(fc) if g77: + directory = 'x' + test.subdir(directory) + test.write("wrapper.py", """import os import sys @@ -105,7 +108,7 @@ os.system(" ".join(sys.argv[1:])) test.write('SConstruct', """ foo = Environment(FORTRAN = '%(fc)s') f77 = foo.Dictionary('FORTRAN') -bar = foo.Clone(FORTRAN = r'%(_python_)s wrapper.py ' + f77, FORTRANFLAGS = '-Ix') +bar = foo.Clone(FORTRAN = r'%(_python_)s wrapper.py ' + f77, FORTRANFLAGS = '-I%(directory)s') foo.Program(target = 'foo', source = 'foo.f') bar.Program(target = 'bar', source = 'bar.f') """ % locals()) diff --git a/test/Fortran/SHF77FLAGS.py b/test/Fortran/SHF77FLAGS.py index 644b827..79e46f3 100644 --- a/test/Fortran/SHF77FLAGS.py +++ b/test/Fortran/SHF77FLAGS.py @@ -75,6 +75,9 @@ g77 = test.detect_tool(fc) if g77: + directory = 'x' + test.subdir(directory) + test.write("wrapper.py", """import os import sys @@ -87,7 +90,7 @@ foo = Environment(SHF77 = '%(fc)s') shf77 = foo.Dictionary('SHF77') bar = foo.Clone(SHF77 = r'%(_python_)s wrapper.py ' + shf77, tools = ["default", 'f77'], F77FILESUFFIXES = [".f"]) -bar.Append(SHF77FLAGS = '-Ix') +bar.Append(SHF77FLAGS = '-I%(directory)s') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') """ % locals()) diff --git a/test/Fortran/SHFORTRANFLAGS.py b/test/Fortran/SHFORTRANFLAGS.py index 11116f4..8e6f019 100644 --- a/test/Fortran/SHFORTRANFLAGS.py +++ b/test/Fortran/SHFORTRANFLAGS.py @@ -91,6 +91,9 @@ fortran = test.detect_tool(fc) if fortran: + directory = 'x' + test.subdir(directory) + test.write("wrapper.py", """import os import sys @@ -102,7 +105,7 @@ os.system(" ".join(sys.argv[1:])) foo = Environment(SHFORTRAN = '%(fc)s') shfortran = foo.Dictionary('SHFORTRAN') bar = foo.Clone(SHFORTRAN = r'%(_python_)s wrapper.py ' + shfortran) -bar.Append(SHFORTRANFLAGS = '-Ix') +bar.Append(SHFORTRANFLAGS = '-I%(directory)s') foo.SharedLibrary(target = 'foo/foo', source = 'foo.f') bar.SharedLibrary(target = 'bar/bar', source = 'bar.f') """ % locals()) -- cgit v0.12 From 59543b3ca4070ba5b35c055780a244a29beadd8a Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 May 2016 07:55:12 -0700 Subject: fix incorrectly updated print formatting --- src/engine/SCons/Node/FS.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index a4dd5d9..d19afa9 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -3082,7 +3082,7 @@ class File(Base): try: self._createDir() except SCons.Errors.StopError as drive: - raise SCons.Errors.StopError("No drive `%s' for target `{}'.".format(drive, self)) + raise SCons.Errors.StopError("No drive `{}' for target `{}'.".format(drive, self)) # # -- cgit v0.12 From 6ea744952d40c63c98f8b04e1b9a8e7ce73992c3 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 May 2016 11:44:48 -0700 Subject: Update logic to pull files from mercurial --- bin/scons_dev_master.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/scons_dev_master.py b/bin/scons_dev_master.py index a8862ea..71842aa 100644 --- a/bin/scons_dev_master.py +++ b/bin/scons_dev_master.py @@ -11,7 +11,7 @@ import sys from Command import CommandRunner, Usage INITIAL_PACKAGES = [ - 'subversion', + 'mercurial', ] INSTALL_PACKAGES = [ @@ -123,7 +123,7 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER] buildbot Install packages for running BuildBot """ - scons_url = 'http://scons.tigris.org/svn/scons/trunk' + scons_url = 'https://bdbaddog@bitbucket.org/scons/scons' sudo = 'sudo' password = '""' username = 'guest' @@ -171,7 +171,7 @@ Usage: scons_dev_master.py [-hnqy] [--password PASSWORD] [--username USER] cmd.run('%(sudo)s apt-get %(yesflag)s upgrade') elif arg == 'checkout': cmd.run('%(sudo)s apt-get %(yesflag)s install %(initial_packages)s') - cmd.run('svn co --username guest --password "" %(scons_url)s') + cmd.run('hg clone" %(scons_url)s') elif arg == 'building': cmd.run('%(sudo)s apt-get %(yesflag)s install %(building_packages)s') elif arg == 'testing': -- cgit v0.12 From c5e30d23ebc878acb8e16e025b6f55aaab43f3a5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 May 2016 12:27:51 -0700 Subject: change to handle py3 changes to byte/string for open().write() --- QMTest/TestCmd.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/QMTest/TestCmd.py b/QMTest/TestCmd.py index 198f586..2fba0a0 100644 --- a/QMTest/TestCmd.py +++ b/QMTest/TestCmd.py @@ -1731,7 +1731,11 @@ class TestCmd(object): file = self.canonicalize(file) if mode[0] != 'w': raise ValueError("mode must begin with 'w'") - open(file, mode).write(content) + try: + open(file, mode).write(content) + except TypeError as e: + # python 3 default strings are not bytes, but unicode + open(file, mode).write(bytes(content,'utf-8')) # Local Variables: # tab-width:4 -- cgit v0.12 From fd9c768bf1b749a15d56481a49f7d60dd22a7ef6 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 15 May 2016 15:16:34 -0700 Subject: revert some py3 changes which fail no py2 on windows and any platform/python without dbm module installed. Revisit py3 issues after we get py2 working again --- src/script/sconsign.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/script/sconsign.py b/src/script/sconsign.py index 6f49858..e046a2c 100644 --- a/src/script/sconsign.py +++ b/src/script/sconsign.py @@ -187,7 +187,9 @@ sys.path = libs + sys.path import SCons.compat import whichdb -import dbm + +# was added for py3, but breaks py2 on windows.. +#import dbm import time import pickle import imp @@ -205,8 +207,14 @@ def my_whichdb(filename): pass return _orig_whichdb(filename) + +# Should work on python2 _orig_whichdb = whichdb.whichdb -dbm.whichdb = my_whichdb +whichdb.whichdb = my_whichdb + +# was changed for python3 +#_orig_whichdb = whichdb.whichdb +#dbm.whichdb = my_whichdb def my_import(mname): if '.' in mname: @@ -523,7 +531,9 @@ if Do_Call: Do_Call(a) else: for a in args: - dbm_name = dbm.whichdb(a) + # changed for py3 compat, broke py2 on windows + # dbm_name = dbm.whichdb(a) + dbm_name = whichdb.whichdb(a) if dbm_name: Map_Module = {'SCons.dblite' : 'dblite'} if dbm_name != "SCons.dblite": -- cgit v0.12 From b763362d906af8e23409a1f5d3dc782b0ca3cc91 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 18 May 2016 19:09:05 -0700 Subject: Fix py2/3 StringIO import --- src/engine/SCons/Script/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 974841c..66120e4 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -41,7 +41,12 @@ start_time = time.time() import collections import os -import StringIO + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + import sys # Special chicken-and-egg handling of the "--debug=memoizer" flag: -- cgit v0.12 From 7d7012b21a1434ab03cead57e4b8926c8b5ef153 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Wed, 18 May 2016 19:58:51 -0700 Subject: fix for module loading to us importlib instead of imp (which no longer works in pyton3) --- src/engine/SCons/Tool/__init__.py | 68 +++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 4cd242b..87ebb98 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -38,11 +38,13 @@ tool definition. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import imp +import importlib import sys import re import os import shutil + import SCons.Builder import SCons.Errors import SCons.Node.FS @@ -114,30 +116,56 @@ class Tool(object): sys.path = self.toolpath + sys.path try: + # Try site_tools first + return importlib.import_module(self.name) + except ImportError as e: + # Then try modules in main distribution + return importlib.import_module('SCons.Tool.'+self.name) + except ImportError as e: + if str(e) != "No module named %s" % self.name: + raise SCons.Errors.EnvironmentError(e) try: - file, path, desc = imp.find_module(self.name, self.toolpath) - try: - return imp.load_module(self.name, file, path, desc) - finally: - if file: - file.close() - except ImportError as e: - if str(e)!="No module named %s"%self.name: - raise SCons.Errors.EnvironmentError(e) - try: - import zipimport - except ImportError: - pass - else: - for aPath in self.toolpath: - try: - importer = zipimport.zipimporter(aPath) - return importer.load_module(self.name) - except ImportError as e: - pass + import zipimport + except ImportError: + pass + else: + for aPath in self.toolpath: + try: + importer = zipimport.zipimporter(aPath) + return importer.load_module(self.name) + except ImportError as e: + pass + finally: sys.path = oldpythonpath + # old code + # try: + # try: + # file, path, desc = imp.find_module(self.name, self.toolpath) + # try: + # return imp.load_module(self.name, file, path, desc) + # + # finally: + # if file: + # file.close() + # except ImportError as e: + # if str(e)!="No module named %s"%self.name: + # raise SCons.Errors.EnvironmentError(e) + # try: + # import zipimport + # except ImportError: + # pass + # else: + # for aPath in self.toolpath: + # try: + # importer = zipimport.zipimporter(aPath) + # return importer.load_module(self.name) + # except ImportError as e: + # pass + # finally: + # sys.path = oldpythonpath + full_name = 'SCons.Tool.' + self.name try: return sys.modules[full_name] -- cgit v0.12 From 01ab580ffdd90459f729d44efa6a3f0cc733fbf5 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 May 2016 09:03:06 -0700 Subject: Fix unicode type code to handle py2/3 --- src/engine/SCons/Util.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index a5a92fa..0be6196 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -55,9 +55,13 @@ except ImportError as e: MethodType = types.MethodType FunctionType = types.FunctionType -try: unicode -except NameError: UnicodeType = None -else: UnicodeType = unicode + +try: + unicode +except NameError: + UnicodeType = str +else: + UnicodeType = unicode def dictify(keys, values, result={}): for k, v in zip(keys, values): @@ -172,7 +176,7 @@ class DisplayEngine(object): return if append_newline: text = text + '\n' try: - sys.stdout.write(unicode(text)) + sys.stdout.write(UnicodeType(text)) except IOError: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed -- cgit v0.12 From 6cb5d61fa6244c37b2aeb0255e47b9b749d3f4d1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 May 2016 09:10:34 -0700 Subject: minor improvement to Tool loading code for py2/3 compat --- src/engine/SCons/Tool/__init__.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 87ebb98..1590053 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -120,21 +120,22 @@ class Tool(object): return importlib.import_module(self.name) except ImportError as e: # Then try modules in main distribution - return importlib.import_module('SCons.Tool.'+self.name) - except ImportError as e: - if str(e) != "No module named %s" % self.name: - raise SCons.Errors.EnvironmentError(e) try: - import zipimport - except ImportError: - pass - else: - for aPath in self.toolpath: - try: - importer = zipimport.zipimporter(aPath) - return importer.load_module(self.name) - except ImportError as e: - pass + return importlib.import_module('SCons.Tool.'+self.name) + except ImportError as e: + if str(e) != "No module named %s" % self.name: + raise SCons.Errors.EnvironmentError(e) + try: + import zipimport + except ImportError: + pass + else: + for aPath in self.toolpath: + try: + importer = zipimport.zipimporter(aPath) + return importer.load_module(self.name) + except ImportError as e: + pass finally: sys.path = oldpythonpath -- cgit v0.12 From 2b20141f5bc6fb7aedd9a24e4c8079e82d52d260 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 19 May 2016 10:53:46 -0700 Subject: Fixing StringIO usage. --- src/engine/SCons/Script/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 66120e4..291c108 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -269,7 +269,7 @@ def HelpFunction(text, append=False): global help_text if help_text is None: if append: - s = StringIO.StringIO() + s = StringIO() PrintHelp(s) help_text = s.getvalue() s.close() -- cgit v0.12 From 561eda349061019df9c8aa904de62896b12472c0 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 23 May 2016 10:00:43 -0700 Subject: use old tool loading code for py2, and new code (not quite working yet) for py3 --- src/engine/SCons/Tool/__init__.py | 101 ++++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 48 deletions(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index 1590053..d75d7ca 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -115,57 +115,62 @@ class Tool(object): oldpythonpath = sys.path sys.path = self.toolpath + sys.path - try: - # Try site_tools first - return importlib.import_module(self.name) - except ImportError as e: - # Then try modules in main distribution + + if False and sys.version_info[0] < 3: + # Py 2 code try: - return importlib.import_module('SCons.Tool.'+self.name) + try: + file, path, desc = imp.find_module(self.name, self.toolpath) + try: + return imp.load_module(self.name, file, path, desc) + + finally: + if file: + file.close() + except ImportError as e: + if str(e)!="No module named %s"%self.name: + raise SCons.Errors.EnvironmentError(e) + try: + import zipimport + except ImportError: + pass + else: + for aPath in self.toolpath: + try: + importer = zipimport.zipimporter(aPath) + return importer.load_module(self.name) + except ImportError as e: + pass + finally: + sys.path = oldpythonpath + else: + # Py 3 code + try: + # Try site_tools first + return importlib.import_module(self.name) except ImportError as e: - if str(e) != "No module named %s" % self.name: - raise SCons.Errors.EnvironmentError(e) + # Then try modules in main distribution try: - import zipimport - except ImportError: - pass - else: - for aPath in self.toolpath: - try: - importer = zipimport.zipimporter(aPath) - return importer.load_module(self.name) - except ImportError as e: - pass - - finally: - sys.path = oldpythonpath - - # old code - # try: - # try: - # file, path, desc = imp.find_module(self.name, self.toolpath) - # try: - # return imp.load_module(self.name, file, path, desc) - # - # finally: - # if file: - # file.close() - # except ImportError as e: - # if str(e)!="No module named %s"%self.name: - # raise SCons.Errors.EnvironmentError(e) - # try: - # import zipimport - # except ImportError: - # pass - # else: - # for aPath in self.toolpath: - # try: - # importer = zipimport.zipimporter(aPath) - # return importer.load_module(self.name) - # except ImportError as e: - # pass - # finally: - # sys.path = oldpythonpath + return importlib.import_module('SCons.Tool.'+self.name) + except ImportError as e: + if str(e) != "No module named %s" % self.name: + raise SCons.Errors.EnvironmentError(e) + try: + import zipimport + except ImportError: + pass + else: + for aPath in self.toolpath: + try: + importer = zipimport.zipimporter(aPath) + return importer.load_module(self.name) + except ImportError as e: + pass + + finally: + sys.path = oldpythonpath + + full_name = 'SCons.Tool.' + self.name try: -- cgit v0.12 From b387e34357c968d0855c525c7e838657a957ff01 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 23 May 2016 10:35:46 -0700 Subject: Remove debug code to reenable python version specific tool module loading code. --- src/engine/SCons/Tool/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py index d75d7ca..45d0aa1 100644 --- a/src/engine/SCons/Tool/__init__.py +++ b/src/engine/SCons/Tool/__init__.py @@ -116,7 +116,7 @@ class Tool(object): sys.path = self.toolpath + sys.path - if False and sys.version_info[0] < 3: + if sys.version_info[0] < 3: # Py 2 code try: try: -- cgit v0.12