summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Falavigna <dktrkranz@debian.org>2010-06-15 14:28:28 +0000
committerLuca Falavigna <dktrkranz@debian.org>2010-06-15 14:28:28 +0000
commit0ed55e71a9f4b9cda836c6a4a5408cece60db0c6 (patch)
treeb1e82f6e428ac15ed9b4de93e48d8079420d537d
parentfe00e4f75ba00298c30d6854b245c2a42c6542b8 (diff)
parent738149c9bfb9965d013d01ef99f9bb1c2819e7e8 (diff)
Merge commit 'upstream/2.0.0'
-rw-r--r--SConstruct174
-rw-r--r--bin/Command.py8
-rw-r--r--bin/SConsDoc.py18
-rw-r--r--bin/calibrate.py3
-rw-r--r--bin/caller-tree.py2
-rw-r--r--bin/import-test.py23
-rw-r--r--bin/install_python.py25
-rw-r--r--bin/install_scons.py9
-rw-r--r--bin/linecount.py29
-rw-r--r--bin/memoicmp.py25
-rw-r--r--bin/objcounts.py14
-rw-r--r--bin/restore.sh22
-rw-r--r--bin/scons-diff.py12
-rw-r--r--bin/scons-doc.py115
-rw-r--r--bin/scons-proc.py61
-rw-r--r--bin/scons-test.py25
-rw-r--r--bin/scons-unzip.py4
-rw-r--r--bin/sconsexamples.py63
-rw-r--r--bin/sfsum9
-rwxr-xr-xbin/svn-bisect.py3
-rw-r--r--bin/time-scons.py14
-rw-r--r--bin/update-release-info.py354
-rwxr-xr-xbin/xmlagenda.py79
-rw-r--r--doc/SConscript35
-rw-r--r--doc/design/engine.xml12
-rw-r--r--doc/design/goals.xml2
-rw-r--r--doc/design/native.xml6
-rw-r--r--doc/design/overview.xml2
-rw-r--r--doc/developer/preface.xml2
-rw-r--r--doc/man/scons-time.14
-rw-r--r--doc/man/scons.188
-rw-r--r--doc/man/sconsign.14
-rw-r--r--doc/python10/abstract.xml2
-rw-r--r--doc/python10/design.xml50
-rw-r--r--doc/python10/main.xml2
-rw-r--r--doc/python10/process.xml4
-rw-r--r--doc/scons.mod7
-rw-r--r--doc/user/actions.in4
-rw-r--r--doc/user/actions.xml4
-rw-r--r--doc/user/build-install.in35
-rw-r--r--doc/user/build-install.xml35
-rw-r--r--doc/user/builders-built-in.in13
-rw-r--r--doc/user/builders-built-in.xml13
-rw-r--r--doc/user/builders-writing.in30
-rw-r--r--doc/user/builders-writing.xml14
-rw-r--r--doc/user/command-line.in8
-rw-r--r--doc/user/command-line.xml8
-rw-r--r--doc/user/depends.in7
-rw-r--r--doc/user/depends.xml7
-rw-r--r--doc/user/environments.in88
-rw-r--r--doc/user/environments.xml89
-rw-r--r--doc/user/less-simple.in2
-rw-r--r--doc/user/less-simple.xml2
-rw-r--r--doc/user/main.in11
-rw-r--r--doc/user/main.xml7
-rw-r--r--doc/user/misc.in4
-rw-r--r--doc/user/misc.xml6
-rw-r--r--doc/user/nodes.in45
-rw-r--r--doc/user/nodes.xml45
-rw-r--r--doc/user/parseflags.in16
-rw-r--r--doc/user/parseflags.xml16
-rw-r--r--doc/user/scanners.in50
-rw-r--r--doc/user/scanners.xml48
-rw-r--r--doc/user/tasks.in27
-rw-r--r--doc/user/tasks.xml27
-rw-r--r--doc/user/troubleshoot.xml40
-rw-r--r--src/Announce.txt1060
-rw-r--r--src/CHANGES.txt155
-rw-r--r--src/README.txt52
-rw-r--r--src/RELEASE.txt1098
-rw-r--r--src/engine/MANIFEST-xml.in1
-rw-r--r--src/engine/MANIFEST.in11
-rw-r--r--src/engine/README.txt4
-rw-r--r--src/engine/SCons/Action.py147
-rw-r--r--src/engine/SCons/ActionTests.py167
-rw-r--r--src/engine/SCons/Builder.py111
-rw-r--r--src/engine/SCons/BuilderTests.py203
-rw-r--r--src/engine/SCons/CacheDir.py9
-rw-r--r--src/engine/SCons/CacheDirTests.py10
-rw-r--r--src/engine/SCons/Conftest.py11
-rw-r--r--src/engine/SCons/Debug.py63
-rw-r--r--src/engine/SCons/Defaults.py49
-rw-r--r--src/engine/SCons/DefaultsTests.py12
-rw-r--r--src/engine/SCons/Environment.py264
-rw-r--r--src/engine/SCons/EnvironmentTests.py443
-rw-r--r--src/engine/SCons/Errors.py8
-rw-r--r--src/engine/SCons/ErrorsTests.py8
-rw-r--r--src/engine/SCons/Executor.py65
-rw-r--r--src/engine/SCons/ExecutorTests.py43
-rw-r--r--src/engine/SCons/Job.py34
-rw-r--r--src/engine/SCons/JobTests.py27
-rw-r--r--src/engine/SCons/Memoize.py106
-rw-r--r--src/engine/SCons/MemoizeTests.py24
-rw-r--r--src/engine/SCons/Node/Alias.py13
-rw-r--r--src/engine/SCons/Node/AliasTests.py6
-rw-r--r--src/engine/SCons/Node/FS.py248
-rw-r--r--src/engine/SCons/Node/FSTests.py214
-rw-r--r--src/engine/SCons/Node/NodeTests.py127
-rw-r--r--src/engine/SCons/Node/Python.py4
-rw-r--r--src/engine/SCons/Node/PythonTests.py6
-rw-r--r--src/engine/SCons/Node/__init__.py87
-rw-r--r--src/engine/SCons/Options/BoolOption.py4
-rw-r--r--src/engine/SCons/Options/EnumOption.py4
-rw-r--r--src/engine/SCons/Options/ListOption.py4
-rw-r--r--src/engine/SCons/Options/PackageOption.py4
-rw-r--r--src/engine/SCons/Options/PathOption.py16
-rw-r--r--src/engine/SCons/Options/__init__.py19
-rw-r--r--src/engine/SCons/PathList.py11
-rw-r--r--src/engine/SCons/PathListTests.py12
-rw-r--r--src/engine/SCons/Platform/PlatformTests.py8
-rw-r--r--src/engine/SCons/Platform/__init__.py43
-rw-r--r--src/engine/SCons/Platform/aix.py9
-rw-r--r--src/engine/SCons/Platform/cygwin.py2
-rw-r--r--src/engine/SCons/Platform/darwin.py2
-rw-r--r--src/engine/SCons/Platform/hpux.py2
-rw-r--r--src/engine/SCons/Platform/irix.py2
-rw-r--r--src/engine/SCons/Platform/os2.py4
-rw-r--r--src/engine/SCons/Platform/posix.py27
-rw-r--r--src/engine/SCons/Platform/sunos.py2
-rw-r--r--src/engine/SCons/Platform/win32.py37
-rw-r--r--src/engine/SCons/SConf.py72
-rw-r--r--src/engine/SCons/SConfTests.py25
-rw-r--r--src/engine/SCons/SConsign.py24
-rw-r--r--src/engine/SCons/SConsignTests.py20
-rw-r--r--src/engine/SCons/Scanner/C.py6
-rw-r--r--src/engine/SCons/Scanner/CTests.py23
-rw-r--r--src/engine/SCons/Scanner/D.py5
-rw-r--r--src/engine/SCons/Scanner/Dir.py16
-rw-r--r--src/engine/SCons/Scanner/DirTests.py16
-rw-r--r--src/engine/SCons/Scanner/Fortran.py14
-rw-r--r--src/engine/SCons/Scanner/FortranTests.py20
-rw-r--r--src/engine/SCons/Scanner/IDL.py2
-rw-r--r--src/engine/SCons/Scanner/IDLTests.py20
-rw-r--r--src/engine/SCons/Scanner/LaTeX.py56
-rw-r--r--src/engine/SCons/Scanner/LaTeXTests.py22
-rw-r--r--src/engine/SCons/Scanner/Prog.py8
-rw-r--r--src/engine/SCons/Scanner/ProgTests.py49
-rw-r--r--src/engine/SCons/Scanner/RC.py2
-rw-r--r--src/engine/SCons/Scanner/RCTests.py21
-rw-r--r--src/engine/SCons/Scanner/ScannerTests.py46
-rw-r--r--src/engine/SCons/Scanner/__init__.py36
-rw-r--r--src/engine/SCons/Script/Interactive.py22
-rw-r--r--src/engine/SCons/Script/Main.py132
-rw-r--r--src/engine/SCons/Script/MainTests.py4
-rw-r--r--src/engine/SCons/Script/SConsOptions.py65
-rw-r--r--src/engine/SCons/Script/SConscript.py70
-rw-r--r--src/engine/SCons/Script/SConscriptTests.py2
-rw-r--r--src/engine/SCons/Script/__init__.py16
-rw-r--r--src/engine/SCons/Sig.py4
-rw-r--r--src/engine/SCons/Subst.py103
-rw-r--r--src/engine/SCons/SubstTests.py96
-rw-r--r--src/engine/SCons/Taskmaster.py79
-rw-r--r--src/engine/SCons/TaskmasterTests.py39
-rw-r--r--src/engine/SCons/Tool/386asm.py2
-rw-r--r--src/engine/SCons/Tool/BitKeeper.py4
-rw-r--r--src/engine/SCons/Tool/CVS.py6
-rw-r--r--src/engine/SCons/Tool/FortranCommon.py17
-rw-r--r--src/engine/SCons/Tool/JavaCommon.py23
-rw-r--r--src/engine/SCons/Tool/JavaCommonTests.py4
-rw-r--r--src/engine/SCons/Tool/MSCommon/__init__.py2
-rw-r--r--src/engine/SCons/Tool/MSCommon/arch.py4
-rw-r--r--src/engine/SCons/Tool/MSCommon/common.py62
-rw-r--r--src/engine/SCons/Tool/MSCommon/netframework.py10
-rw-r--r--src/engine/SCons/Tool/MSCommon/sdk.py22
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py182
-rw-r--r--src/engine/SCons/Tool/MSCommon/vc.py.bak394
-rw-r--r--src/engine/SCons/Tool/MSCommon/vs.py36
-rw-r--r--src/engine/SCons/Tool/Perforce.py7
-rw-r--r--src/engine/SCons/Tool/PharLapCommon.py15
-rw-r--r--src/engine/SCons/Tool/PharLapCommonTests.py2
-rw-r--r--src/engine/SCons/Tool/RCS.py6
-rw-r--r--src/engine/SCons/Tool/SCCS.py6
-rw-r--r--src/engine/SCons/Tool/Subversion.py6
-rw-r--r--src/engine/SCons/Tool/ToolTests.py8
-rw-r--r--src/engine/SCons/Tool/__init__.py68
-rw-r--r--src/engine/SCons/Tool/__init__.xml4
-rw-r--r--src/engine/SCons/Tool/aixc++.py2
-rw-r--r--src/engine/SCons/Tool/aixcc.py2
-rw-r--r--src/engine/SCons/Tool/aixf77.py2
-rw-r--r--src/engine/SCons/Tool/aixlink.py2
-rw-r--r--src/engine/SCons/Tool/applelink.py2
-rw-r--r--src/engine/SCons/Tool/ar.py2
-rw-r--r--src/engine/SCons/Tool/as.py2
-rw-r--r--src/engine/SCons/Tool/bcc32.py3
-rw-r--r--src/engine/SCons/Tool/c++.py2
-rw-r--r--src/engine/SCons/Tool/cc.py20
-rw-r--r--src/engine/SCons/Tool/cvf.py2
-rw-r--r--src/engine/SCons/Tool/default.py2
-rw-r--r--src/engine/SCons/Tool/dmd.py5
-rw-r--r--src/engine/SCons/Tool/dvi.py2
-rw-r--r--src/engine/SCons/Tool/dvipdf.py5
-rw-r--r--src/engine/SCons/Tool/dvips.py2
-rw-r--r--src/engine/SCons/Tool/f77.py2
-rw-r--r--src/engine/SCons/Tool/f90.py2
-rw-r--r--src/engine/SCons/Tool/f95.py2
-rw-r--r--src/engine/SCons/Tool/filesystem.py6
-rw-r--r--src/engine/SCons/Tool/fortran.py3
-rw-r--r--src/engine/SCons/Tool/g++.py2
-rw-r--r--src/engine/SCons/Tool/g77.py2
-rw-r--r--src/engine/SCons/Tool/gas.py2
-rw-r--r--src/engine/SCons/Tool/gcc.py2
-rw-r--r--src/engine/SCons/Tool/gfortran.py2
-rw-r--r--src/engine/SCons/Tool/gnulink.py2
-rw-r--r--src/engine/SCons/Tool/gs.py4
-rw-r--r--src/engine/SCons/Tool/hpc++.py7
-rw-r--r--src/engine/SCons/Tool/hpcc.py2
-rw-r--r--src/engine/SCons/Tool/hplink.py2
-rw-r--r--src/engine/SCons/Tool/icc.py2
-rw-r--r--src/engine/SCons/Tool/icl.py6
-rw-r--r--src/engine/SCons/Tool/ifl.py6
-rw-r--r--src/engine/SCons/Tool/ifort.py10
-rw-r--r--src/engine/SCons/Tool/ilink.py2
-rw-r--r--src/engine/SCons/Tool/ilink32.py2
-rw-r--r--src/engine/SCons/Tool/install.py16
-rw-r--r--src/engine/SCons/Tool/intelc.py42
-rw-r--r--src/engine/SCons/Tool/ipkg.py10
-rw-r--r--src/engine/SCons/Tool/jar.py2
-rw-r--r--src/engine/SCons/Tool/javac.py36
-rw-r--r--src/engine/SCons/Tool/javah.py7
-rw-r--r--src/engine/SCons/Tool/latex.py4
-rw-r--r--src/engine/SCons/Tool/lex.py6
-rw-r--r--src/engine/SCons/Tool/link.py2
-rw-r--r--src/engine/SCons/Tool/linkloc.py4
-rw-r--r--src/engine/SCons/Tool/m4.py2
-rw-r--r--src/engine/SCons/Tool/masm.py2
-rw-r--r--src/engine/SCons/Tool/midl.py8
-rw-r--r--src/engine/SCons/Tool/mingw.py5
-rw-r--r--src/engine/SCons/Tool/mslib.py2
-rw-r--r--src/engine/SCons/Tool/mslink.py14
-rw-r--r--src/engine/SCons/Tool/mssdk.py2
-rw-r--r--src/engine/SCons/Tool/msvc.py17
-rw-r--r--src/engine/SCons/Tool/msvs.py233
-rw-r--r--src/engine/SCons/Tool/msvsTests.py54
-rw-r--r--src/engine/SCons/Tool/mwcc.py11
-rw-r--r--src/engine/SCons/Tool/mwld.py4
-rw-r--r--src/engine/SCons/Tool/nasm.py2
-rw-r--r--src/engine/SCons/Tool/packaging/__init__.py32
-rw-r--r--src/engine/SCons/Tool/packaging/ipk.py12
-rw-r--r--src/engine/SCons/Tool/packaging/msi.py27
-rw-r--r--src/engine/SCons/Tool/packaging/rpm.py48
-rw-r--r--src/engine/SCons/Tool/packaging/src_tarbz2.py2
-rw-r--r--src/engine/SCons/Tool/packaging/src_targz.py2
-rw-r--r--src/engine/SCons/Tool/packaging/src_zip.py2
-rw-r--r--src/engine/SCons/Tool/packaging/tarbz2.py2
-rw-r--r--src/engine/SCons/Tool/packaging/targz.py2
-rw-r--r--src/engine/SCons/Tool/packaging/zip.py2
-rw-r--r--src/engine/SCons/Tool/pdf.py2
-rw-r--r--src/engine/SCons/Tool/pdflatex.py4
-rw-r--r--src/engine/SCons/Tool/pdftex.py6
-rw-r--r--src/engine/SCons/Tool/qt.py4
-rw-r--r--src/engine/SCons/Tool/rmic.py5
-rw-r--r--src/engine/SCons/Tool/rpcgen.py2
-rw-r--r--src/engine/SCons/Tool/rpm.py2
-rw-r--r--src/engine/SCons/Tool/sgiar.py2
-rw-r--r--src/engine/SCons/Tool/sgic++.py2
-rw-r--r--src/engine/SCons/Tool/sgicc.py2
-rw-r--r--src/engine/SCons/Tool/sgilink.py2
-rw-r--r--src/engine/SCons/Tool/sunar.py2
-rw-r--r--src/engine/SCons/Tool/sunc++.py2
-rw-r--r--src/engine/SCons/Tool/suncc.py2
-rw-r--r--src/engine/SCons/Tool/sunf77.py2
-rw-r--r--src/engine/SCons/Tool/sunf90.py2
-rw-r--r--src/engine/SCons/Tool/sunf95.py2
-rw-r--r--src/engine/SCons/Tool/sunlink.py2
-rw-r--r--src/engine/SCons/Tool/swig.py20
-rw-r--r--src/engine/SCons/Tool/tar.py2
-rw-r--r--src/engine/SCons/Tool/tex.py38
-rw-r--r--src/engine/SCons/Tool/textfile.py6
-rw-r--r--src/engine/SCons/Tool/tlib.py2
-rw-r--r--src/engine/SCons/Tool/wix.py5
-rw-r--r--src/engine/SCons/Tool/yacc.py5
-rw-r--r--src/engine/SCons/Tool/zip.py13
-rw-r--r--src/engine/SCons/Tool/zip.xml5
-rw-r--r--src/engine/SCons/Util.py669
-rw-r--r--src/engine/SCons/UtilTests.py136
-rw-r--r--src/engine/SCons/Variables/BoolVariable.py6
-rw-r--r--src/engine/SCons/Variables/BoolVariableTests.py2
-rw-r--r--src/engine/SCons/Variables/EnumVariable.py22
-rw-r--r--src/engine/SCons/Variables/EnumVariableTests.py2
-rw-r--r--src/engine/SCons/Variables/ListVariable.py34
-rw-r--r--src/engine/SCons/Variables/ListVariableTests.py2
-rw-r--r--src/engine/SCons/Variables/PackageVariable.py13
-rw-r--r--src/engine/SCons/Variables/PackageVariableTests.py2
-rw-r--r--src/engine/SCons/Variables/PathVariable.py4
-rw-r--r--src/engine/SCons/Variables/PathVariableTests.py20
-rw-r--r--src/engine/SCons/Variables/VariablesTests.py26
-rw-r--r--src/engine/SCons/Variables/__init__.py53
-rw-r--r--src/engine/SCons/Warnings.py98
-rw-r--r--src/engine/SCons/WarningsTests.py14
-rw-r--r--src/engine/SCons/__init__.py12
-rw-r--r--src/engine/SCons/compat/__init__.py271
-rw-r--r--src/engine/SCons/compat/_scons_UserString.py98
-rw-r--r--src/engine/SCons/compat/_scons_builtins.py (renamed from src/engine/SCons/compat/builtins.py)123
-rw-r--r--src/engine/SCons/compat/_scons_collections.py45
-rw-r--r--src/engine/SCons/compat/_scons_dbm.py45
-rw-r--r--src/engine/SCons/compat/_scons_hashlib.py27
-rw-r--r--src/engine/SCons/compat/_scons_io.py45
-rw-r--r--src/engine/SCons/compat/_scons_itertools.py124
-rw-r--r--src/engine/SCons/compat/_scons_optparse.py1725
-rw-r--r--src/engine/SCons/compat/_scons_platform.py237
-rw-r--r--src/engine/SCons/compat/_scons_sets.py56
-rw-r--r--src/engine/SCons/compat/_scons_sets15.py176
-rw-r--r--src/engine/SCons/compat/_scons_shlex.py325
-rw-r--r--src/engine/SCons/compat/_scons_subprocess.py55
-rw-r--r--src/engine/SCons/compat/_scons_textwrap.py382
-rw-r--r--src/engine/SCons/cpp.py55
-rw-r--r--src/engine/SCons/cppTests.py11
-rw-r--r--src/engine/SCons/dblite.py57
-rw-r--r--src/engine/SCons/exitfuncs.py4
-rw-r--r--src/engine/setup.py6
-rw-r--r--src/script/README.txt4
-rw-r--r--src/script/scons-post-install.py25
-rw-r--r--src/script/scons-time.py105
-rw-r--r--src/script/scons.bat6
-rw-r--r--src/script/scons.py25
-rw-r--r--src/script/sconsign.py68
-rw-r--r--src/script/setup.py4
-rw-r--r--src/setup.py18
-rw-r--r--src/test_aegistests.py12
-rw-r--r--src/test_files.py9
-rw-r--r--src/test_interrupts.py14
-rw-r--r--src/test_pychecker.py28
-rw-r--r--src/test_setup.py27
-rw-r--r--src/test_strings.py58
324 files changed, 6002 insertions, 9408 deletions
diff --git a/SConstruct b/SConstruct
index 12abc80..ea87a09 100644
--- a/SConstruct
+++ b/SConstruct
@@ -2,14 +2,13 @@
# SConstruct file to build scons packages during development.
#
# See the README file for an overview of how SCons is built and tested.
-#
# 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.
copyright_years = '2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010'
# This gets inserted into the man pages to reflect the month of release.
-month_year = 'March 2010'
+month_year = 'June 2010'
#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
@@ -40,12 +39,11 @@ import os
import os.path
import re
import stat
-import string
import sys
import tempfile
project = 'scons'
-default_version = '1.3.0'
+default_version = '2.0.0.final.0'
copyright = "Copyright (c) %s The SCons Foundation" % copyright_years
platform = distutils.util.get_platform()
@@ -60,7 +58,7 @@ def whereis(file):
exts = ['']
if platform == "win32":
exts += ['.exe']
- for dir in string.split(os.environ['PATH'], os.pathsep):
+ for dir in os.environ['PATH'].split(os.pathsep):
f = os.path.join(dir, file)
for ext in exts:
f_ext = f + ext
@@ -106,7 +104,7 @@ if not developer:
build_system = ARGUMENTS.get('BUILD_SYSTEM')
if not build_system:
import socket
- build_system = string.split(socket.gethostname(), '.')[0]
+ build_system = socket.gethostname().split('.')[0]
version = ARGUMENTS.get('VERSION', '')
if not version:
@@ -137,7 +135,7 @@ if not revision and hg:
revision = b.group(1) + ':' + revision
def generate_build_id(revision):
result = revision
- if filter(lambda l: l[0] in 'AMR!', hg_status_lines):
+ if [l for l in hg_status_lines if l[0] in 'AMR!']:
result = result + '[MODIFIED]'
return result
@@ -148,7 +146,7 @@ if not revision and svn:
revision = m.group(1)
def generate_build_id(revision):
result = 'r' + revision
- if filter(lambda l: l[0] in 'ACDMR', svn_status_lines):
+ if [l for l in svn_status_lines if l[0] in 'ACDMR']:
result = result + '[MODIFIED]'
return result
@@ -156,10 +154,10 @@ checkpoint = ARGUMENTS.get('CHECKPOINT', '')
if checkpoint:
if checkpoint == 'd':
import time
- checkpoint = time.strftime('d%Y%m%d', time.localtime(time.time()))
+ checkpoint = time.strftime('%Y%m%d', time.localtime(time.time()))
elif checkpoint == 'r':
checkpoint = 'r' + revision
- version = version + '.' + checkpoint
+ version = version + '.beta.' + checkpoint
build_id = ARGUMENTS.get('BUILD_ID')
if build_id is None:
@@ -175,7 +173,7 @@ python_ver = sys.version[0:3]
ENV = { 'PATH' : os.environ['PATH'] }
for key in ['LOGNAME', 'PYTHONPATH', 'LD_LIBRARY_PATH']:
- if os.environ.has_key(key):
+ if key in os.environ:
ENV[key] = os.environ[key]
build_dir = ARGUMENTS.get('BUILDDIR', 'build')
@@ -280,8 +278,7 @@ runtest.py -p option to run tests against what's been actually packaged:
""")
-aliases = packaging_flavors + [('doc', 'The SCons documentation.')]
-aliases.sort()
+aliases = sorted(packaging_flavors + [('doc', 'The SCons documentation.')])
for alias, help_text in aliases:
tw = textwrap.TextWrapper(
@@ -365,16 +362,16 @@ def SCons_revision(target, source, env):
# Note: We construct the __*__ substitution strings here
# so that they don't get replaced when this file gets
# copied into the tree for packaging.
- contents = string.replace(contents, '__BUILD' + '__', env['BUILD'])
- contents = string.replace(contents, '__BUILDSYS' + '__', env['BUILDSYS'])
- contents = string.replace(contents, '__COPYRIGHT' + '__', env['COPYRIGHT'])
- contents = string.replace(contents, '__DATE' + '__', env['DATE'])
- contents = string.replace(contents, '__DEVELOPER' + '__', env['DEVELOPER'])
- contents = string.replace(contents, '__FILE' + '__', str(source[0]))
- contents = string.replace(contents, '__MONTH_YEAR'+ '__', env['MONTH_YEAR'])
- contents = string.replace(contents, '__REVISION' + '__', env['REVISION'])
- contents = string.replace(contents, '__VERSION' + '__', env['VERSION'])
- contents = string.replace(contents, '__NULL' + '__', '')
+ contents = contents.replace('__BUILD' + '__', env['BUILD'])
+ contents = contents.replace('__BUILDSYS' + '__', env['BUILDSYS'])
+ contents = contents.replace('__COPYRIGHT' + '__', env['COPYRIGHT'])
+ contents = contents.replace('__DATE' + '__', env['DATE'])
+ contents = contents.replace('__DEVELOPER' + '__', env['DEVELOPER'])
+ contents = contents.replace('__FILE' + '__', str(source[0]))
+ contents = contents.replace('__MONTH_YEAR'+ '__', env['MONTH_YEAR'])
+ contents = contents.replace('__REVISION' + '__', env['REVISION'])
+ contents = contents.replace('__VERSION' + '__', env['VERSION'])
+ contents = contents.replace('__NULL' + '__', '')
open(t, 'wb').write(contents)
os.chmod(t, os.stat(s)[0])
@@ -708,7 +705,7 @@ for p in [ scons ]:
pkg_version = "%s-%s" % (pkg, version)
src = 'src'
- if p.has_key('src_subdir'):
+ if 'src_subdir' in p:
src = os.path.join(src, p['src_subdir'])
build = os.path.join(build_dir, pkg)
@@ -747,15 +744,14 @@ for p in [ scons ]:
# destination files.
#
manifest_in = File(os.path.join(src, 'MANIFEST.in')).rstr()
- src_files = map(lambda x: x[:-1],
- open(manifest_in).readlines())
+ src_files = [x[:-1] for x in open(manifest_in).readlines()]
raw_files = src_files[:]
dst_files = src_files[:]
rpm_files = []
MANIFEST_in_list = []
- if p.has_key('subpkgs'):
+ if 'subpkgs' in p:
#
# This package includes some sub-packages. Read up their
# MANIFEST.in files, and add them to our source and destination
@@ -767,9 +763,9 @@ for p in [ scons ]:
isubdir = p['subinst_dirs'][sp['pkg']]
MANIFEST_in = File(os.path.join(src, ssubdir, 'MANIFEST.in')).rstr()
MANIFEST_in_list.append(MANIFEST_in)
- files = map(lambda x: x[:-1], open(MANIFEST_in).readlines())
+ files = [x[:-1] for x in open(MANIFEST_in).readlines()]
raw_files.extend(files)
- src_files.extend(map(lambda x, s=ssubdir: os.path.join(s, x), files))
+ src_files.extend([os.path.join(ssubdir, x) for x in files])
for f in files:
r = os.path.join(sp['rpm_dir'], f)
rpm_files.append(r)
@@ -778,7 +774,7 @@ for p in [ scons ]:
for f in sp.get('extra_rpm_files', []):
r = os.path.join(sp['rpm_dir'], f)
rpm_files.append(r)
- files = map(lambda x, i=isubdir: os.path.join(i, x), files)
+ files = [os.path.join(isubdir, x) for x in files]
dst_files.extend(files)
for k, f in sp['filemap'].items():
if f:
@@ -798,7 +794,7 @@ for p in [ scons ]:
#
# Now run everything in src_file through the sed command we
- # concocted to expand SConstruct, 1.3.0, etc.
+ # concocted to expand SConstruct, 2.0.0.final.0, etc.
#
for b in src_files:
s = p['filemap'].get(b, b)
@@ -832,8 +828,8 @@ for p in [ scons ]:
#
# Now go through and arrange to create whatever packages we can.
#
- build_src_files = map(lambda x, b=build: os.path.join(b, x), src_files)
- apply(Local, build_src_files, {})
+ build_src_files = [os.path.join(build, x) for x in src_files]
+ Local(*build_src_files)
distutils_formats = []
@@ -870,9 +866,8 @@ for p in [ scons ]:
# but that gives heartburn to Cygwin's tar, so work around it
# with separate zcat-tar-rm commands.
#
- unpack_tar_gz_files = map(lambda x, u=unpack_tar_gz_dir, pv=pkg_version:
- os.path.join(u, pv, x),
- src_files)
+ unpack_tar_gz_files = [os.path.join(unpack_tar_gz_dir, pkg_version, x)
+ for x in src_files]
env.Command(unpack_tar_gz_files, dist_tar_gz, [
Delete(os.path.join(unpack_tar_gz_dir, pkg_version)),
"$ZCAT $SOURCES > .temp",
@@ -884,8 +879,8 @@ for p in [ scons ]:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under etc (for the testing modules TestCmd.py, TestSCons.py,
- # and unittest.py). This makes sure that our tests pass with what
+ # and under QMTest (for the testing modules TestCmd.py, TestSCons.py,
+ # etc.). This makes sure that our tests pass with what
# we really packaged, not because of something hanging around in
# the development directory.
#
@@ -893,7 +888,7 @@ for p in [ scons ]:
# like this because we put a preamble in it that will chdir()
# to the directory in which setup.py exists.
#
- dfiles = map(lambda x, d=test_tar_gz_dir: os.path.join(d, x), dst_files)
+ dfiles = [os.path.join(test_tar_gz_dir, x) for x in dst_files]
env.Command(dfiles, unpack_tar_gz_files, [
Delete(os.path.join(unpack_tar_gz_dir, pkg_version, 'build')),
Delete("$TEST_TAR_GZ_DIR"),
@@ -910,21 +905,9 @@ for p in [ scons ]:
env.Command(ebuild, os.path.join('gentoo', 'scons.ebuild.in'), SCons_revision)
def Digestify(target, source, env):
import md5
- def hexdigest(s):
- """Return a signature as a string of hex characters.
- """
- # NOTE: This routine is a method in the Python 2.0 interface
- # of the native md5 module, but we want SCons to operate all
- # the way back to at least Python 1.5.2, which doesn't have it.
- h = string.hexdigits
- r = ''
- for c in s:
- i = ord(c)
- r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
- return r
src = source[0].rfile()
contents = open(str(src)).read()
- sig = hexdigest(md5.new(contents).digest())
+ sig = md5.new(contents).hexdigest()
bytes = os.stat(str(src))[6]
open(str(target[0]), 'w').write("MD5 %s %s %d\n" % (sig,
src.name,
@@ -951,9 +934,8 @@ for p in [ scons ]:
# Unpack the zip archive created by the distutils into
# build/unpack-zip/scons-{version}.
#
- unpack_zip_files = map(lambda x, u=unpack_zip_dir, pv=pkg_version:
- os.path.join(u, pv, x),
- src_files)
+ unpack_zip_files = [os.path.join(unpack_zip_dir, pkg_version, x)
+ for x in src_files]
env.Command(unpack_zip_files, dist_zip, [
Delete(os.path.join(unpack_zip_dir, pkg_version)),
@@ -964,8 +946,8 @@ for p in [ scons ]:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under etc (for the testing modules TestCmd.py, TestSCons.py,
- # and unittest.py). This makes sure that our tests pass with what
+ # and under QMTest (for the testing modules TestCmd.py, TestSCons.py,
+ # etc.). This makes sure that our tests pass with what
# we really packaged, not because of something hanging around in
# the development directory.
#
@@ -973,7 +955,7 @@ for p in [ scons ]:
# like this because we put a preamble in it that will chdir()
# to the directory in which setup.py exists.
#
- dfiles = map(lambda x, d=test_zip_dir: os.path.join(d, x), dst_files)
+ dfiles = [os.path.join(test_zip_dir, x) for x in dst_files]
env.Command(dfiles, unpack_zip_files, [
Delete(os.path.join(unpack_zip_dir, pkg_version, 'build')),
Delete("$TEST_ZIP_DIR"),
@@ -1010,12 +992,12 @@ for p in [ scons ]:
maintain multiple lists.
"""
c = open(str(source[0]), 'rb').read()
- c = string.replace(c, '__VERSION' + '__', env['VERSION'])
- c = string.replace(c, '__RPM_FILES' + '__', env['RPM_FILES'])
+ c = c.replace('__VERSION' + '__', env['VERSION'])
+ c = c.replace('__RPM_FILES' + '__', env['RPM_FILES'])
open(str(target[0]), 'wb').write(c)
rpm_files.sort()
- rpm_files_str = string.join(rpm_files, "\n") + "\n"
+ rpm_files_str = "\n".join(rpm_files) + "\n"
rpm_spec_env = env.Clone(RPM_FILES = rpm_files_str)
rpm_spec_action = Action(spec_function, varlist=['RPM_FILES'])
rpm_spec_env.Command(specfile, specfile_in, rpm_spec_action)
@@ -1036,8 +1018,7 @@ for p in [ scons ]:
AddPostAction(dist_noarch_rpm, Chmod(dist_noarch_rpm, 0644))
AddPostAction(dist_src_rpm, Chmod(dist_src_rpm, 0644))
- dfiles = map(lambda x, d=test_rpm_dir: os.path.join(d, 'usr', x),
- dst_files)
+ dfiles = [os.path.join(test_rpm_dir, 'usr', x) for x in dst_files]
env.Command(dfiles,
dist_noarch_rpm,
"$RPM2CPIO $SOURCES | (cd $TEST_RPM_DIR && cpio -id)")
@@ -1060,8 +1041,7 @@ for p in [ scons ]:
if s[:len(old)] == old:
s = new + s[len(old):]
return os.path.join('usr', s)
- dfiles = map(lambda x, t=test_deb_dir: os.path.join(t, x),
- map(xxx, dst_files))
+ dfiles = [os.path.join(test_deb_dir, xxx(x)) for x in dst_files]
env.Command(dfiles,
deb,
"dpkg --fsys-tarfile $SOURCES | (cd $TEST_DEB_DIR && tar -xf -)")
@@ -1084,7 +1064,7 @@ for p in [ scons ]:
commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_dumb -f %s" % format)
commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY sdist --formats=%s" % \
- string.join(distutils_formats, ','))
+ ','.join(distutils_formats))
commands.append("$PYTHON $PYTHONFLAGS $SETUP_PY bdist_wininst")
@@ -1117,11 +1097,11 @@ for p in [ scons ]:
local_script = os.path.join(build_dir_local, script)
commands.append(Move(local_script + '.py', local_script))
- rf = filter(lambda x: not x in scripts, raw_files)
- rf = map(lambda x, slv=s_l_v: os.path.join(slv, x), rf)
+ rf = [x for x in raw_files if not x in scripts]
+ rf = [os.path.join(s_l_v, x) for x in rf]
for script in scripts:
rf.append("%s.py" % script)
- local_targets = map(lambda x, s=build_dir_local: os.path.join(s, x), rf)
+ local_targets = [os.path.join(build_dir_local, x) for x in rf]
env.Command(local_targets, build_src_files, commands)
@@ -1140,9 +1120,7 @@ for p in [ scons ]:
local_targets,
"cd %s && tar czf $( ${TARGET.abspath} $) *" % build_dir_local)
- unpack_targets = map(lambda x, d=test_local_tar_gz_dir:
- os.path.join(d, x),
- rf)
+ unpack_targets = [os.path.join(test_local_tar_gz_dir, x) for x in rf]
commands = [Delete(test_local_tar_gz_dir),
Mkdir(test_local_tar_gz_dir),
"cd %s && tar xzf $( ${SOURCE.abspath} $)" % test_local_tar_gz_dir]
@@ -1153,9 +1131,7 @@ for p in [ scons ]:
env.Command(dist_local_zip, local_targets, zipit,
CD = build_dir_local, PSV = '.')
- unpack_targets = map(lambda x, d=test_local_zip_dir:
- os.path.join(d, x),
- rf)
+ unpack_targets = [os.path.join(test_local_zip_dir, x) for x in rf]
commands = [Delete(test_local_zip_dir),
Mkdir(test_local_zip_dir),
unzipit]
@@ -1208,12 +1184,12 @@ SConscript('doc/SConscript')
sfiles = None
if hg_status_lines:
- slines = filter(lambda l: l[0] in 'ACM', hg_status_lines)
- sfiles = map(lambda l: l.split()[-1], slines)
+ slines = [l for l in hg_status_lines if l[0] in 'ACM']
+ sfiles = [l.split()[-1] for l in slines]
elif svn_status_lines:
- slines = filter(lambda l: l[0] in ' MA', svn_status_lines)
- sentries = map(lambda l: l.split()[-1], slines)
- sfiles = filter(os.path.isfile, sentries)
+ slines = [l for l in svn_status_lines if l[0] in ' MA']
+ sentries = [l.split()[-1] for l in slines]
+ sfiles = list(filter(os.path.isfile, sentries))
else:
"Not building in a Mercurial or Subversion tree; skipping building src package."
@@ -1228,7 +1204,7 @@ if sfiles:
]
for p in remove_patterns:
- sfiles = filter(lambda s, p=p: not fnmatch.fnmatch(s, p), sfiles)
+ sfiles = [s for s in sfiles if not fnmatch.fnmatch(s, p)]
if sfiles:
ps = "%s-src" % project
@@ -1245,7 +1221,7 @@ if sfiles:
for file in sfiles:
env.SCons_revision(os.path.join(b_ps, file), file)
- b_ps_files = map(lambda x, d=b_ps: os.path.join(d, x), sfiles)
+ b_ps_files = [os.path.join(b_ps, x) for x in sfiles]
cmds = [
Delete(b_psv),
Copy(b_psv, b_ps),
@@ -1254,7 +1230,7 @@ if sfiles:
env.Command(b_psv_stamp, src_deps + b_ps_files, cmds)
- apply(Local, b_ps_files, {})
+ Local(*b_ps_files)
if gzip:
@@ -1264,9 +1240,8 @@ if sfiles:
#
# Unpack the archive into build/unpack/scons-{version}.
#
- unpack_tar_gz_files = map(lambda x, u=unpack_tar_gz_dir, psv=psv:
- os.path.join(u, psv, x),
- sfiles)
+ unpack_tar_gz_files = [os.path.join(unpack_tar_gz_dir, psv, x)
+ for x in sfiles]
#
# We'd like to replace the last three lines with the following:
@@ -1286,17 +1261,16 @@ if sfiles:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under etc (for the testing modules TestCmd.py, TestSCons.py,
- # and unittest.py). This makes sure that our tests pass with what
- # we really packaged, not because of something hanging around in
- # the development directory.
+ # and under QMTest (for the testing modules TestCmd.py,
+ # TestSCons.py, etc.). This makes sure that our tests pass with
+ # what we really packaged, not because of something hanging around
+ # in the development directory.
#
# We can get away with calling setup.py using a directory path
# like this because we put a preamble in it that will chdir()
# to the directory in which setup.py exists.
#
- dfiles = map(lambda x, d=test_src_tar_gz_dir: os.path.join(d, x),
- dst_files)
+ dfiles = [os.path.join(test_src_tar_gz_dir, x) for x in dst_files]
scons_lib_dir = os.path.join(unpack_tar_gz_dir, psv, 'src', 'engine')
ENV = env.Dictionary('ENV').copy()
ENV['SCONS_LIB_DIR'] = scons_lib_dir
@@ -1329,9 +1303,8 @@ if sfiles:
#
# Unpack the archive into build/unpack/scons-{version}.
#
- unpack_zip_files = map(lambda x, u=unpack_zip_dir, psv=psv:
- os.path.join(u, psv, x),
- sfiles)
+ unpack_zip_files = [os.path.join(unpack_zip_dir, psv, x)
+ for x in sfiles]
env.Command(unpack_zip_files, src_zip, [
Delete(os.path.join(unpack_zip_dir, psv)),
@@ -1342,17 +1315,16 @@ if sfiles:
# Run setup.py in the unpacked subdirectory to "install" everything
# into our build/test subdirectory. The runtest.py script will set
# PYTHONPATH so that the tests only look under build/test-{package},
- # and under etc (for the testing modules TestCmd.py, TestSCons.py,
- # and unittest.py). This makes sure that our tests pass with what
- # we really packaged, not because of something hanging around in
- # the development directory.
+ # and under QMTest (for the testing modules TestCmd.py,
+ # TestSCons.py, etc.). This makes sure that our tests pass with
+ # what we really packaged, not because of something hanging
+ # around in the development directory.
#
# We can get away with calling setup.py using a directory path
# like this because we put a preamble in it that will chdir()
# to the directory in which setup.py exists.
#
- dfiles = map(lambda x, d=test_src_zip_dir: os.path.join(d, x),
- dst_files)
+ dfiles = [os.path.join(test_src_zip_dir, x) for x in dst_files]
scons_lib_dir = os.path.join(unpack_zip_dir, psv, 'src', 'engine')
ENV = env.Dictionary('ENV').copy()
ENV['SCONS_LIB_DIR'] = scons_lib_dir
diff --git a/bin/Command.py b/bin/Command.py
index efaa356..8702f51 100644
--- a/bin/Command.py
+++ b/bin/Command.py
@@ -14,7 +14,7 @@ class Usage(Exception):
def __init__(self, msg):
self.msg = msg
-class CommandRunner:
+class CommandRunner(object):
"""
Representation of a command to be executed.
"""
@@ -44,7 +44,7 @@ class CommandRunner:
return string
def do_display(self, string):
- if type(string) == type(()):
+ if isinstance(string, tuple):
func = string[0]
args = string[1:]
s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
@@ -59,14 +59,14 @@ class CommandRunner:
pass
def do_execute(self, command):
- if type(command) == type(''):
+ if isinstance(command, str):
command = self.subst(command)
cmdargs = shlex.split(command)
if cmdargs[0] == 'cd':
command = (os.chdir,) + tuple(cmdargs[1:])
elif cmdargs[0] == 'mkdir':
command = (os.mkdir,) + tuple(cmdargs[1:])
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
return func(*args)
diff --git a/bin/SConsDoc.py b/bin/SConsDoc.py
index 3f64a25..4927dc0 100644
--- a/bin/SConsDoc.py
+++ b/bin/SConsDoc.py
@@ -146,7 +146,7 @@ class Tool(Item):
class ConstructionVariable(Item):
pass
-class Chunk:
+class Chunk(object):
def __init__(self, tag, body=None):
self.tag = tag
if not body:
@@ -158,7 +158,7 @@ class Chunk:
def append(self, data):
self.body.append(data)
-class Arguments:
+class Arguments(object):
def __init__(self, signature, body=None):
if not body:
body = []
@@ -175,7 +175,7 @@ class Arguments:
def append(self, data):
self.body.append(data)
-class Summary:
+class Summary(object):
def __init__(self):
self.body = []
self.collect = []
@@ -217,9 +217,9 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
def __init__(self):
self._start_dispatch = {}
self._end_dispatch = {}
- keys = self.__class__.__dict__.keys()
- start_tag_method_names = filter(lambda k: k[:6] == 'start_', keys)
- end_tag_method_names = filter(lambda k: k[:4] == 'end_', keys)
+ keys = list(self.__class__.__dict__.keys())
+ start_tag_method_names = [k for k in keys if k[:6] == 'start_']
+ end_tag_method_names = [k for k in keys if k[:4] == 'end_']
for method_name in start_tag_method_names:
tag = method_name[6:]
self._start_dispatch[tag] = getattr(self, method_name)
@@ -353,15 +353,13 @@ class SConsDocHandler(xml.sax.handler.ContentHandler,
def start_uses(self, attrs):
self.begin_collecting([])
def end_uses(self):
- self.current_object.uses = ''.join(self.collect).split()
- self.current_object.uses.sort()
+ self.current_object.uses = sorted(''.join(self.collect).split())
self.end_collecting()
def start_sets(self, attrs):
self.begin_collecting([])
def end_sets(self):
- self.current_object.sets = ''.join(self.collect).split()
- self.current_object.sets.sort()
+ self.current_object.sets = sorted(''.join(self.collect).split())
self.end_collecting()
# Stuff for the ErrorHandler portion.
diff --git a/bin/calibrate.py b/bin/calibrate.py
index c5d45ce..f377869 100644
--- a/bin/calibrate.py
+++ b/bin/calibrate.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 division
import optparse
import os
@@ -71,7 +72,7 @@ def main(argv=None):
good = 0
for v in vm.groups():
var, value = v.split('=', 1)
- value = int((int(value) * opts.max) / elapsed)
+ value = int((int(value) * opts.max) // elapsed)
os.environ[var] = str(value)
run += 1
diff --git a/bin/caller-tree.py b/bin/caller-tree.py
index 85bb599..03c1616 100644
--- a/bin/caller-tree.py
+++ b/bin/caller-tree.py
@@ -42,7 +42,7 @@
import sys
-class Entry:
+class Entry(object):
def __init__(self, file_line_func):
self.file_line_func = file_line_func
self.called_by = []
diff --git a/bin/import-test.py b/bin/import-test.py
index 18f7428..906bab0 100644
--- a/bin/import-test.py
+++ b/bin/import-test.py
@@ -25,7 +25,7 @@
# """ triple-quotes will need to have their contents edited by hand.
#
-__revision__ = "bin/import-test.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "bin/import-test.py 5023 2010/06/14 22:05:46 scons"
import os.path
import sys
@@ -35,16 +35,13 @@ directory = sys.argv[1]
Top = None
TopPath = None
-class Dir:
+class Dir(object):
def __init__(self, path):
self.path = path
self.entries = {}
def call_for_each_entry(self, func):
- entries = self.entries
- names = entries.keys()
- names.sort()
- for name in names:
- func(name, entries[name])
+ for name in sorted(self.entries.keys()):
+ func(name, self.entries[name])
def lookup(dirname):
global Top, TopPath
@@ -60,11 +57,6 @@ def lookup(dirname):
node = t.entries[dirs[-1]] = Dir(dirs)
return node
-def make_nodes(arg, dirname, fnames):
- dir = lookup(dirname)
- for f in fnames:
- dir.entries[f] = None
-
def collect_dirs(l, dir):
if dir.path:
l.append(dir.path)
@@ -78,7 +70,7 @@ def print_files(dir):
if not d:
l = dir.path + [n]
sys.stdout.write('\ntest.write(%s, """\\\n' % l)
- p = os.path.join(*([directory] + l))
+ p = os.path.join(directory, *l)
sys.stdout.write(open(p, 'r').read())
sys.stdout.write('""")\n')
dir.call_for_each_entry(print_a_file)
@@ -88,7 +80,10 @@ def print_files(dir):
print_files(d)
dir.call_for_each_entry(recurse)
-os.path.walk(directory, make_nodes, None)
+for dirpath, dirnames, filenames in os.walk(directory):
+ dir = lookup(dirpath)
+ for f in fnames:
+ dir.entries[f] = None
subdir_list = []
collect_dirs(subdir_list, Top)
diff --git a/bin/install_python.py b/bin/install_python.py
index ca1c8b7..86807af 100644
--- a/bin/install_python.py
+++ b/bin/install_python.py
@@ -15,10 +15,6 @@ import sys
from Command import CommandRunner, Usage
all_versions = [
- #'1.5.2', # no longer available at python.org
- '2.0.1',
- '2.1.3',
- '2.2',
'2.3.7',
'2.4.5',
#'2.5.2',
@@ -89,16 +85,6 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...]
tar_gz = os.path.join(downloads_dir, python + '.tgz')
tar_gz_url = os.path.join(downloads_url, version, python + '.tgz')
- if (version.startswith('1.5') or
- version.startswith('1.6') or
- version.startswith('2.0')):
-
- configureflags = '--with-threads'
-
- else:
-
- configureflags = ''
-
cmd.subst_dictionary(locals())
if not os.path.exists(tar_gz):
@@ -110,17 +96,6 @@ Usage: install_python.py [-ahnq] [-d DIR] [-p PREFIX] [VERSION ...]
cmd.run('cd %(python)s')
- if (version.startswith('1.6') or
- version.startswith('2.0')):
-
- def edit_modules_setup_in():
- content = open('Modules/Setup.in', 'r').read()
- content = content.replace('\n#zlib', '\nzlib')
- open('Modules/Setup.in', 'w').write(content)
-
- display = 'ed Modules/Setup.in <<EOF\ns/^#zlib/zlib/\nw\nq\nEOF\n'
- cmd.run((edit_modules_setup_in,), display)
-
cmd.run('./configure --prefix=%(prefix)s %(configureflags)s 2>&1 | tee configure.out')
cmd.run('make 2>&1 | tee make.out')
cmd.run('%(sudo)s make install')
diff --git a/bin/install_scons.py b/bin/install_scons.py
index e4e6aff..b5e0af8 100644
--- a/bin/install_scons.py
+++ b/bin/install_scons.py
@@ -79,6 +79,15 @@ all_versions = [
'1.2.0',
'1.2.0.d20090113',
'1.2.0.d20090223',
+ '1.2.0.d20090905',
+ '1.2.0.d20090919',
+ '1.2.0.d20091224',
+ '1.2.0.d20100117',
+ '1.2.0.d20100306',
+ '1.3.0',
+ '1.3.0.d20100404',
+ '1.3.0.d20100501',
+ '2.0.0.alpha.20100508',
]
def main(argv=None):
diff --git a/bin/linecount.py b/bin/linecount.py
index 23ac7c9..7d6e457 100644
--- a/bin/linecount.py
+++ b/bin/linecount.py
@@ -21,12 +21,11 @@
# 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__ = "bin/linecount.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "bin/linecount.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
fmt = "%-16s %5s %7s %9s %11s %11s"
@@ -43,8 +42,12 @@ class Collection(object):
return self.pred(fname)
def __len__(self):
return len(self.files)
- def extend(self, files):
- self.files.extend(files)
+ def collect(self, directory):
+ for dirpath, dirnames, filenames in os.walk(directory):
+ try: dirnames.remove('.svn')
+ except ValueError: pass
+ self.files.extend([ os.path.join(dirpath, f)
+ for f in filenames if self.pred(f) ])
def lines(self):
try:
return self._lines
@@ -82,17 +85,11 @@ src_test_tests = Collection('src/ test_*.py', pred=is_test_)
test_tests = Collection('test/ tests', pred=is_python)
sources = Collection('sources', pred=is_source)
-def t(arg, dirname, names):
- try: names.remove('.svn')
- except ValueError: pass
- names = filter(arg, names)
- arg.extend(map(lambda n, d=dirname: os.path.join(d, n), names))
-
-os.path.walk('src', t, src_Tests_py_tests)
-os.path.walk('src', t, src_test_tests)
-os.path.walk('test', t, test_tests)
-os.path.walk('src/engine', t, sources)
-os.path.walk('src/script', t, sources)
+src_Tests_py_tests.collect('src')
+src_test_tests.collect('src')
+test_tests.collect('test')
+sources.collect('src/engine')
+sources.collect('src/script')
src_tests = Collection('src/ tests', src_Tests_py_tests.files
+ src_test_tests.files)
diff --git a/bin/memoicmp.py b/bin/memoicmp.py
index f45ecb0..812af66 100644
--- a/bin/memoicmp.py
+++ b/bin/memoicmp.py
@@ -1,21 +1,24 @@
#!/usr/bin/env python
#
-# A script to compare the --debug=memoizer output found int
+# A script to compare the --debug=memoizer output found in
# two different files.
-import sys,string
+import sys
def memoize_output(fname):
- mout = {}
- lines=filter(lambda words:
- len(words) == 5 and
- words[1] == 'hits' and words[3] == 'misses',
- map(string.split, open(fname,'r').readlines()))
- for line in lines:
- mout[line[-1]] = ( int(line[0]), int(line[2]) )
- return mout
+ mout = {}
+ #lines=filter(lambda words:
+ # len(words) == 5 and
+ # words[1] == 'hits' and words[3] == 'misses',
+ # map(string.split, open(fname,'r').readlines()))
+ #for line in lines:
+ # mout[line[-1]] = ( int(line[0]), int(line[2]) )
+ for line in open(fname,'r').readlines():
+ words = line.split()
+ if len(words) == 5 and words[1] == 'hits' and words[3] == 'misses':
+ mout[words[-1]] = ( int(words[0]), int(words[2]) )
+ return mout
-
def memoize_cmp(filea, fileb):
ma = memoize_output(filea)
mb = memoize_output(fileb)
diff --git a/bin/objcounts.py b/bin/objcounts.py
index ca814b4..0662012 100644
--- a/bin/objcounts.py
+++ b/bin/objcounts.py
@@ -40,7 +40,7 @@ def fetch_counts(fname):
list = [l.split() for l in lines if re.match('\s+\d', l)]
d = {}
for l in list:
- d[l[-1]] = map(int, l[:-1])
+ d[l[-1]] = list(map(int, l[:-1]))
return d
c1 = fetch_counts(sys.argv[1])
@@ -86,20 +86,14 @@ def printline(c1, c2, classname):
diffstr(c1[3], c2[3]) + \
' ' + classname
-keys = common.keys()
-keys.sort()
-for k in keys:
+for k in sorted(common.keys()):
c = common[k]
printline(c[0], c[1], k)
-keys = c1.keys()
-keys.sort()
-for k in keys:
+for k in sorted(list(c1.keys())):
printline(c1[k], ['--']*4, k)
-keys = c2.keys()
-keys.sort()
-for k in keys:
+for k in sorted(list(c2.keys())):
printline(['--']*4, c2[k], k)
# Local Variables:
diff --git a/bin/restore.sh b/bin/restore.sh
index 8dce2d3..3fd8d72 100644
--- a/bin/restore.sh
+++ b/bin/restore.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
#
-# Simple hack script to restore __revision__, __COPYRIGHT_, 1.3.0
+# Simple hack script to restore __revision__, __COPYRIGHT_, 2.0.0.final.0
# and other similar variables to what gets checked in to source. This
# comes in handy when people send in diffs based on the released source.
#
@@ -24,7 +24,7 @@ for i in `find $DIRS -name '*.py'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/^__revision__ = /s/= .*/= "bin/restore.sh 4720 2010/03/24 03:14:11 jars"/p
+/^__revision__ = /s/= .*/= "bin/restore.sh 5023 2010/06/14 22:05:46 scons"/p
w
q
EOF
@@ -35,7 +35,7 @@ for i in `find $DIRS -name 'scons.bat'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 4720 2010/03/24 03:14:11 jars/p
+/^@REM src\/script\/scons.bat/s/@REM .* knight/@REM bin/restore.sh 5023 2010/06/14 22:05:46 scons/p
w
q
EOF
@@ -44,15 +44,15 @@ done
for i in `find $DIRS -name '__init__.py' -o -name 'scons.py' -o -name 'sconsign.py'`; do
header $i
ed $i <<EOF
-/^__version__ = /s/= .*/= "1.3.0"/p
+/^__version__ = /s/= .*/= "2.0.0.final.0"/p
w
-/^__build__ = /s/= .*/= "r4720"/p
+/^__build__ = /s/= .*/= "r5023"/p
w
-/^__buildsys__ = /s/= .*/= "jars-desktop"/p
+/^__buildsys__ = /s/= .*/= "scons-dev"/p
w
-/^__date__ = /s/= .*/= "2010/03/24 03:14:11"/p
+/^__date__ = /s/= .*/= "2010/06/14 22:05:46"/p
w
-/^__developer__ = /s/= .*/= "jars"/p
+/^__developer__ = /s/= .*/= "scons"/p
w
q
EOF
@@ -61,7 +61,7 @@ done
for i in `find $DIRS -name 'setup.py'`; do
header $i
ed $i <<EOF
-/^ *version = /s/= .*/= "1.3.0",/p
+/^ *version = /s/= .*/= "2.0.0.final.0",/p
w
q
EOF
@@ -72,9 +72,9 @@ for i in `find $DIRS -name '*.txt'`; do
ed $i <<EOF
g/Copyright (c) 2001.*SCons Foundation/s//Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation/p
w
-/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 4720 2010/03/24 03:14:11 jars/p
+/# [^ ]* 0.96.[CD][0-9]* [0-9\/]* [0-9:]* knight$/s/.*/# bin/restore.sh 5023 2010/06/14 22:05:46 scons/p
w
-/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 1.3.0/p
+/Version [0-9][0-9]*\.[0-9][0-9]*/s//Version 2.0.0.final.0/p
w
q
EOF
diff --git a/bin/scons-diff.py b/bin/scons-diff.py
index 11d1bda..1e4bca0 100644
--- a/bin/scons-diff.py
+++ b/bin/scons-diff.py
@@ -97,15 +97,15 @@ def simple_diff(a, b, fromfile='', tofile='',
for op, a1, a2, b1, b2 in sm.get_opcodes():
if op == 'delete':
result.append("%sd%d\n" % (comma(a1, a2), b1))
- result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.extend(['< ' + l for l in a[a1:a2]])
elif op == 'insert':
result.append("%da%s\n" % (a1, comma(b1, b2)))
- result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ result.extend(['> ' + l for l in b[b1:b2]])
elif op == 'replace':
result.append("%sc%s\n" % (comma(a1, a2), comma(b1, b2)))
- result.extend(map(lambda l: '< ' + l, a[a1:a2]))
+ result.extend(['< ' + l for l in a[a1:a2]])
result.append('---\n')
- result.extend(map(lambda l: '> ' + l, b[b1:b2]))
+ result.extend(['> ' + l for l in b[b1:b2]])
return result
diff_map = {
@@ -173,9 +173,7 @@ def diff_dir(left, right):
u[l] = 1
for r in rlist:
u[r] = 1
- clist = [ x for x in u.keys() if x[-4:] != '.pyc' ]
- clist.sort()
- for x in clist:
+ 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-doc.py b/bin/scons-doc.py
index e385b08..14e862c 100644
--- a/bin/scons-doc.py
+++ b/bin/scons-doc.py
@@ -93,7 +93,6 @@ import optparse
import os
import re
import sgmllib
-import string
import sys
import time
@@ -118,7 +117,7 @@ import TestCmd
sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]')
# Classes for collecting different types of data we're interested in.
-class DataCollector:
+class DataCollector(object):
"""Generic class for collecting data between a start tag and end
tag. We subclass for various types of tags we care about."""
def __init__(self):
@@ -185,7 +184,6 @@ Prompt = {
Stdin = """\
import os
import re
-import string
import SCons.Action
import SCons.Defaults
import SCons.Node.FS
@@ -205,7 +203,7 @@ Sep = {
orig = SCons.Node.FS.EntryProxy
class MyEntryProxy(orig):
def __str__(self):
- return string.replace(str(self._Proxy__subject), os.sep, Sep)
+ return str(self._subject).replace(os.sep, Sep)
SCons.Node.FS.EntryProxy = MyEntryProxy
# Slip our own RDirs() method into the Node.FS.File class so that the
@@ -214,11 +212,10 @@ SCons.Node.FS.EntryProxy = MyEntryProxy
# running on to what's appropriate for the example system.
orig_RDirs = SCons.Node.FS.File.RDirs
def my_RDirs(self, pathlist, orig_RDirs=orig_RDirs):
- return map(lambda x: string.replace(str(x), os.sep, Sep),
- orig_RDirs(self, pathlist))
+ return [str(x).replace(os.sep, Sep) for x in orig_RDirs(self, pathlist)]
SCons.Node.FS.File.RDirs = my_RDirs
-class Curry:
+class Curry(object):
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
@@ -231,18 +228,18 @@ class Curry:
else:
kw = kwargs or self.kwargs
- return apply(self.fun, self.pending + args, kw)
+ return self.fun(*self.pending + args, **kw)
def Str(target, source, env, cmd=""):
result = []
for cmd in env.subst_list(cmd, target=target, source=source):
- result.append(string.join(map(str, cmd)))
- return string.join(result, '\\n')
+ result.append(' '.join(map(str, cmd)))
+ return '\\n'.join(result)
-class ToolSurrogate:
+class ToolSurrogate(object):
def __init__(self, tool, variable, func, varlist):
self.tool = tool
- if not type(variable) is type([]):
+ if not isinstance(variable, list):
variable = [variable]
self.variable = variable
self.func = func
@@ -304,7 +301,7 @@ def JavaCCom(target, source, env):
# public class FooBar
# lines in the source file(s) and spits those out
# to .class files named after the class.
- tlist = map(str, target)
+ tlist = list(map(str, target))
not_copied = {}
for t in tlist:
not_copied[t] = 1
@@ -312,7 +309,7 @@ def JavaCCom(target, source, env):
contents = open(src, "rb").read()
classes = public_class_re.findall(contents)
for c in classes:
- for t in filter(lambda x: string.find(x, c) != -1, tlist):
+ for t in [x for x in tlist if x.find(c) != -1]:
open(t, "wb").write(contents)
del not_copied[t]
for t in not_copied.keys():
@@ -324,16 +321,13 @@ def JavaHCom(target, source, env):
for t, s in zip(tlist, slist):
open(t, "wb").write(open(s, "rb").read())
-def find_class_files(arg, dirname, names):
- class_files = filter(lambda n: n[-6:] == '.class', names)
- paths = map(lambda n, d=dirname: os.path.join(d, n), class_files)
- arg.extend(paths)
-
def JarCom(target, source, env):
target = str(target[0])
class_files = []
for src in map(str, source):
- os.path.walk(src, find_class_files, class_files)
+ for dirpath, dirnames, filenames in os.walk(src):
+ class_files.extend([ os.path.join(dirpath, f)
+ for f in filenames if f.endswith('.class') ])
f = open(target, "wb")
for cf in class_files:
f.write(open(cf, "rb").read())
@@ -380,11 +374,11 @@ ToolList = {
}
toollist = ToolList[platform]
-filter_tools = string.split('%(tools)s')
+filter_tools = '%(tools)s'.split()
if filter_tools:
- toollist = filter(lambda x, ft=filter_tools: x[0] in ft, toollist)
+ toollist = [x for x in toollist if x[0] in filter_tools]
-toollist = map(lambda t: apply(ToolSurrogate, t), toollist)
+toollist = [ToolSurrogate(*t) for t in toollist]
toollist.append('install')
@@ -413,8 +407,8 @@ def command_scons(args, c, test, dict):
except AttributeError:
pass
else:
- for arg in string.split(c.environment):
- key, val = string.split(arg, '=')
+ for arg in c.environment.split():
+ key, val = arg.split('=')
try:
save_vals[key] = os.environ[key]
except KeyError:
@@ -427,17 +421,17 @@ def command_scons(args, c, test, dict):
# warnings that come from the new revamped VS support so
# we can build doc on (Linux) systems that don't have
# Visual C installed.
- arguments = '--warn=no-visual-c-missing -f - ' + string.join(args),
+ arguments = '--warn=no-visual-c-missing -f - ' + ' '.join(args),
chdir = test.workpath('WORK'),
stdin = Stdin % dict)
os.environ.update(save_vals)
for key in delete_keys:
del(os.environ[key])
out = test.stdout()
- out = string.replace(out, test.workpath('ROOT'), '')
- out = string.replace(out, test.workpath('WORK/SConstruct'),
+ out = out.replace(test.workpath('ROOT'), '')
+ out = out.replace(test.workpath('WORK/SConstruct'),
'/home/my/project/SConstruct')
- lines = string.split(out, '\n')
+ lines = out.split('\n')
if lines:
while lines[-1] == '':
lines = lines[:-1]
@@ -478,10 +472,7 @@ def command_edit(args, c, test, dict):
def command_ls(args, c, test, dict):
def ls(a):
- files = os.listdir(a)
- files = filter(lambda x: x[0] != '.', files)
- files.sort()
- return [string.join(files, ' ')]
+ return [' '.join(sorted([x for x in os.listdir(a) if x[0] != '.']))]
if args:
l = []
for a in args:
@@ -509,14 +500,11 @@ def ExecuteCommand(args, c, t, dict):
return func(args[1:], c, t, dict)
class MySGML(sgmllib.SGMLParser):
- """A subclass of the standard Python 2.2 sgmllib SGML parser.
+ """A subclass of the standard Python sgmllib SGML parser.
This extends the standard sgmllib parser to recognize, and do cool
stuff with, the added tags that describe our SCons examples,
commands, and other stuff.
-
- Note that this doesn't work with the 1.5.2 sgmllib module, because
- that didn't have the ability to work with ENTITY declarations.
"""
def __init__(self, outfp):
sgmllib.SGMLParser.__init__(self)
@@ -568,8 +556,14 @@ class MySGML(sgmllib.SGMLParser):
# Here is where the heavy lifting begins. The following methods
# handle the begin-end tags of our SCons examples.
+ def for_display(self, contents):
+ contents = contents.replace('__ROOT__', '')
+ contents = contents.replace('<', '&lt;')
+ contents = contents.replace('>', '&gt;')
+ return contents
+
def start_scons_example(self, attrs):
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if t:
name = t[0][1]
try:
@@ -585,7 +579,7 @@ class MySGML(sgmllib.SGMLParser):
def end_scons_example(self):
e = self.e
- files = filter(lambda f: f.printme, e.files)
+ files = [f for f in e.files if f.printme]
if files:
self.outfp.write('<programlisting>')
for f in files:
@@ -593,9 +587,7 @@ class MySGML(sgmllib.SGMLParser):
i = len(f.data) - 1
while f.data[i] == ' ':
i = i - 1
- output = string.replace(f.data[:i+1], '__ROOT__', '')
- output = string.replace(output, '<', '&lt;')
- output = string.replace(output, '>', '&gt;')
+ output = self.for_display(f.data[:i+1])
self.outfp.write(output)
if e.data and e.data[0] == '\n':
e.data = e.data[1:]
@@ -608,7 +600,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<file> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <file> name attribute found")
try:
@@ -632,7 +624,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<directory> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <directory> name attribute found")
try:
@@ -651,7 +643,7 @@ class MySGML(sgmllib.SGMLParser):
self.afunclist = self.afunclist[:-1]
def start_scons_example_file(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_example_file> example attribute found")
exname = t[0][1]
@@ -659,11 +651,11 @@ class MySGML(sgmllib.SGMLParser):
e = self.examples[exname]
except KeyError:
self.error("unknown example name '%s'" % exname)
- fattrs = filter(lambda t: t[0] == 'name', attrs)
+ fattrs = [t for t in attrs if t[0] == 'name']
if not fattrs:
self.error("no <scons_example_file> name attribute found")
fname = fattrs[0][1]
- f = filter(lambda f, fname=fname: f.name == fname, e.files)
+ f = [f for f in e.files if f.name == fname]
if not f:
self.error("example '%s' does not have a file named '%s'" % (exname, fname))
self.f = f[0]
@@ -675,7 +667,7 @@ class MySGML(sgmllib.SGMLParser):
delattr(self, 'f')
def start_scons_output(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_output> example attribute found")
exname = t[0][1]
@@ -704,7 +696,7 @@ class MySGML(sgmllib.SGMLParser):
if o.preserve:
t.preserve()
t.subdir('ROOT', 'WORK')
- t.rootpath = string.replace(t.workpath('ROOT'), '\\', '\\\\')
+ t.rootpath = t.workpath('ROOT').replace('\\', '\\\\')
for d in e.dirs:
dir = t.workpath('WORK', d.name)
@@ -715,19 +707,19 @@ class MySGML(sgmllib.SGMLParser):
i = 0
while f.data[i] == '\n':
i = i + 1
- lines = string.split(f.data[i:], '\n')
+ lines = f.data[i:].split('\n')
i = 0
while lines[0][i] == ' ':
i = i + 1
- lines = map(lambda l, i=i: l[i:], lines)
- path = string.replace(f.name, '__ROOT__', t.rootpath)
+ lines = [l[i:] for l in lines]
+ path = f.name.replace('__ROOT__', t.rootpath)
if not os.path.isabs(path):
path = t.workpath('WORK', path)
dir, name = os.path.split(path)
if dir and not os.path.exists(dir):
os.makedirs(dir)
- content = string.join(lines, '\n')
- content = string.replace(content, '__ROOT__', t.rootpath)
+ content = '\n'.join(lines)
+ content = content.replace('__ROOT__', t.rootpath)
path = t.workpath('WORK', path)
t.write(path, content)
if hasattr(f, 'chmod'):
@@ -761,24 +753,23 @@ class MySGML(sgmllib.SGMLParser):
for c in o.commandlist:
self.outfp.write(p + Prompt[o.os])
- d = string.replace(c.data, '__ROOT__', '')
+ d = c.data.replace('__ROOT__', '')
self.outfp.write('<userinput>' + d + '</userinput>\n')
- e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
- args = string.split(e)
+ e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+ args = e.split()
lines = ExecuteCommand(args, c, t, {'osname':o.os, 'tools':o.tools})
content = None
if c.output:
content = c.output
elif lines:
- content = string.join(lines, '\n' + p)
+ content = ( '\n' + p).join(lines)
if content:
content = address_re.sub(r' at 0x700000&gt;', content)
content = engine_re.sub(r' File "bootstrap/src/engine/SCons/', content)
content = file_re.sub(r'\1 <module>', content)
content = nodelist_re.sub(r"\1 'NodeList' object \2", content)
- content = string.replace(content, '<', '&lt;')
- content = string.replace(content, '>', '&gt;')
+ content = self.for_display(content)
self.outfp.write(p + content + '\n')
if o.data[0] == '\n':
@@ -815,7 +806,7 @@ class MySGML(sgmllib.SGMLParser):
def end_sconstruct(self):
f = self.f
self.outfp.write('<programlisting>')
- output = string.replace(f.data, '__ROOT__', '')
+ output = self.for_display(f.data)
self.outfp.write(output + '</programlisting>')
delattr(self, 'f')
self.afunclist = self.afunclist[:-1]
@@ -827,7 +818,7 @@ def process(filename):
try:
f = open(filename, 'r')
except EnvironmentError, e:
- sys.stderr.write('%s: %s\n' % (filename, msg))
+ sys.stderr.write('%s: %s\n' % (filename, e))
return 1
data = f.read()
diff --git a/bin/scons-proc.py b/bin/scons-proc.py
index 15f22b7..7cdb618 100644
--- a/bin/scons-proc.py
+++ b/bin/scons-proc.py
@@ -10,13 +10,16 @@
# and/or .mod files contining the ENTITY definitions for each item,
# or in man-page-formatted output.
#
+import os
+import sys
import getopt
-import os.path
import re
-import string
-import StringIO
-import sys
import xml.sax
+try:
+ from io import StringIO
+except ImportError:
+ # No 'io' module or no StringIO in io
+ exec('from cStringIO import StringIO')
import SConsDoc
@@ -101,7 +104,7 @@ for f in args:
content = content.replace('-->\n', '-->')
input = xml_preamble + content + xml_postamble
try:
- saxparser.parse(StringIO.StringIO(input))
+ saxparser.parse(StringIO(input))
except:
sys.stderr.write("error in %s\n" % f)
raise
@@ -128,7 +131,7 @@ Link_Entities_Header = """\
-->
"""
-class SCons_XML:
+class SCons_XML(object):
def __init__(self, entries, **kw):
self.values = entries
for k, v in kw.items():
@@ -140,7 +143,7 @@ class SCons_XML:
class SCons_XML_to_XML(SCons_XML):
def write(self, files):
- gen, mod = string.split(files, ',')
+ gen, mod = files.split(',')
g.write_gen(gen)
g.write_mod(mod)
def write_gen(self, filename):
@@ -157,12 +160,12 @@ class SCons_XML_to_XML(SCons_XML):
for chunk in v.summary.body:
f.write(str(chunk))
if v.sets:
- s = map(lambda x: '&cv-link-%s;' % x, v.sets)
+ s = ['&cv-link-%s;' % x for x in v.sets]
f.write('<para>\n')
f.write('Sets: ' + ', '.join(s) + '.\n')
f.write('</para>\n')
if v.uses:
- u = map(lambda x: '&cv-link-%s;' % x, v.uses)
+ u = ['&cv-link-%s;' % x for x in v.uses]
f.write('<para>\n')
f.write('Uses: ' + ', '.join(u) + '.\n')
f.write('</para>\n')
@@ -216,34 +219,34 @@ class SCons_XML_to_man(SCons_XML):
for v in self.values:
chunks.extend(v.mansep())
chunks.extend(v.initial_chunks())
- chunks.extend(map(str, v.summary.body))
+ chunks.extend(list(map(str, v.summary.body)))
body = ''.join(chunks)
- body = string.replace(body, '<programlisting>', '.ES')
- body = string.replace(body, '</programlisting>', '.EE')
- body = string.replace(body, '\n</para>\n<para>\n', '\n\n')
- body = string.replace(body, '<para>\n', '')
- body = string.replace(body, '<para>', '\n')
- body = string.replace(body, '</para>\n', '')
-
- body = string.replace(body, '<variablelist>\n', '.RS 10\n')
+ body = body.replace('<programlisting>', '.ES')
+ body = body.replace('</programlisting>', '.EE')
+ body = body.replace('\n</para>\n<para>\n', '\n\n')
+ body = body.replace('<para>\n', '')
+ body = body.replace('<para>', '\n')
+ body = body.replace('</para>\n', '')
+
+ body = body.replace('<variablelist>\n', '.RS 10\n')
# Handling <varlistentry> needs to be rationalized and made
# consistent. Right now, the <term> values map to arbitrary,
# ad-hoc idioms in the current man page.
body = re.compile(r'<varlistentry>\n<term><literal>([^<]*)</literal></term>\n<listitem>\n').sub(r'.TP 6\n.B \1\n', body)
body = re.compile(r'<varlistentry>\n<term><parameter>([^<]*)</parameter></term>\n<listitem>\n').sub(r'.IP \1\n', body)
body = re.compile(r'<varlistentry>\n<term>([^<]*)</term>\n<listitem>\n').sub(r'.HP 6\n.B \1\n', body)
- body = string.replace(body, '</listitem>\n', '')
- body = string.replace(body, '</varlistentry>\n', '')
- body = string.replace(body, '</variablelist>\n', '.RE\n')
+ body = body.replace('</listitem>\n', '')
+ body = body.replace('</varlistentry>\n', '')
+ body = body.replace('</variablelist>\n', '.RE\n')
body = re.sub(r'\.EE\n\n+(?!\.IP)', '.EE\n.IP\n', body)
- body = string.replace(body, '\n.IP\n\'\\"', '\n\n\'\\"')
+ body = body.replace('\n.IP\n\'\\"', '\n\n\'\\"')
body = re.sub('&(scons|SConstruct|SConscript|jar|Make|lambda);', r'\\fB\1\\fP', body)
body = re.sub('&(TARGET|TARGETS|SOURCE|SOURCES);', r'\\fB$\1\\fP', body)
- body = string.replace(body, '&Dir;', r'\fBDir\fP')
- body = string.replace(body, '&target;', r'\fItarget\fP')
- body = string.replace(body, '&source;', r'\fIsource\fP')
+ body = body.replace('&Dir;', r'\fBDir\fP')
+ body = body.replace('&target;', r'\fItarget\fP')
+ body = body.replace('&source;', r'\fIsource\fP')
body = re.sub('&b(-link)?-([^;]*);', r'\\fB\2\\fP()', body)
body = re.sub('&cv(-link)?-([^;]*);', r'$\2', body)
body = re.sub('&f(-link)?-env-([^;]*);', r'\\fBenv.\2\\fP()', body)
@@ -258,8 +261,8 @@ class SCons_XML_to_man(SCons_XML):
body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP$', re.M).sub(r'.R\2 \1 \3', body)
body = re.compile(r'^(\S+)\\f([BI])(.*)\\fP([^\s\\]+)$', re.M).sub(r'.R\2 \1 \3 \4', body)
body = re.compile(r'^(\.R[BI].*[\S])\s+$;', re.M).sub(r'\1', body)
- body = string.replace(body, '&lt;', '<')
- body = string.replace(body, '&gt;', '>')
+ body = body.replace('&lt;', '<')
+ body = body.replace('&gt;', '>')
body = re.sub(r'\\([^f])', r'\\\\\1', body)
body = re.compile("^'\\\\\\\\", re.M).sub("'\\\\", body)
body = re.compile(r'^\.([BI]R?) --', re.M).sub(r'.\1 \-\-', body)
@@ -268,7 +271,7 @@ class SCons_XML_to_man(SCons_XML):
body = re.compile(r'\\f([BI])-', re.M).sub(r'\\f\1\-', body)
f.write(body)
-class Proxy:
+class Proxy(object):
def __init__(self, subject):
"""Wrap an object as a Proxy object"""
self.__subject = subject
@@ -336,7 +339,7 @@ class Tool(Proxy):
prefix = 't-'
tag = 'literal'
def idfunc(self):
- return string.replace(self.name, '+', 'X')
+ return self.name.replace('+', 'X')
def termfunc(self):
return [self.name]
def entityfunc(self):
diff --git a/bin/scons-test.py b/bin/scons-test.py
index aa03d72..2191532 100644
--- a/bin/scons-test.py
+++ b/bin/scons-test.py
@@ -19,13 +19,21 @@ import getopt
import imp
import os
import os.path
-import string
import sys
import tempfile
import time
-import urllib
import zipfile
+try:
+ # try Python 3.x style
+ from urllib.request import urlretrieve
+except ImportError:
+ # nope, must be 2.x; this hack is equivalent
+ import imp
+ # protect import from fixer
+ urlretrieve = imp.load_module('urllib',
+ *imp.find_module('urllib')).urlretrieve
+
helpstr = """\
Usage: scons-test.py [-f zipfile] [-o outdir] [-v] [--xml] [runtest arguments]
Options:
@@ -70,7 +78,7 @@ if not os.path.exists(tempdir):
# Fetch the input file if it happens to be across a network somewhere.
# Ohmigod, does Python make this simple...
-inputfile, headers = urllib.urlretrieve(inputfile)
+inputfile, headers = urlretrieve(inputfile)
# Unzip the header file in the output directory. We use our own code
# (lifted from scons-unzip.py) to make the output subdirectory name
@@ -83,14 +91,14 @@ if outdir is None:
def outname(n, outdir=outdir):
l = []
- while 1:
+ while True:
n, tail = os.path.split(n)
if not n:
break
l.append(tail)
l.append(outdir)
l.reverse()
- return apply(os.path.join, l)
+ return os.path.join(*l)
for name in zf.namelist():
dest = outname(name)
@@ -135,7 +143,7 @@ fp.close()
if not args:
runtest_args = '-a'
else:
- runtest_args = string.join(args)
+ runtest_args = ' '.join(args)
if format == '--xml':
@@ -205,10 +213,7 @@ if format == '--xml':
]
print " <environment>"
- #keys = os.environ.keys()
- keys = environ_keys
- keys.sort()
- for key in keys:
+ for key in sorted(environ_keys):
value = os.environ.get(key)
if value:
print " <variable>"
diff --git a/bin/scons-unzip.py b/bin/scons-unzip.py
index 28c73f8..d4ec4bf 100644
--- a/bin/scons-unzip.py
+++ b/bin/scons-unzip.py
@@ -45,14 +45,14 @@ if outdir is None:
def outname(n, outdir=outdir):
l = []
- while 1:
+ while True:
n, tail = os.path.split(n)
if not n:
break
l.append(tail)
l.append(outdir)
l.reverse()
- return apply(os.path.join, l)
+ return os.path.join(*l)
for name in zf.namelist():
dest = outname(name)
diff --git a/bin/sconsexamples.py b/bin/sconsexamples.py
index 0a409bc..6d3b2de 100644
--- a/bin/sconsexamples.py
+++ b/bin/sconsexamples.py
@@ -66,13 +66,11 @@
# 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.
-#
import os
import os.path
import re
import sgmllib
-import string
import sys
sys.path.append(os.path.join(os.getcwd(), 'etc'))
@@ -93,7 +91,7 @@ import TestCmd
# Override it with our own regular expression that adds underscore.
sgmllib.entityref = re.compile('&([a-zA-Z][-_.a-zA-Z0-9]*)[^-_a-zA-Z0-9]')
-class DataCollector:
+class DataCollector(object):
"""Generic class for collecting data between a start tag and end
tag. We subclass for various types of tags we care about."""
def __init__(self):
@@ -156,12 +154,11 @@ Prompt = {
# command output.
Stdin = """\
-import string
import SCons.Defaults
platform = '%s'
-class Curry:
+class Curry(object):
def __init__(self, fun, *args, **kwargs):
self.fun = fun
self.pending = args[:]
@@ -174,15 +171,15 @@ class Curry:
else:
kw = kwargs or self.kwargs
- return apply(self.fun, self.pending + args, kw)
+ return self.fun(*self.pending + args, **kw)
def Str(target, source, env, cmd=""):
result = []
for cmd in env.subst_list(cmd, target=target, source=source):
- result.append(string.join(map(str, cmd)))
- return string.join(result, '\\n')
+ result.append(" ".join(map(str, cmd)))
+ return '\\n'.join(result)
-class ToolSurrogate:
+class ToolSurrogate(object):
def __init__(self, tool, variable, func):
self.tool = tool
self.variable = variable
@@ -212,7 +209,7 @@ ToolList = {
('mslink', 'LINKCOM', Cat)]
}
-tools = map(lambda t: apply(ToolSurrogate, t), ToolList[platform])
+tools = map(lambda t: ToolSurrogate(*t), ToolList[platform])
SCons.Defaults.ConstructionEnvironment.update({
'PLATFORM' : platform,
@@ -223,10 +220,7 @@ SConscript('SConstruct')
"""
class MySGML(sgmllib.SGMLParser):
- """A subclass of the standard Python 2.2 sgmllib SGML parser.
-
- Note that this doesn't work with the 1.5.2 sgmllib module, because
- that didn't have the ability to work with ENTITY declarations.
+ """A subclass of the standard Python sgmllib SGML parser.
"""
def __init__(self):
sgmllib.SGMLParser.__init__(self)
@@ -270,7 +264,7 @@ class MySGML(sgmllib.SGMLParser):
sys.stdout.write('&#' + ref + ';')
def start_scons_example(self, attrs):
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if t:
name = t[0][1]
try:
@@ -286,7 +280,7 @@ class MySGML(sgmllib.SGMLParser):
def end_scons_example(self):
e = self.e
- files = filter(lambda f: f.printme, e.files)
+ files = [f for f in e.files if f.printme]
if files:
sys.stdout.write('<programlisting>')
for f in files:
@@ -294,7 +288,7 @@ class MySGML(sgmllib.SGMLParser):
i = len(f.data) - 1
while f.data[i] == ' ':
i = i - 1
- output = string.replace(f.data[:i+1], '__ROOT__', '')
+ output = f.data[:i+1].replace('__ROOT__', '')
sys.stdout.write(output)
if e.data and e.data[0] == '\n':
e.data = e.data[1:]
@@ -307,7 +301,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<file> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <file> name attribute found")
try:
@@ -331,7 +325,7 @@ class MySGML(sgmllib.SGMLParser):
e = self.e
except AttributeError:
self.error("<directory> tag outside of <scons_example>")
- t = filter(lambda t: t[0] == 'name', attrs)
+ t = [t for t in attrs if t[0] == 'name']
if not t:
self.error("no <directory> name attribute found")
try:
@@ -350,7 +344,7 @@ class MySGML(sgmllib.SGMLParser):
self.afunclist = self.afunclist[:-1]
def start_scons_example_file(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_example_file> example attribute found")
exname = t[0][1]
@@ -358,11 +352,11 @@ class MySGML(sgmllib.SGMLParser):
e = self.examples[exname]
except KeyError:
self.error("unknown example name '%s'" % exname)
- fattrs = filter(lambda t: t[0] == 'name', attrs)
+ fattrs = [t for t in attrs if t[0] == 'name']
if not fattrs:
self.error("no <scons_example_file> name attribute found")
fname = fattrs[0][1]
- f = filter(lambda f, fname=fname: f.name == fname, e.files)
+ f = [f for f in e.files if f.name == fname]
if not f:
self.error("example '%s' does not have a file named '%s'" % (exname, fname))
self.f = f[0]
@@ -377,7 +371,7 @@ class MySGML(sgmllib.SGMLParser):
delattr(self, 'f')
def start_scons_output(self, attrs):
- t = filter(lambda t: t[0] == 'example', attrs)
+ t = [t for t in attrs if t[0] == 'example']
if not t:
self.error("no <scons_output> example attribute found")
exname = t[0][1]
@@ -408,20 +402,19 @@ class MySGML(sgmllib.SGMLParser):
i = 0
while f.data[i] == '\n':
i = i + 1
- lines = string.split(f.data[i:], '\n')
+ lines = f.data[i:].split('\n')
i = 0
while lines[0][i] == ' ':
i = i + 1
- lines = map(lambda l, i=i: l[i:], lines)
- path = string.replace(f.name, '__ROOT__', t.workpath('ROOT'))
+ lines = [l[i:] for l in lines]
+ path = f.name.replace('__ROOT__', t.workpath('ROOT'))
dir, name = os.path.split(f.name)
if dir:
dir = t.workpath('WORK', dir)
if not os.path.exists(dir):
os.makedirs(dir)
- content = string.join(lines, '\n')
- content = string.replace(content,
- '__ROOT__',
+ content = '\n'.join(lines)
+ content = content.replace('__ROOT__',
t.workpath('ROOT'))
t.write(t.workpath('WORK', f.name), content)
i = len(o.prefix)
@@ -431,19 +424,19 @@ class MySGML(sgmllib.SGMLParser):
p = o.prefix[i:]
for c in o.commandlist:
sys.stdout.write(p + Prompt[o.os])
- d = string.replace(c.data, '__ROOT__', '')
+ d = c.data.replace('__ROOT__', '')
sys.stdout.write('<userinput>' + d + '</userinput>\n')
- e = string.replace(c.data, '__ROOT__', t.workpath('ROOT'))
- args = string.split(e)[1:]
+ e = c.data.replace('__ROOT__', t.workpath('ROOT'))
+ args = e.split()[1:]
os.environ['SCONS_LIB_DIR'] = scons_lib_dir
t.run(interpreter = sys.executable,
program = scons_py,
- arguments = '-f - ' + string.join(args),
+ arguments = '-f - ' + ' '.join(args),
chdir = t.workpath('WORK'),
stdin = Stdin % o.os)
- out = string.replace(t.stdout(), t.workpath('ROOT'), '')
+ out = t.stdout().replace(t.workpath('ROOT'), '')
if out:
- lines = string.split(out, '\n')
+ lines = out.split('\n')
if lines:
while lines[-1] == '':
lines = lines[:-1]
diff --git a/bin/sfsum b/bin/sfsum
index a560b7d..2dfa422 100644
--- a/bin/sfsum
+++ b/bin/sfsum
@@ -25,7 +25,6 @@
import xml.sax
import xml.sax.saxutils
-import string
import sys
SFName = {
@@ -42,7 +41,7 @@ SFName = {
'Christoph Wiedemann' : 'wiedeman',
}
-class Artifact:
+class Artifact(object):
"""Just a place to hold attributes that we find in the XML."""
pass
@@ -51,7 +50,7 @@ Artifacts = {}
def nws(text):
"""Normalize white space. This will become important if/when
we enhance this to search for arbitrary fields."""
- return string.join(string.split(text), ' ')
+ return ' '.join(text.split())
class ClassifyArtifacts(xml.sax.saxutils.DefaultHandler):
"""
@@ -120,9 +119,9 @@ if __name__ == '__main__':
# Hard-coded search for 'Open' bugs. This should be easily
# generalized once we figure out other things for this script to do.
- bugs = filter(lambda x: x.status == 'Open', Artifacts['Bugs'])
+ bugs = [x for x in Artifacts['Bugs'] if x.status == 'Open']
- print Artifacts.keys()
+ print list(Artifacts.keys())
print "%d open bugs" % len(bugs)
diff --git a/bin/svn-bisect.py b/bin/svn-bisect.py
index e9ebcf8..77bda58 100755
--- a/bin/svn-bisect.py
+++ b/bin/svn-bisect.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# -*- Python -*-
+from __future__ import division
import sys
from math import log, ceil
@@ -52,7 +53,7 @@ msg = "****** max %d revisions to test (bug bracketed by [%d,%d])"
while upper-lower > 1:
print msg % (ceil(log(upper-lower,2)), lower, upper)
- mid = int((lower + upper)/2)
+ mid = (lower + upper)//2
midfails = testfail(mid)
if midfails == lowerfails:
lower = mid
diff --git a/bin/time-scons.py b/bin/time-scons.py
index 78d26e5..b7d8ef1 100644
--- a/bin/time-scons.py
+++ b/bin/time-scons.py
@@ -46,7 +46,7 @@ TimeSCons_revision = 4569
TimeSCons_pieces = ['QMTest', 'timings', 'runtest.py']
-class CommandRunner:
+class CommandRunner(object):
"""
Executor class for commands, including "commands" implemented by
Python functions.
@@ -81,11 +81,11 @@ class CommandRunner:
def display(self, command, stdout=None, stderr=None):
if not self.verbose:
return
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
- if type(command) == type([]):
+ if isinstance(command, list):
# TODO: quote arguments containing spaces
# TODO: handle meta characters?
s = ' '.join(command)
@@ -102,12 +102,12 @@ class CommandRunner:
"""
if not self.active:
return 0
- if type(command) == type(''):
+ if isinstance(command, str):
command = self.subst(command)
cmdargs = shlex.split(command)
if cmdargs[0] == 'cd':
command = (os.chdir,) + tuple(cmdargs[1:])
- if type(command) == type(()):
+ if isinstance(command, tuple):
func = command[0]
args = command[1:]
return func(*args)
@@ -260,13 +260,15 @@ def do_revisions(cr, opts, branch, revisions, scripts):
lf = os.path.join(opts.origin, opts.logsdir, subdir, log_name)
out = open(lf, 'w')
err = None
+ close_out = True
else:
out = stdout
err = stderr
+ close_out = False
s = cr.run(script_command(script), stdout=out, stderr=err)
if s and status == 0:
status = s
- if out not in (sys.stdout, None):
+ if close_out:
out.close()
out = None
diff --git a/bin/update-release-info.py b/bin/update-release-info.py
new file mode 100644
index 0000000..5c438db
--- /dev/null
+++ b/bin/update-release-info.py
@@ -0,0 +1,354 @@
+#!/usr/bin/env python
+"""
+This program takes information about a release in the ReleaseConfig file
+and inserts the information in various files. It helps to keep the files
+in sync because it never forgets which files need to be updated, nor what
+information should be inserted in each file.
+
+It takes one parameter that says what the mode of update should be, which
+may be one of 'develop', 'release', or 'post'.
+
+In 'develop' mode, which is what someone would use as part of their own
+development practices, the release type is forced to be 'alpha' and the
+patch level is the string 'yyyymmdd'. Otherwise, it's the same as the
+'release' mode.
+
+In 'release' mode, the release type is taken from ReleaseConfig and the
+patch level is calculated from the release date for non-final runs and
+taken from the version tuple for final runs. It then inserts information
+in various files:
+ - The RELEASE header line in src/CHANGES.txt and src/Announce.txt.
+ - The version string at the top of src/RELEASE.txt.
+ - The version string in the 'default_version' variable in SConstruct
+ and QMTest/TestSCons.py.
+ - The copyright years in SConstruct and QMTest/TestSCons.py.
+ - The month and year (used for documentation) in SConstruct.
+ - The unsupported and deprecated Python floors in QMTest/TestSCons.py
+ and src/engine/SCons/Script/Main.py
+ - The version string in the filenames in README.
+
+In 'post' mode, files are prepared for the next release cycle:
+ - In ReleaseConfig, the version tuple is updated for the next release
+ by incrementing the release number (either minor or micro, depending
+ on the branch) and resetting release type to 'alpha'.
+ - A blank template replaces src/RELEASE.txt.
+ - A new section to accumulate changes is added to src/CHANGES.txt and
+ src/Announce.txt.
+"""
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
+# 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__ = "bin/update-release-info.py 5023 2010/06/14 22:05:46 scons"
+
+import os
+import sys
+import time
+import re
+
+DEBUG = os.environ.get('DEBUG', 0)
+
+# Evaluate parameter
+
+if len(sys.argv) < 2:
+ mode = 'develop'
+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)
+ sys.exit(1)
+
+# Get configuration information
+
+config = dict()
+exec open('ReleaseConfig').read() in globals(), config
+
+try:
+ version_tuple = config['version_tuple']
+ unsupported_version = config['unsupported_python_version']
+ deprecated_version = config['deprecated_python_version']
+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
+
+try:
+ release_date = config['release_date']
+except KeyError:
+ release_date = time.localtime()[:6]
+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
+ sys.exit(1)
+if DEBUG: print 'release date', release_date
+
+if mode == 'develop' and version_tuple[3] != 'alpha':
+ version_tuple == version_tuple[:3] + ('alpha', 0)
+if version_tuple[3] != 'final':
+ if mode == 'develop':
+ version_tuple = version_tuple[:4] + ('yyyymmdd',)
+ else:
+ yyyy,mm,dd,_,_,_ = release_date
+ version_tuple = version_tuple[:4] + ((yyyy*100 + mm)*100 + dd,)
+version_string = '.'.join(map(str, version_tuple))
+version_type = version_tuple[3]
+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)
+ sys.exit(1)
+
+try:
+ month_year = config['month_year']
+except KeyError:
+ if version_type == 'alpha':
+ month_year = 'MONTH YEAR'
+ else:
+ month_year = time.strftime('%B %Y', release_date + (0,0,0))
+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
+
+class UpdateFile(object):
+ """
+ XXX
+ """
+
+ def __init__(self, file, orig = None):
+ '''
+ '''
+ if orig is None: orig = file
+ try:
+ self.content = open(orig, 'rU').read()
+ except IOError:
+ # Couldn't open file; don't try to write anything in __del__
+ self.file = None
+ raise
+ else:
+ self.file = file
+ if file == orig:
+ # so we can see if it changed
+ self.orig = self.content
+ else:
+ # pretend file changed
+ self.orig = ''
+
+ def sub(self, pattern, replacement, count = 1):
+ '''
+ XXX
+ '''
+ self.content = re.sub(pattern, replacement, self.content, count)
+
+ def replace_assign(self, name, replacement, count = 1):
+ '''
+ XXX
+ '''
+ self.sub('\n' + name + ' = .*', '\n' + name + ' = ' + replacement)
+
+ # Determine the pattern to match a version
+
+ _rel_types = '(alpha|beta|candidate|final)'
+ match_pat = '\d+\.\d+\.\d+\.' + _rel_types + '\.(\d+|yyyymmdd)'
+ match_rel = re.compile(match_pat)
+
+ def replace_version(self, replacement = version_string, count = 1):
+ '''
+ XXX
+ '''
+ self.content = self.match_rel.sub(replacement, self.content, count)
+
+ # Determine the release date and the pattern to match a date
+ # Mon, 05 Jun 2010 21:17:15 -0700
+ # NEW DATE WILL BE INSERTED HERE
+
+ if mode == 'develop':
+ new_date = 'NEW DATE WILL BE INSERTED HERE'
+ else:
+ min = (time.daylight and time.altzone or time.timezone)//60
+ hr = min//60
+ min = -(min%60 + hr*100)
+ new_date = (time.strftime('%a, %d %b %Y %X', release_date + (0,0,0))
+ + ' %+.4d' % min)
+
+ _days = '(Sun|Mon|Tue|Wed|Thu|Fri|Sat)'
+ _months = '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oce|Nov|Dec)'
+ match_date = _days+', \d\d '+_months+' \d\d\d\d \d\d:\d\d:\d\d [+-]\d\d\d\d'
+ match_date = re.compile(match_date)
+
+ def replace_date(self, replacement = new_date, count = 1):
+ '''
+ XXX
+ '''
+ self.content = self.match_date.sub(replacement, self.content, count)
+
+ def __del__(self):
+ '''
+ XXX
+ '''
+ if self.file is not None and self.content != self.orig:
+ print 'Updating ' + self.file + '...'
+ open(self.file, 'w').write(self.content)
+
+if mode == 'post':
+ # Set up for the next release series.
+
+ if version_tuple[2]:
+ # micro release, increment micro value
+ minor = version_tuple[1]
+ micro = version_tuple[2] + 1
+ else:
+ # minor release, increment minor value
+ minor = version_tuple[1] + 1
+ micro = 0
+ new_tuple = (version_tuple[0], minor, micro, 'alpha', 0)
+ new_version = '.'.join(map(str, new_tuple[:4])) + '.yyyymmdd'
+
+ # Update ReleaseConfig
+
+ t = UpdateFile('ReleaseConfig')
+ if DEBUG: t.file = '/tmp/ReleaseConfig'
+ t.replace_assign('version_tuple', str(new_tuple))
+
+ # Update src/CHANGES.txt
+
+ t = UpdateFile(os.path.join('src', 'CHANGES.txt'))
+ if DEBUG: t.file = '/tmp/CHANGES.txt'
+ t.sub('(\nRELEASE .*)', r"""\nRELEASE VERSION/DATE TO BE FILLED IN LATER\n
+ From John Doe:\n
+ - Whatever John Doe did.\n
+\1""")
+
+ # Update src/RELEASE.txt
+
+ t = UpdateFile(os.path.join('src', 'RELEASE.txt'),
+ os.path.join('template', 'RELEASE.txt'))
+ if DEBUG: t.file = '/tmp/RELEASE.txt'
+ t.replace_version(new_version)
+
+ # Update src/Announce.txt
+
+ t = UpdateFile(os.path.join('src', 'Announce.txt'))
+ if DEBUG: t.file = '/tmp/Announce.txt'
+ t.sub('\nRELEASE .*', '\nRELEASE VERSION/DATE TO BE FILLED IN LATER')
+ announce_pattern = """(
+ Please note the following important changes scheduled for the next
+ release:
+)"""
+ announce_replace = (r"""\1
+ -- FEATURE THAT WILL CHANGE\n
+ Please note the following important changes since release """
+ + '.'.join(map(str, version_tuple[:3])) + ':\n')
+ t.sub(announce_pattern, announce_replace)
+
+ # Write out the last update and exit
+
+ t = None
+ sys.exit()
+
+# Update src/CHANGES.txt
+
+t = UpdateFile(os.path.join('src', 'CHANGES.txt'))
+if DEBUG: t.file = '/tmp/CHANGES.txt'
+t.sub('\nRELEASE .*', '\nRELEASE ' + version_string + ' - ' + t.new_date)
+
+# Update src/RELEASE.txt
+
+t = UpdateFile(os.path.join('src', 'RELEASE.txt'))
+if DEBUG: t.file = '/tmp/RELEASE.txt'
+t.replace_version()
+
+# Update src/Announce.txt
+
+t = UpdateFile(os.path.join('src', 'Announce.txt'))
+if DEBUG: t.file = '/tmp/Announce.txt'
+t.sub('\nRELEASE .*', '\nRELEASE ' + version_string + ' - ' + t.new_date)
+
+# Update SConstruct
+
+t = UpdateFile('SConstruct')
+if DEBUG: t.file = '/tmp/SConstruct'
+t.replace_assign('month_year', repr(month_year))
+t.replace_assign('copyright_years', repr(copyright_years))
+t.replace_assign('default_version', repr(version_string))
+
+# Update README
+
+t = UpdateFile('README')
+if DEBUG: t.file = '/tmp/README'
+t.sub('-' + t.match_pat + '\.', '-' + version_string + '.', count = 0)
+# the loop below can be removed after all 1.x.y releases are dead
+for suf in ['tar', 'win32', 'zip']:
+ t.sub('-(\d+\.\d+\.\d+)\.%s' % suf,
+ '-%s.%s' % (version_string, suf),
+ count = 0)
+
+# Update QMTest/TestSCons.py
+
+t = UpdateFile(os.path.join('QMTest', 'TestSCons.py'))
+if DEBUG: t.file = '/tmp/TestSCons.py'
+t.replace_assign('copyright_years', repr(copyright_years))
+t.replace_assign('default_version', repr(version_string))
+#??? t.replace_assign('SConsVersion', repr(version_string))
+t.replace_assign('python_version_unsupported', str(unsupported_version))
+t.replace_assign('python_version_deprecated', str(deprecated_version))
+
+# Update Script/Main.py
+
+t = UpdateFile(os.path.join('src', 'engine', 'SCons', 'Script', 'Main.py'))
+if DEBUG: t.file = '/tmp/Main.py'
+t.replace_assign('unsupported_python_version', str(unsupported_version))
+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))))
+t = UpdateFile(os.path.join('doc', 'user', 'main.in'))
+if DEBUG: t.file = '/tmp/main.in'
+## TODO debug these
+#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+
+t = UpdateFile(os.path.join('doc', 'user', 'main.xml'))
+if DEBUG: t.file = '/tmp/main.xml'
+## TODO debug these
+#t.sub('<pubdate>[^<]*</pubdate>', '<pubdate>' + docyears + '</pubdate>')
+#t.sub('<year>[^<]*</year>', '<year>' + docyears + '</year>')
+
+# Write out the last update
+
+t = None
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/bin/xmlagenda.py b/bin/xmlagenda.py
index 3009e4c..7937331 100755
--- a/bin/xmlagenda.py
+++ b/bin/xmlagenda.py
@@ -17,24 +17,23 @@
# The team members
# FIXME: These names really should be external to this script
-team = 'Bill Greg Steven Gary Ken Brandon Sohail Jim David'.split()
-team.sort()
+team = sorted('Steven Gary Greg Ken Jim David Bill Sergey Jason'.split())
# The elements to be picked out of the issue
PickList = [
- # sort key -- these are used to sort the entry
- 'target_milestone', 'priority', 'votes_desc', 'creation_ts',
- # payload -- these are displayed
- 'issue_id', 'votes', 'issue_type', 'target_milestone',
- 'priority', 'assigned_to', 'short_desc',
- ]
+ # sort key -- these are used to sort the entry
+ 'target_milestone', 'priority', 'votes_desc', 'creation_ts',
+ # payload -- these are displayed
+ 'issue_id', 'votes', 'issue_type', 'target_milestone',
+ 'priority', 'assigned_to', 'short_desc',
+ ]
# Conbert a leaf element into its value as a text string
# We assume it's "short enough" that there's only one substring
def Value(element):
- v = element.firstChild
- if v is None: return ''
- return v.nodeValue
+ v = element.firstChild
+ if v is None: return ''
+ return v.nodeValue
# Parse the XML issues file and produce a DOM for it
import sys
@@ -47,26 +46,26 @@ xml = parse(xml)
# and put them in our list of issues.
issues = []
for issuezilla in xml.childNodes:
- # The Issuezilla element contains the issues
- if issuezilla.nodeType != issuezilla.ELEMENT_NODE: continue
- for issue in issuezilla.childNodes:
- # The issue elements contain the info for an issue
- if issue.nodeType != issue.ELEMENT_NODE: continue
- # Accumulate the pieces we want to include
- d = {}
- for element in issue.childNodes:
- if element.nodeName in PickList:
- d[element.nodeName] = Value(element)
- # convert 'votes' to numeric, ascending and descending
- try:
- v = int('0' + d['votes'])
- except KeyError:
- pass
- else:
- d['votes_desc'] = -v
- d['votes'] = v
- # Marshal the elements and add them to the list
- issues.append([ d[ix] for ix in PickList ])
+ # The Issuezilla element contains the issues
+ if issuezilla.nodeType != issuezilla.ELEMENT_NODE: continue
+ for issue in issuezilla.childNodes:
+ # The issue elements contain the info for an issue
+ if issue.nodeType != issue.ELEMENT_NODE: continue
+ # Accumulate the pieces we want to include
+ d = {}
+ for element in issue.childNodes:
+ if element.nodeName in PickList:
+ d[element.nodeName] = Value(element)
+ # convert 'votes' to numeric, ascending and descending
+ try:
+ v = int('0' + d['votes'])
+ except KeyError:
+ pass
+ else:
+ d['votes_desc'] = -v
+ d['votes'] = v
+ # Marshal the elements and add them to the list
+ issues.append([ d[ix] for ix in PickList ])
issues.sort()
# Transcribe the issues into comma-separated values.
@@ -75,16 +74,16 @@ import csv
writer = csv.writer(open('editlist.csv', 'w'))
# header
writer.writerow(['ID', 'Votes', 'Type/Member', 'Milestone',
- 'Pri', 'Owner', 'Summary/Comments'])
+ 'Pri', 'Owner', 'Summary/Comments'])
for issue in issues:
- row = issue[4:] # strip off sort key
- #row[0] = """=hyperlink("http://scons.tigris.org/issues/show_bug.cgi?id=%s","%s")""" % (row[0],row[0])
- if row[3] == '-unspecified-': row[3] = 'triage'
- writer.writerow(['','','','','','',''])
- writer.writerow(row)
- writer.writerow(['','','consensus','','','',''])
- writer.writerow(['','','','','','',''])
- for member in team: writer.writerow(['','',member,'','','',''])
+ row = issue[4:] # strip off sort key
+ #row[0] = """=hyperlink("http://scons.tigris.org/issues/show_bug.cgi?id=%s","%s")""" % (row[0],row[0])
+ if row[3] == '-unspecified-': row[3] = 'triage'
+ writer.writerow(['','','','','','',''])
+ writer.writerow(row)
+ writer.writerow(['','','consensus','','','',''])
+ writer.writerow(['','','','','','',''])
+ for member in team: writer.writerow(['','',member,'','','',''])
# Local Variables:
# tab-width:4
diff --git a/doc/SConscript b/doc/SConscript
index 9ad4d12..e0b3f71 100644
--- a/doc/SConscript
+++ b/doc/SConscript
@@ -23,11 +23,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.
-#
import os.path
import re
-import string
Import('build_dir', 'env', 'whereis')
@@ -93,7 +91,7 @@ def scanxml(node, env, target):
if tail == 'doc':
break
a = [tail] + a
- file = apply(os.path.join, a, {})
+ file = os.path.join(*a)
includes.append(file)
return includes
@@ -119,8 +117,8 @@ def chop(s): return s[:-1]
#manifest_in = File('#src/engine/MANIFEST.in').rstr()
manifest_xml_in = File('#src/engine/MANIFEST-xml.in').rstr()
-scons_doc_files = map(chop, open(manifest_xml_in).readlines())
-scons_doc_files = map(lambda x: File('#src/engine/'+x).rstr(), scons_doc_files)
+scons_doc_files = list(map(chop, open(manifest_xml_in).readlines()))
+scons_doc_files = [File('#src/engine/'+x).rstr() for x in scons_doc_files]
if not jw:
print "jw not found, skipping building User Guide."
@@ -240,7 +238,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
# get included by the document XML files in the subdirectories.
#
manifest = File('MANIFEST').rstr()
- src_files = map(lambda x: x[:-1], open(manifest).readlines())
+ src_files = [x[:-1] for x in open(manifest).readlines()]
for s in src_files:
base, ext = os.path.splitext(s)
if ext in ['.fig', '.jpg']:
@@ -255,8 +253,7 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
#
for doc in docs.keys():
manifest = File(os.path.join(doc, 'MANIFEST')).rstr()
- src_files = map(lambda x: x[:-1],
- open(manifest).readlines())
+ src_files = [x[:-1] for x in open(manifest).readlines()]
build_doc = docs[doc].get('scons-doc') and int(ARGUMENTS.get('BUILDDOC', 0))
for s in src_files:
doc_s = os.path.join(doc, s)
@@ -408,8 +405,7 @@ for m in man_page_list:
man_i_files = ['builders.man', 'tools.man', 'variables.man']
-man_intermediate_files = map(lambda x: os.path.join(build, 'man', x),
- man_i_files)
+man_intermediate_files = [os.path.join(build, 'man', x) for x in man_i_files]
cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)"
man_intermediate_files = env.Command(man_intermediate_files,
@@ -444,12 +440,12 @@ for man_1 in man_page_list:
def strip_to_first_html_tag(target, source, env):
t = str(target[0])
contents = open(t).read()
- contents = contents[string.find(contents, '<HTML>'):]
+ contents = contents[contents.find('<HTML>'):]
open(t, 'w').write(contents)
return 0
cmds = [
- "( cd %s/man && cp %s .. )" % (build, string.join(man_i_files)),
+ "( cd %s/man && cp %s .. )" % (build, ' '.join(man_i_files)),
"( cd ${SOURCE.dir} && man2html ${SOURCE.file} ) > $TARGET",
Action(strip_to_first_html_tag),
]
@@ -469,15 +465,15 @@ else:
# the SConstruct file.
e = os.path.join('#src', 'engine')
manifest_in = File(os.path.join(e, 'MANIFEST.in')).rstr()
- sources = map(lambda x: x[:-1], open(manifest_in).readlines())
- sources = filter(lambda x: string.find(x, 'Optik') == -1, sources)
- sources = filter(lambda x: string.find(x, 'Platform') == -1, sources)
- sources = filter(lambda x: string.find(x, 'Tool') == -1, sources)
+ sources = [x[:-1] for x in open(manifest_in).readlines()]
+ sources = [x for x in sources if x.find('Optik') == -1]
+ sources = [x for x in sources if x.find('Platform') == -1]
+ sources = [x for x in sources if x.find('Tool') == -1]
# XXX
- sources = filter(lambda x: string.find(x, 'Options') == -1, sources)
+ sources = [x for x in sources if x.find('Options') == -1]
e = os.path.join(build, '..', 'scons', 'engine')
- sources = map(lambda x, e=e: os.path.join(e, x), sources)
+ sources = [os.path.join(e, x) for x in sources]
epydoc_commands = [
Delete('$OUTDIR'),
@@ -519,8 +515,7 @@ else:
# for easy distribution to the web site.
#
if tar_deps:
- tar_list = string.join(map(lambda x, b=build+'/': string.replace(x, b, ''),
- tar_list))
+ tar_list = ' '.join([x.replace(build+'/', '') for x in tar_list])
t = env.Command(dist_doc_tar_gz, tar_deps,
"tar cf${TAR_HFLAG} - -C %s %s | gzip > $TARGET" % (build, tar_list))
AddPostAction(dist_doc_tar_gz, Chmod(dist_doc_tar_gz, 0644))
diff --git a/doc/design/engine.xml b/doc/design/engine.xml
index 1a1e335..afe9877 100644
--- a/doc/design/engine.xml
+++ b/doc/design/engine.xml
@@ -85,7 +85,7 @@
<section id="sect-envs">
- <title>&ConsEnvs</title>
+ <title>&ConsEnvs;</title>
<para>
@@ -129,7 +129,7 @@
<footnote>
<para>
It would be nice if we could avoid re-inventing the wheel here by
- using some other Python-based tool &Autoconf replacement--like what
+ using some other Python-based tool &Autoconf; replacement--like what
was supposed to come out of the Software Carpentry configuration
tool contest. It will probably be most efficient to roll our own
logic initially and convert if something better does come along.
@@ -283,7 +283,7 @@
MyBuilder = Builder(command = "$XX $XXFLAGS -c $_INPUTS -o $target")
env.Command(targets = 'bar.out', sources = 'bar.in',
- command = "sed '1d' < $source > $target")
+ command = "sed '1d' &lt; $source > $target")
</programlisting>
<para>
@@ -317,7 +317,7 @@
<programlisting>
env = Environment(FUNC = myfunc)
env.Command(target = 'foo.out', source = 'foo.in',
- command = "${FUNC($<)}")
+ command = "${FUNC($&lt;)}")
</programlisting>
<para>
@@ -1678,8 +1678,8 @@ I dunno, maybe this is fine as it is...
<literal>target</literal> (that is, one passed to the
&Build; or &Clean; method). Objects which a top-level
<literal>target</literal> is directly dependent upon have a
- <literal>level</literal> of <1>, their direct dependencies have a
- <literal>level</literal> of <2>, etc. Typically used to indent
+ <literal>level</literal> of &lt;1>, their direct dependencies have a
+ <literal>level</literal> of &lt;2>, etc. Typically used to indent
output to reflect the recursive levels.
</para>
diff --git a/doc/design/goals.xml b/doc/design/goals.xml
index 2a7b69b..f2e6b7c 100644
--- a/doc/design/goals.xml
+++ b/doc/design/goals.xml
@@ -26,7 +26,7 @@
<para>
As a next-generation build tool,
- &SCons should fundamentally
+ &SCons; should fundamentally
improve on its predecessors.
Rather than simply being driven by trying to
<emphasis>not</emphasis> be like previous tools,
diff --git a/doc/design/native.xml b/doc/design/native.xml
index 8cdd867..c665e0c 100644
--- a/doc/design/native.xml
+++ b/doc/design/native.xml
@@ -52,7 +52,7 @@
<para>
By default, the &SCons; utility searches for a file named
- &SConstruct;, &Sconstruct; or &sconstruct (in that order) in the
+ &SConstruct;, &Sconstruct; or &sconstruct; (in that order) in the
current directory, and reads its configuration from the first file
found. A <option>-f</option> command-line option exists to read a
different file name.
@@ -175,7 +175,7 @@
Any variables (not just &SCons; objects) that are to be shared between configuration files must be
explicitly passed in the &SConscript; call
- using the &Export method:
+ using the &Export; method:
</para>
@@ -261,7 +261,7 @@ Equivalent to the above example:
<para>
- &SCons; will allow users to share &consenvs, as well as other &SCons;
+ &SCons; will allow users to share &consenvs;, as well as other &SCons;
objects and Python variables, by importing them from a central, shared
repository using normal Python syntax:
diff --git a/doc/design/overview.xml b/doc/design/overview.xml
index 38e4258..266c9e8 100644
--- a/doc/design/overview.xml
+++ b/doc/design/overview.xml
@@ -409,7 +409,7 @@ This is where it will go, anyway...
<para>
An alternate &SCons; interface would provide backwards
- compatibility with the classic &Make utility.
+ compatibility with the classic &Make; utility.
This would be done by embedding the &SCons; Build Engine
in a Python script that can translate existing
&Makefile;s into the underlying calls to the
diff --git a/doc/developer/preface.xml b/doc/developer/preface.xml
index 05b7562..da2964c 100644
--- a/doc/developer/preface.xml
+++ b/doc/developer/preface.xml
@@ -36,7 +36,7 @@
<para>
There are a few overriding principles
- we try to live up to in designing and implementing &SCons:
+ we try to live up to in designing and implementing &SCons;:
</para>
diff --git a/doc/man/scons-time.1 b/doc/man/scons-time.1
index 4160986..81417c3 100644
--- a/doc/man/scons-time.1
+++ b/doc/man/scons-time.1
@@ -19,7 +19,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.
.\"
-.\" doc/man/scons-time.1 4720 2010/03/24 03:14:11 jars
+.\" doc/man/scons-time.1 5023 2010/06/14 22:05:46 scons
.\"
.\" ES - Example Start - indents and turns off line fill
.de ES
@@ -98,7 +98,7 @@
[\fB--which=\fIWHICH\fR]
[\fIARGUMENTS\fR]
..
-.TH SCONS-TIME 1 "March 2010"
+.TH SCONS-TIME 1 "June 2010"
.SH NAME
scons-time \- generate and display SCons timing information
'\"==========================================================================
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 0cfe62a..9617fec 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -19,9 +19,9 @@
.\" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
.\" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
.\"
-.\" doc/man/scons.1 4720 2010/03/24 03:14:11 jars
+.\" doc/man/scons.1 5023 2010/06/14 22:05:46 scons
.\"
-.TH SCONS 1 "March 2010"
+.TH SCONS 1 "June 2010"
.\" ES - Example Start - indents and turns off line fill
.rm ES
.de ES
@@ -380,7 +380,7 @@ try to access a list member that
does not exist.
.B scons
-requires Python version 1.5.2 or later.
+requires Python version 2.4 or later.
There should be no other dependencies or requirements to run
.B scons.
@@ -591,10 +591,9 @@ Print how many objects are created
of the various classes used internally by SCons
before and after reading the SConscript files
and before and after building targets.
-This is not supported when run under Python versions earlier than 2.1,
-when SCons is executed with the Python
+This is not supported when SCons is executed with the Python
.B -O
-(optimized) option,
+(optimized) option
or when the SCons modules
have been compiled with optimization
(that is, when executing from
@@ -642,7 +641,6 @@ Prints a summary of hits and misses using the Memoizer,
an internal subsystem that counts
how often SCons uses cached values in memory
instead of recomputing them each time they're needed.
-Only available when using Python 2.2 or later.
.TP
--debug=memory
@@ -658,7 +656,6 @@ A deprecated option preserved for backwards compatibility.
--debug=objects
Prints a list of the various objects
of the various classes used internally by SCons.
-This only works when run under Python 2.1 or later.
.TP
--debug=pdb
@@ -1841,9 +1838,7 @@ and a same-named environment method
that split a single string
into a list, separated on
strings of white-space characters.
-(These are similar to the
-string.split() method
-from the standard Python library,
+(These are similar to the split() member function of Python strings
but work even if the input isn't a string.)
Like all Python arguments,
@@ -1862,7 +1857,7 @@ env.Program('bar', env.Split('bar.c foo.c'))
env.Program(source = ['bar.c', 'foo.c'], target = 'bar')
env.Program(target = 'bar', Split('bar.c foo.c'))
env.Program(target = 'bar', env.Split('bar.c foo.c'))
-env.Program('bar', source = string.split('bar.c foo.c'))
+env.Program('bar', source = 'bar.c foo.c'.split())
.EE
Target and source file names
@@ -2273,11 +2268,13 @@ and
Builders by adding them
to the
.B SourceFileScanner
-object as follows:
-
+object.
See the section "Scanner Objects,"
-below, for a more information about
-defining your own Scanner objects.
+below, for more information about
+defining your own Scanner objects
+and using the
+.B SourceFileScanner
+object.
.SS Methods and Functions to Do Things
In addition to Builder methods,
@@ -2448,13 +2445,6 @@ method (with a few additional capabilities noted below);
see the documentation for
.B optparse
for a thorough discussion of its option-processing capabities.
-(Note that although the
-.B optparse
-module was not a standard module until Python 2.3,
-.B scons
-contains a compatible version of the module
-that is used to provide identical functionality
-when run by earlier Python versions.)
In addition to the arguments and values supported by the
.B optparse.add_option ()
@@ -2796,6 +2786,10 @@ is intended to be passed to the
.B SourceCode
function.
+This function is deprecated. For details, see the entry for the
+.B SourceCode
+function.
+
Example:
.ES
@@ -3178,6 +3172,10 @@ replicate part of the repository
directory hierarchy in your
local build directory.
+This function is deprecated. For details, see the entry for the
+.B SourceCode
+function.
+
Examples:
.ES
@@ -3745,7 +3743,7 @@ in the path specified by
.IR dirs .
.I dirs
may be a list of directory names or a single directory name.
-In addition to searching for files that exist in the filesytem,
+In addition to searching for files that exist in the filesystem,
this function also searches for derived files
that have not yet been built.
@@ -4729,6 +4727,10 @@ is intended to be passed to the
.B SourceCode
function.
+This function is deprecated. For details, see the entry for the
+.B SourceCode
+function.
+
Example:
.ES
@@ -4844,7 +4846,7 @@ will overwrite itself on a display:
.ES
import sys
-class ProgressCounter:
+class ProgressCounter(object):
count = 0
def __call__(self, node, *args, **kw):
self.count += 100
@@ -5022,6 +5024,10 @@ is intended to be passed to the
.B SourceCode
function:
+This function is deprecated. For details, see the entry for the
+.B SourceCode
+function.
+
Examples:
.ES
@@ -5190,6 +5196,10 @@ is intended to be passed to the
.B SourceCode
function.
+This function is deprecated. For details, see the entry for the
+.B SourceCode
+function.
+
Example:
.ES
@@ -5502,7 +5512,7 @@ The default is to use a custom
.B SCons.dblite
module that uses pickled
Python data structures,
-and which works on all Python versions from 1.5.2 on.
+and which works on all Python versions.
Examples:
@@ -5534,7 +5544,7 @@ The following statements are equivalent:
.ES
env.SetDefault(FOO = 'foo')
-if not env.has_key('FOO'): env['FOO'] = 'foo'
+if 'FOO' not in env: env['FOO'] = 'foo'
.EE
'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@@ -5648,6 +5658,13 @@ function.
.RI SourceCode( entries ", " builder )
.TP
.RI env.SourceCode( entries ", " builder )
+This function and its associate factory functions are deprecated.
+There is no replacement.
+The intended use was to keep a local tree in sync with an archive,
+but in actuality the function only causes the archive
+to be fetched on the first run.
+Synchronizing with the archive is best done external to SCons.
+
Arrange for non-existent source files to
be fetched from a source code management system
using the specified
@@ -5836,6 +5853,10 @@ source_nodes = env.subst('$EXPAND_TO_NODELIST',
'\"directory hierarchy in your
'\"local build directory.
'\"
+'\"This function is deprecated. For details, see the entry for the
+'\".B SourceCode
+'\"function.
+'\"
'\"Example:
'\"
'\".ES
@@ -7395,7 +7416,7 @@ vars.Add('CC', 'The C compiler')
def validate_color(key, val, env):
if not val in ['red', 'blue', 'yellow']:
- raise "Invalid color value '%s'" % val
+ raise Exception("Invalid color value '%s'" % val)
vars.Add('COLOR', validator=valid_color)
.EE
@@ -8006,7 +8027,7 @@ may be indicated by a dictionary entry with a key value of None.
.P
.ES
-b = Builder("build_it < $SOURCE > $TARGET"
+b = Builder("build_it < $SOURCE > $TARGET",
prefix = "file-")
def gen_prefix(env, sources):
@@ -9259,7 +9280,7 @@ be associated with the
instantiation of the class:
.ES
-class foo:
+class foo(object):
def __init__(self, arg):
self.arg = arg
@@ -9382,7 +9403,9 @@ You can use the
function to define
objects to scan
new file types for implicit dependencies.
-Scanner accepts the following arguments:
+The
+.B Scanner
+function accepts the following arguments:
.IP function
This can be either:
@@ -9533,6 +9556,7 @@ that should be scanned recursively;
this can be used to select a specific subset of
Nodes for additional scanning.
+.RE
Note that
.B scons
has a global
@@ -9901,7 +9925,7 @@ as follows:
def pf(env, dir, target, source, arg):
top_dir = Dir('#').abspath
results = []
- if env.has_key('MYPATH'):
+ if 'MYPATH' in env:
for p in env['MYPATH']:
results.append(top_dir + os.sep + p)
return results
diff --git a/doc/man/sconsign.1 b/doc/man/sconsign.1
index aed21d7..eb3894c 100644
--- a/doc/man/sconsign.1
+++ b/doc/man/sconsign.1
@@ -19,7 +19,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.
.\"
-.\" doc/man/sconsign.1 4720 2010/03/24 03:14:11 jars
+.\" doc/man/sconsign.1 5023 2010/06/14 22:05:46 scons
.\"
.\" ES - Example Start - indents and turns off line fill
.de ES
@@ -31,7 +31,7 @@
.RE
.fi
..
-.TH SCONSIGN 1 "March 2010"
+.TH SCONSIGN 1 "June 2010"
.SH NAME
sconsign \- print SCons .sconsign file information
.SH SYNOPSIS
diff --git a/doc/python10/abstract.xml b/doc/python10/abstract.xml
index 294180b..45b4918 100644
--- a/doc/python10/abstract.xml
+++ b/doc/python10/abstract.xml
@@ -3,7 +3,7 @@
&SCons; is a software construction tool (build tool, or make tool)
implemented in Python, which uses Python scripts as "configuration
files" for software builds. Based on the design which won the
- Software Carpentry build tool competition, &SCons solves a number of
+ Software Carpentry build tool competition, &SCons; solves a number of
problems associated with other build tools, especially including the
classic and ubiquitous &Make; itself.
diff --git a/doc/python10/design.xml b/doc/python10/design.xml
index cb58af9..0dd5faa 100644
--- a/doc/python10/design.xml
+++ b/doc/python10/design.xml
@@ -6,14 +6,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="arch" format="eps" align="center">
+ <imagedata fileref="arch" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="arch.jpg" format="jpg" align="center">
+ <imagedata fileref="arch.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="arch.pdf" align="center">
+ <imagedata fileref="arch.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -166,14 +166,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="node" format="eps" align="center">
+ <imagedata fileref="node" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="node.jpg" format="jpg" align="center">
+ <imagedata fileref="node.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="node.pdf" align="center">
+ <imagedata fileref="node.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -230,14 +230,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="scanner" format="eps" align="center">
+ <imagedata fileref="scanner" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="scanner.jpg" format="jpg" align="center">
+ <imagedata fileref="scanner.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="scanner.pdf" align="center">
+ <imagedata fileref="scanner.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -264,7 +264,7 @@
signature information for &Node; objects.
The signature subsystem in &SCons;
supports multiple ways to
- determine whether a &Node is up-to-date
+ determine whether a &Node; is up-to-date
by using an abstract &Sig; class
as a strategy wrapper:
@@ -272,14 +272,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="sig" format="eps" align="center">
+ <imagedata fileref="sig" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="sig.jpg" format="jpg" align="center">
+ <imagedata fileref="sig.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="sig.pdf" align="center">
+ <imagedata fileref="sig.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -328,14 +328,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="builder" format="eps" align="center">
+ <imagedata fileref="builder" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="builder.jpg" format="jpg" align="center">
+ <imagedata fileref="builder.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="builder.pdf" align="center">
+ <imagedata fileref="builder.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -391,14 +391,14 @@
<mediaobject>
<imageobject>
- <imagedata fileref="job-task" format="eps" align="center">
+ <imagedata fileref="job-task" format="eps" align="center"/>
</imageobject>
<imageobject>
- <imagedata fileref="job-task.jpg" format="jpg" align="center">
+ <imagedata fileref="job-task.jpg" format="jpg" align="center"/>
</imageobject>
<!-- PDF files?
<imageobject>
- <imagedata fileref="job-task.pdf" align="center">
+ <imagedata fileref="job-task.pdf" align="center"/>
</imageobject>
-->
</mediaobject>
@@ -435,7 +435,7 @@
<para>
- The &Taskmaster uses the node subsystem's
+ The &Taskmaster; uses the node subsystem's
&Walker; class to walk the dependency tree,
and the &Sig; class to use the
appropriate method
@@ -629,8 +629,8 @@
<para>
&Builder; objects are associated with a &consenv; through a
- &consvar; named &BUILDERS;, a list of the &Builder objects that
- will be available for execution through the &consenv:
+ &consvar; named &BUILDERS;, a list of the &Builder; objects that
+ will be available for execution through the &consenv;:
</para>
@@ -679,7 +679,7 @@
&Scanner; objects are associated with a &consenv; through a
&consvar; named &SCANNERS;, a list of the &Scanner; objects that
- will be available through the &consenv:
+ will be available through the &consenv;:
</para>
@@ -818,10 +818,10 @@
The most noticeable difference between &scons; and &Make;, or most
other build tools, is that the configuration files are actually
Python scripts, generically called "SConscripts" (although the
- top-level "Makefile" is named &SConstruct). Users do not have to
+ top-level "Makefile" is named &SConstruct;). Users do not have to
learn a new language syntax, but instead configure dependency
information by making direct calls to the Python API of the
- &SCons; Build Engine. Here is an example &SConstruct file which
+ &SCons; Build Engine. Here is an example &SConstruct; file which
builds a program in side-by-side normal and debug versions:
</para>
diff --git a/doc/python10/main.xml b/doc/python10/main.xml
index 42bc4af..e061b90 100644
--- a/doc/python10/main.xml
+++ b/doc/python10/main.xml
@@ -182,7 +182,7 @@
<holder>O'Reilly &amp; Associates, Inc.</holder>
</copyright>
<publisher>
- <publishername>O'Reilly & Associates, Inc.</publishername>
+ <publishername>O'Reilly &amp; Associates, Inc.</publishername>
</publisher>
<title>Managing Projects with Make, 2nd Ed.</title>
</biblioentry>
diff --git a/doc/python10/process.xml b/doc/python10/process.xml
index f1b2479..4ff0ab1 100644
--- a/doc/python10/process.xml
+++ b/doc/python10/process.xml
@@ -13,7 +13,7 @@
<listitem>
<para>
- &SCons; will be written to Python version 1.5.2 (to ensure
+ &SCons; will be written to Python version 2.4 (to ensure
usability by a wide install base).
</para>
@@ -181,7 +181,7 @@
<para>
- In practice, these restrictions can be overridden as necessary­for
+ In practice, these restrictions can be overridden as necessary--for
example, when changing comments or documentation.
</para>
diff --git a/doc/scons.mod b/doc/scons.mod
index b500101..b1993d4 100644
--- a/doc/scons.mod
+++ b/doc/scons.mod
@@ -157,6 +157,7 @@
<!ENTITY AddVariables "<function>AddVariables</function>">
<!ENTITY Alias "<function>Alias</function>">
<!ENTITY Aliases "<function>Aliases</function>">
+<!ENTITY AllowSubstExceptions "<function>AllowSubstExceptions</function>">
<!ENTITY AlwaysBuild "<function>AlwaysBuild</function>">
<!ENTITY Append "<function>Append</function>">
<!ENTITY AppendENVPath "<function>AppendENVPath</function>">
@@ -191,10 +192,12 @@
<!ENTITY File "<function>File</function>">
<!ENTITY FindFile "<function>FindFile</function>">
<!ENTITY FindInstalledFiles "<function>FindInstalledFiles</function>">
+<!ENTITY FindPathDirs "<function>FindPathDirs</function>">
<!ENTITY Finish "<function>Finish</function>">
<!ENTITY Flatten "<function>Flatten</function>">
<!ENTITY GenerateHelpText "<function>GenerateHelpText</function>">
<!ENTITY GetBuildFailures "<function>GetBuildFailures</function>">
+<!ENTITY GetBuildPath "<function>GetBuildPath</function>">
<!ENTITY GetLaunchDir "<function>GetLaunchDir</function>">
<!ENTITY GetOption "<function>GetOption</function>">
<!ENTITY Glob "<function>Glob</function>">
@@ -279,7 +282,9 @@
<!ENTITY TryRun "<function>TryRun</function>">
-<!-- Python functions -->
+<!-- Python functions and classes -->
+<!ENTITY IndexError "<classname>IndexError</classname>">
+<!ENTITY NameError "<classname>NameError</classname>">
<!ENTITY str "<function>str</function>">
<!ENTITY zipfile "<function>zipfile</function>">
diff --git a/doc/user/actions.in b/doc/user/actions.in
index 3f91c67..06dcd63 100644
--- a/doc/user/actions.in
+++ b/doc/user/actions.in
@@ -245,7 +245,7 @@ solutions to the above limitations.
</para>
<sconstruct>
- b = Builder(action = 'build < $SOURCE > $TARGET')
+ b = Builder(action = 'build &lt; $SOURCE &gt; $TARGET')
</sconstruct>
<para>
@@ -255,7 +255,7 @@ solutions to the above limitations.
</para>
<sconstruct>
- b = Builder(action = Action('build < $SOURCE > $TARGET'))
+ b = Builder(action = Action('build &lt; $SOURCE &gt; $TARGET'))
</sconstruct>
<para>
diff --git a/doc/user/actions.xml b/doc/user/actions.xml
index f969698..7231a70 100644
--- a/doc/user/actions.xml
+++ b/doc/user/actions.xml
@@ -245,7 +245,7 @@ solutions to the above limitations.
</para>
<programlisting>
- b = Builder(action = 'build < $SOURCE > $TARGET')
+ b = Builder(action = 'build &lt; $SOURCE &gt; $TARGET')
</programlisting>
<para>
@@ -255,7 +255,7 @@ solutions to the above limitations.
</para>
<programlisting>
- b = Builder(action = Action('build < $SOURCE > $TARGET'))
+ b = Builder(action = Action('build &lt; $SOURCE &gt; $TARGET'))
</programlisting>
<para>
diff --git a/doc/user/build-install.in b/doc/user/build-install.in
index 577c140..05ead9d 100644
--- a/doc/user/build-install.in
+++ b/doc/user/build-install.in
@@ -111,17 +111,6 @@
<para>
- (Note that the <option>-V</option> option
- was added to Python version 2.0,
- so if your system only has an earlier version available
- you may see an
- <literal>"Unknown option: -V"</literal>
- error message.)
-
- </para>
-
- <para>
-
The standard location for information
about downloading and installing Python is
<ulink url="http://www.python.org/download/">http://www.python.org/download/</ulink>.
@@ -132,10 +121,10 @@
<para>
- &SCons; will work with any version of Python from 1.5.2 or later.
+ &SCons; will work with any version of Python from 2.4 or later.
If you need to install Python and have a choice,
- we recommend using the most recent Python 2.5 version available.
- Python 2.5 has significant improvements
+ we recommend using the most recent Python version available.
+ Newer Pythons have significant improvements
that help speed up the performance of &SCons;.
</para>
@@ -209,7 +198,7 @@
</para>
<screen>
- # <userinput>rpm -Uvh scons-1.3.0-1.noarch.rpm</userinput>
+ # <userinput>rpm -Uvh scons-2.0.0.final.0-1.noarch.rpm</userinput>
</screen>
<para>
@@ -271,7 +260,7 @@
&SCons; provides a Windows installer
that makes installation extremely easy.
- Download the <filename>scons-1.3.0.win32.exe</filename>
+ Download the <filename>scons-2.0.0.final.0.win32.exe</filename>
file from the &SCons; download page at
<ulink url="http://www.scons.org/download.php">http://www.scons.org/download.php</ulink>.
Then all you need to do is execute the file
@@ -381,8 +370,8 @@
<para>
The first step is to download either the
- <filename>scons-1.3.0.tar.gz</filename>
- or <filename>scons-1.3.0.zip</filename>,
+ <filename>scons-2.0.0.final.0.tar.gz</filename>
+ or <filename>scons-2.0.0.final.0.zip</filename>,
which are available from the SCons download page at
<ulink url="http://www.scons.org/download.html">http://www.scons.org/download.html</ulink>.
@@ -395,7 +384,7 @@
on Linux or UNIX,
or <application>WinZip</application> on Windows.
This will create a directory called
- <filename>scons-1.3.0</filename>,
+ <filename>scons-2.0.0.final.0</filename>,
usually in your local directory.
Then change your working directory to that directory
and install &SCons; by executing the following commands:
@@ -403,7 +392,7 @@
</para>
<screen>
- # <userinput>cd scons-1.3.0</userinput>
+ # <userinput>cd scons-2.0.0.final.0</userinput>
# <userinput>python setup.py install</userinput>
</screen>
@@ -471,9 +460,9 @@
This will install the &SCons; build engine
in the
- <filename>/usr/lib/scons-1.3.0</filename>
+ <filename>/usr/lib/scons-2.0.0.final.0</filename>
or
- <filename>C:\Python25\scons-1.3.0</filename>
+ <filename>C:\Python25\scons-2.0.0.final.0</filename>
directory, for example.
</para>
@@ -530,7 +519,7 @@
relative to the specified prefix.
Adding <option>--version-lib</option> to the
above example would install the build engine in
- <filename>/opt/scons/lib/scons-1.3.0</filename>.
+ <filename>/opt/scons/lib/scons-2.0.0.final.0</filename>.
</para>
diff --git a/doc/user/build-install.xml b/doc/user/build-install.xml
index 577c140..05ead9d 100644
--- a/doc/user/build-install.xml
+++ b/doc/user/build-install.xml
@@ -111,17 +111,6 @@
<para>
- (Note that the <option>-V</option> option
- was added to Python version 2.0,
- so if your system only has an earlier version available
- you may see an
- <literal>"Unknown option: -V"</literal>
- error message.)
-
- </para>
-
- <para>
-
The standard location for information
about downloading and installing Python is
<ulink url="http://www.python.org/download/">http://www.python.org/download/</ulink>.
@@ -132,10 +121,10 @@
<para>
- &SCons; will work with any version of Python from 1.5.2 or later.
+ &SCons; will work with any version of Python from 2.4 or later.
If you need to install Python and have a choice,
- we recommend using the most recent Python 2.5 version available.
- Python 2.5 has significant improvements
+ we recommend using the most recent Python version available.
+ Newer Pythons have significant improvements
that help speed up the performance of &SCons;.
</para>
@@ -209,7 +198,7 @@
</para>
<screen>
- # <userinput>rpm -Uvh scons-1.3.0-1.noarch.rpm</userinput>
+ # <userinput>rpm -Uvh scons-2.0.0.final.0-1.noarch.rpm</userinput>
</screen>
<para>
@@ -271,7 +260,7 @@
&SCons; provides a Windows installer
that makes installation extremely easy.
- Download the <filename>scons-1.3.0.win32.exe</filename>
+ Download the <filename>scons-2.0.0.final.0.win32.exe</filename>
file from the &SCons; download page at
<ulink url="http://www.scons.org/download.php">http://www.scons.org/download.php</ulink>.
Then all you need to do is execute the file
@@ -381,8 +370,8 @@
<para>
The first step is to download either the
- <filename>scons-1.3.0.tar.gz</filename>
- or <filename>scons-1.3.0.zip</filename>,
+ <filename>scons-2.0.0.final.0.tar.gz</filename>
+ or <filename>scons-2.0.0.final.0.zip</filename>,
which are available from the SCons download page at
<ulink url="http://www.scons.org/download.html">http://www.scons.org/download.html</ulink>.
@@ -395,7 +384,7 @@
on Linux or UNIX,
or <application>WinZip</application> on Windows.
This will create a directory called
- <filename>scons-1.3.0</filename>,
+ <filename>scons-2.0.0.final.0</filename>,
usually in your local directory.
Then change your working directory to that directory
and install &SCons; by executing the following commands:
@@ -403,7 +392,7 @@
</para>
<screen>
- # <userinput>cd scons-1.3.0</userinput>
+ # <userinput>cd scons-2.0.0.final.0</userinput>
# <userinput>python setup.py install</userinput>
</screen>
@@ -471,9 +460,9 @@
This will install the &SCons; build engine
in the
- <filename>/usr/lib/scons-1.3.0</filename>
+ <filename>/usr/lib/scons-2.0.0.final.0</filename>
or
- <filename>C:\Python25\scons-1.3.0</filename>
+ <filename>C:\Python25\scons-2.0.0.final.0</filename>
directory, for example.
</para>
@@ -530,7 +519,7 @@
relative to the specified prefix.
Adding <option>--version-lib</option> to the
above example would install the build engine in
- <filename>/opt/scons/lib/scons-1.3.0</filename>.
+ <filename>/opt/scons/lib/scons-2.0.0.final.0</filename>.
</para>
diff --git a/doc/user/builders-built-in.in b/doc/user/builders-built-in.in
index 2c3045b..f7da806 100644
--- a/doc/user/builders-built-in.in
+++ b/doc/user/builders-built-in.in
@@ -838,19 +838,6 @@
<scons_output_command>scons -Q .</scons_output_command>
</scons_output>
- <para>
-
- If you're using Python version 1.5.2 to run &SCons;,
- then &SCons; will try to use an external
- &zip; program as follows:
-
- </para>
-
- <screen>
- % <userinput>scons -Q .</userinput>
- zip /home/my/project/zip.out file1 file2
- </screen>
-
</section>
</section>
diff --git a/doc/user/builders-built-in.xml b/doc/user/builders-built-in.xml
index a947f8b..3d47f5c 100644
--- a/doc/user/builders-built-in.xml
+++ b/doc/user/builders-built-in.xml
@@ -812,19 +812,6 @@
zip(["out.zip"], ["file1", "file2"])
</screen>
- <para>
-
- If you're using Python version 1.5.2 to run &SCons;,
- then &SCons; will try to use an external
- &zip; program as follows:
-
- </para>
-
- <screen>
- % <userinput>scons -Q .</userinput>
- zip /home/my/project/zip.out file1 file2
- </screen>
-
</section>
</section>
diff --git a/doc/user/builders-writing.in b/doc/user/builders-writing.in
index fda83cd..0bf6971 100644
--- a/doc/user/builders-writing.in
+++ b/doc/user/builders-writing.in
@@ -129,7 +129,7 @@ This functionality could be invoked as in the following example:
</para>
<programlisting>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
</programlisting>
<para>
@@ -165,7 +165,7 @@ This functionality could be invoked as in the following example:
<scons_example name="ex1">
<file name="SConstruct">
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env = Environment(BUILDERS = {'Foo' : bld})
import os
env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
@@ -180,7 +180,7 @@ This functionality could be invoked as in the following example:
</scons_example>
<sconstruct>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env = Environment(BUILDERS = {'Foo' : bld})
</sconstruct>
@@ -276,7 +276,7 @@ This functionality could be invoked as in the following example:
env = Environment()
import os
env['ENV']['PATH'] = env['ENV']['PATH'] + os.pathsep + os.getcwd()
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env.Append(BUILDERS = {'Foo' : bld})
env.Foo('file.foo', 'file.input')
env.Program('hello.c')
@@ -294,7 +294,7 @@ This functionality could be invoked as in the following example:
<sconstruct>
env = Environment()
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env.Append(BUILDERS = {'Foo' : bld})
env.Foo('file.foo', 'file.input')
env.Program('hello.c')
@@ -309,7 +309,7 @@ This functionality could be invoked as in the following example:
<sconstruct>
env = Environment()
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env['BUILDERS']['Foo'] = bld
env.Foo('file.foo', 'file.input')
env.Program('hello.c')
@@ -352,7 +352,7 @@ This functionality could be invoked as in the following example:
<scons_example name="ex4">
<file name="SConstruct">
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET',
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input')
env = Environment(BUILDERS = {'Foo' : bld})
@@ -373,7 +373,7 @@ This functionality could be invoked as in the following example:
</scons_example>
<sconstruct>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET',
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input')
env = Environment(BUILDERS = {'Foo' : bld})
@@ -544,7 +544,7 @@ This functionality could be invoked as in the following example:
<programlisting>
def generate_actions(source, target, env, for_signature):
- return 'foobuild < %s > %s' % (target[0], source[0])
+ return 'foobuild &lt; %s &gt; %s' % (target[0], source[0])
</programlisting>
<para>
@@ -647,7 +647,7 @@ This functionality could be invoked as in the following example:
<scons_example name="ex6">
<file name="SConstruct">
def generate_actions(source, target, env, for_signature):
- return 'foobuild < %s > %s' % (source[0], target[0])
+ return 'foobuild &lt; %s &gt; %s' % (source[0], target[0])
bld = Builder(generator = generate_actions,
suffix = '.foo',
src_suffix = '.input')
@@ -666,7 +666,7 @@ This functionality could be invoked as in the following example:
<sconstruct>
def generate_actions(source, target, env, for_signature):
- return 'foobuild < %s > %s' % (source[0], target[0])
+ return 'foobuild &lt; %s &gt; %s' % (source[0], target[0])
bld = Builder(generator = generate_actions,
suffix = '.foo',
src_suffix = '.input')
@@ -790,7 +790,7 @@ This functionality could be invoked as in the following example:
<scons_example name="MY_EMITTER">
<file name="SConstruct" printme="1">
- bld = Builder(action = 'my_command $SOURCES > $TARGET',
+ bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input',
emitter = '$MY_EMITTER')
@@ -828,7 +828,7 @@ This functionality could be invoked as in the following example:
</scons_example>
<sconstruct>
- bld = Builder(action = 'my_command $SOURCES > $TARGET',
+ bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input',
emitter = '$MY_EMITTER')
@@ -934,8 +934,8 @@ This functionality could be invoked as in the following example:
<file name="site_scons/site_init.py" printme=1>
def TOOL_ADD_HEADER(env):
"""A Tool to add a header from $HEADER to the source file"""
- add_header = Builder(action=['echo "$HEADER" > $TARGET',
- 'cat $SOURCE >> $TARGET'])
+ add_header = Builder(action=['echo "$HEADER" &gt; $TARGET',
+ 'cat $SOURCE &gt;&gt; $TARGET'])
env.Append(BUILDERS = {'AddHeader' : add_header})
env['HEADER'] = '' # set default value
</file>
diff --git a/doc/user/builders-writing.xml b/doc/user/builders-writing.xml
index 5c01934..f364e27 100644
--- a/doc/user/builders-writing.xml
+++ b/doc/user/builders-writing.xml
@@ -166,7 +166,7 @@ This functionality could be invoked as in the following example:
<programlisting>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env = Environment(BUILDERS = {'Foo' : bld})
</programlisting>
@@ -233,7 +233,7 @@ This functionality could be invoked as in the following example:
<screen>
% <userinput>scons -Q</userinput>
- AttributeError: SConsEnvironment instance has no attribute 'Program':
+ AttributeError: 'SConsEnvironment' object has no attribute 'Program':
File "/home/my/project/SConstruct", line 4:
env.Program('hello.c')
</screen>
@@ -251,7 +251,7 @@ This functionality could be invoked as in the following example:
<programlisting>
env = Environment()
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env.Append(BUILDERS = {'Foo' : bld})
env.Foo('file.foo', 'file.input')
env.Program('hello.c')
@@ -266,7 +266,7 @@ This functionality could be invoked as in the following example:
<programlisting>
env = Environment()
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET')
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET')
env['BUILDERS']['Foo'] = bld
env.Foo('file.foo', 'file.input')
env.Program('hello.c')
@@ -313,7 +313,7 @@ This functionality could be invoked as in the following example:
<programlisting>
- bld = Builder(action = 'foobuild < $SOURCE > $TARGET',
+ bld = Builder(action = 'foobuild &lt; $SOURCE &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input')
env = Environment(BUILDERS = {'Foo' : bld})
@@ -586,7 +586,7 @@ This functionality could be invoked as in the following example:
<programlisting>
def generate_actions(source, target, env, for_signature):
- return 'foobuild < %s > %s' % (source[0], target[0])
+ return 'foobuild &lt; %s &gt; %s' % (source[0], target[0])
bld = Builder(generator = generate_actions,
suffix = '.foo',
src_suffix = '.input')
@@ -708,7 +708,7 @@ This functionality could be invoked as in the following example:
</programlisting>
<programlisting>
- bld = Builder(action = 'my_command $SOURCES > $TARGET',
+ bld = Builder(action = 'my_command $SOURCES &gt; $TARGET',
suffix = '.foo',
src_suffix = '.input',
emitter = '$MY_EMITTER')
diff --git a/doc/user/command-line.in b/doc/user/command-line.in
index d910546..cd5ead6 100644
--- a/doc/user/command-line.in
+++ b/doc/user/command-line.in
@@ -943,8 +943,8 @@
These older names still work,
and you may encounter them in older
&SConscript; fles,
- but their use is discouraged
- and will be officially deprecated some day.
+ but they have been officially deprecated
+ as of &SCons; version 2.0.
</para>
@@ -1237,7 +1237,7 @@
choices to a specific set of allowed colors.
This can be set up quite easily
using the &EnumVariable;,
- which takes a list of &allowed_values
+ which takes a list of &allowed_values;
in addition to the variable name,
default value,
and help text arguments:
@@ -2154,7 +2154,7 @@
&SCons; supports a &DEFAULT_TARGETS; variable
that lets you get at the current list of default targets.
- The &DEFAULT_TARGETS variable has
+ The &DEFAULT_TARGETS; variable has
two important differences from the &COMMAND_LINE_TARGETS; variable.
First, the &DEFAULT_TARGETS; variable is a list of
internal &SCons; nodes,
diff --git a/doc/user/command-line.xml b/doc/user/command-line.xml
index 21b52dd..8bc72bb 100644
--- a/doc/user/command-line.xml
+++ b/doc/user/command-line.xml
@@ -926,8 +926,8 @@
These older names still work,
and you may encounter them in older
&SConscript; fles,
- but their use is discouraged
- and will be officially deprecated some day.
+ but they have been officially deprecated
+ as of &SCons; version 2.0.
</para>
@@ -1208,7 +1208,7 @@
choices to a specific set of allowed colors.
This can be set up quite easily
using the &EnumVariable;,
- which takes a list of &allowed_values
+ which takes a list of &allowed_values;
in addition to the variable name,
default value,
and help text arguments:
@@ -2064,7 +2064,7 @@
&SCons; supports a &DEFAULT_TARGETS; variable
that lets you get at the current list of default targets.
- The &DEFAULT_TARGETS variable has
+ The &DEFAULT_TARGETS; variable has
two important differences from the &COMMAND_LINE_TARGETS; variable.
First, the &DEFAULT_TARGETS; variable is a list of
internal &SCons; nodes,
diff --git a/doc/user/depends.in b/doc/user/depends.in
index 213713f..69bb242 100644
--- a/doc/user/depends.in
+++ b/doc/user/depends.in
@@ -672,13 +672,14 @@
&SCons; still supports two functions that used to be the
primary methods for configuring the
decision about whether or not an input file has changed.
- Although they're not officially deprecated yet,
- their use is discouraged,
+ These functions have been officially deprecated
+ as &SCons; version 2.0,
+ and their use is discouraged,
mainly because they rely on a somewhat
confusing distinction between how
source files and target files are handled.
These functions are documented here mainly in case you
- encounter them in existing &SConscript; files.
+ encounter them in older &SConscript; files.
</para>
diff --git a/doc/user/depends.xml b/doc/user/depends.xml
index d386a1f..430e64a 100644
--- a/doc/user/depends.xml
+++ b/doc/user/depends.xml
@@ -661,13 +661,14 @@
&SCons; still supports two functions that used to be the
primary methods for configuring the
decision about whether or not an input file has changed.
- Although they're not officially deprecated yet,
- their use is discouraged,
+ These functions have been officially deprecated
+ as &SCons; version 2.0,
+ and their use is discouraged,
mainly because they rely on a somewhat
confusing distinction between how
source files and target files are handled.
These functions are documented here mainly in case you
- encounter them in existing &SConscript; files.
+ encounter them in older &SConscript; files.
</para>
diff --git a/doc/user/environments.in b/doc/user/environments.in
index dfe98f2..9ce5568 100644
--- a/doc/user/environments.in
+++ b/doc/user/environments.in
@@ -672,11 +672,8 @@ environment, of directory names, suffixes, etc.
<sconstruct>
env = Environment()
- dict = env.Dictionary()
- keys = dict.keys()
- keys.sort()
- for key in keys:
- print "construction variable = '%s', value = '%s'" % (key, dict[key])
+ for item in sorted(env.Dictionary().items()):
+ print "construction variable = '%s', value = '%s'" % item
</sconstruct>
</section>
@@ -775,6 +772,82 @@ environment, of directory names, suffixes, etc.
</section>
<section>
+ <title>Handling Problems With Value Expansion</title>
+
+ <para>
+
+ If a problem occurs when expanding a construction variable,
+ by default it is expanded to <literal>''</literal>
+ (a null string), and will not cause scons to fail.
+
+ <scons_example name="missing1">
+ <file name="SConstruct" printme="1">
+ env = Environment()
+ print "value is:", env.subst( '->$MISSING<-' )
+ </file>
+ </scons_example>
+
+ <scons_output example="missing1">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
+
+ This default behaviour can be changed using the &AllowSubstExceptions;
+ function.
+ When a problem occurs with a variable expansion it generates
+ an exception, and the &AllowSubstExceptions; function controls
+ which of these exceptions are actually fatal and which are
+ allowed to occur safely. By default, &NameError; and &IndexError;
+ are the two exceptions that are allowed to occur: so instead of
+ causing scons to fail, these are caught, the variable expanded to
+ <literal>''</literal>
+ and scons execution continues.
+ To require that all construction variable names exist, and that
+ indexes out of range are not allowed, call &AllowSubstExceptions;
+ with no extra arguments.
+ </para>
+
+ <scons_example name="missing2">
+ <file name="SConstruct" printme="1">
+ AllowSubstExceptions()
+ env = Environment()
+ print "value is:", env.subst( '->$MISSING<-' )
+ </file>
+ </scons_example>
+
+ <scons_output example="missing2">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
+
+ <para>
+ This can also be used to allow other exceptions that might occur,
+ most usefully with the <literal>${...}</literal> construction
+ variable syntax. For example, this would allow zero-division to
+ occur in a variable expansion in addition to the default exceptions
+ allowed
+ </para>
+
+ <scons_example name="missing3">
+ <file name="SConstruct" printme="1">
+ AllowSubstExceptions(IndexError, NameError, ZeroDivisionError)
+ env = Environment()
+ print "value is:", env.subst( '->${1 / 0}<-' )
+ </file>
+ </scons_example>
+
+ <scons_output example="missing3">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
+ <sconstruct>
+ </sconstruct>
+
+ <para>
+ If &AllowSubstExceptions; is called multiple times, each call
+ completely overwrites the previous list of allowed exceptions.
+ </para>
+
+ </section>
+
+ <section>
<title>Controlling the Default &ConsEnv;: the &DefaultEnvironment; Function</title>
<para>
@@ -1556,11 +1629,10 @@ environment, of directory names, suffixes, etc.
#!/usr/bin/env python
import os
import sys
- if len(sys.argv) > 1:
+ if len(sys.argv) &gt; 1:
keys = sys.argv[1:]
else:
- keys = os.environ.keys()
- keys.sort()
+ keys = sorted(os.environ.keys())
for key in keys:
print " " + key + "=" + os.environ[key]
</file>
diff --git a/doc/user/environments.xml b/doc/user/environments.xml
index fafb120..5bb1089 100644
--- a/doc/user/environments.xml
+++ b/doc/user/environments.xml
@@ -672,11 +672,8 @@ environment, of directory names, suffixes, etc.
<programlisting>
env = Environment()
- dict = env.Dictionary()
- keys = dict.keys()
- keys.sort()
- for key in keys:
- print "construction variable = '%s', value = '%s'" % (key, dict[key])
+ for item in sorted(env.Dictionary().items()):
+ print "construction variable = '%s', value = '%s'" % item
</programlisting>
</section>
@@ -775,6 +772,83 @@ environment, of directory names, suffixes, etc.
</section>
<section>
+ <title>Handling Problems With Value Expansion</title>
+
+ <para>
+
+ If a problem occurs when expanding a construction variable,
+ by default it is expanded to <literal>''</literal>
+ (a null string), and will not cause scons to fail.
+
+ <programlisting>
+ env = Environment()
+ print "value is:", env.subst( '-&gt;$MISSING&lt;-' )
+ </programlisting>
+
+ <screen>
+ % <userinput>scons -Q</userinput>
+ value is: -&gt;&lt;-
+ scons: `.' is up to date.
+ </screen>
+
+ This default behaviour can be changed using the &AllowSubstExceptions;
+ function.
+ When a problem occurs with a variable expansion it generates
+ an exception, and the &AllowSubstExceptions; function controls
+ which of these exceptions are actually fatal and which are
+ allowed to occur safely. By default, &NameError; and &IndexError;
+ are the two exceptions that are allowed to occur: so instead of
+ causing scons to fail, these are caught, the variable expanded to
+ <literal>''</literal>
+ and scons execution continues.
+ To require that all construction variable names exist, and that
+ indexes out of range are not allowed, call &AllowSubstExceptions;
+ with no extra arguments.
+ </para>
+
+ <programlisting>
+ AllowSubstExceptions()
+ env = Environment()
+ print "value is:", env.subst( '-&gt;$MISSING&lt;-' )
+ </programlisting>
+
+ <screen>
+ % <userinput>scons -Q</userinput>
+ value is:
+ scons: *** NameError `MISSING' trying to evaluate `$MISSING'
+ File "/home/my/project/SConstruct", line 3, in &lt;module&gt;
+ </screen>
+
+ <para>
+ This can also be used to allow other exceptions that might occur,
+ most usefully with the <literal>${...}</literal> construction
+ variable syntax. For example, this would allow zero-division to
+ occur in a variable expansion in addition to the default exceptions
+ allowed
+ </para>
+
+ <programlisting>
+ AllowSubstExceptions(IndexError, NameError, ZeroDivisionError)
+ env = Environment()
+ print "value is:", env.subst( '-&gt;${1 / 0}&lt;-' )
+ </programlisting>
+
+ <screen>
+ % <userinput>scons -Q</userinput>
+ value is: -&gt;&lt;-
+ scons: `.' is up to date.
+ </screen>
+ <programlisting>
+ </programlisting>
+
+ <para>
+ If &AllowSubstExceptions; is called multiple times, each call
+ completely overwrites the previous list of allowed exceptions.
+ </para>
+
+ </section>
+
+ <section>
<title>Controlling the Default &ConsEnv;: the &DefaultEnvironment; Function</title>
<para>
@@ -1543,11 +1617,10 @@ environment, of directory names, suffixes, etc.
#!/usr/bin/env python
import os
import sys
- if len(sys.argv) > 1:
+ if len(sys.argv) &gt; 1:
keys = sys.argv[1:]
else:
- keys = os.environ.keys()
- keys.sort()
+ keys = sorted(os.environ.keys())
for key in keys:
print " " + key + "=" + os.environ[key]
</file>
diff --git a/doc/user/less-simple.in b/doc/user/less-simple.in
index 4cd00e9..cccad83 100644
--- a/doc/user/less-simple.in
+++ b/doc/user/less-simple.in
@@ -371,7 +371,7 @@
you'll have realized that this is similar to the
<function>split()</function> method
in the Python standard <function>string</function> module.
- Unlike the <function>string.split()</function> method,
+ Unlike the <function>split()</function> member function of strings,
however, the &Split; function
does not require a string as input
and will wrap up a single non-string object in a list,
diff --git a/doc/user/less-simple.xml b/doc/user/less-simple.xml
index 17ce181..24b45e6 100644
--- a/doc/user/less-simple.xml
+++ b/doc/user/less-simple.xml
@@ -360,7 +360,7 @@
you'll have realized that this is similar to the
<function>split()</function> method
in the Python standard <function>string</function> module.
- Unlike the <function>string.split()</function> method,
+ Unlike the <function>split()</function> member function of strings,
however, the &Split; function
does not require a string as input
and will wrap up a single non-string object in a list,
diff --git a/doc/user/main.in b/doc/user/main.in
index be4fd21..fbc28df 100644
--- a/doc/user/main.in
+++ b/doc/user/main.in
@@ -96,14 +96,7 @@
<!--
- XXX FindFile()
- XXX FindPathDirs()
- XXX GetBuildPath()
- XXX GetLaunchDir()
-
- XXX ParseDepends()
XXX Platform()
- XXX SConsignFile()
XXX Tools()
XXX GetOption('duplicate')
@@ -129,10 +122,10 @@
<edition>Revision &buildrevision; (&builddate;)</edition>
- <pubdate>2004, 2005, 2006, 2007, 2008</pubdate>
+ <pubdate>2004, 2005, 2006, 2007, 2008, 2009, 2010</pubdate>
<copyright>
- <year>2004, 2005, 2006, 2007, 2008</year>
+ <year>2004, 2005, 2006, 2007, 2008, 2009, 2010</year>
<holder>Steven Knight</holder>
</copyright>
diff --git a/doc/user/main.xml b/doc/user/main.xml
index be4fd21..00b8268 100644
--- a/doc/user/main.xml
+++ b/doc/user/main.xml
@@ -96,14 +96,7 @@
<!--
- XXX FindFile()
- XXX FindPathDirs()
- XXX GetBuildPath()
- XXX GetLaunchDir()
-
- XXX ParseDepends()
XXX Platform()
- XXX SConsignFile()
XXX Tools()
XXX GetOption('duplicate')
diff --git a/doc/user/misc.in b/doc/user/misc.in
index 3116fd3..87b5db4 100644
--- a/doc/user/misc.in
+++ b/doc/user/misc.in
@@ -36,10 +36,10 @@
<para>
Although the &SCons; code itself will run
- on any Python version 1.5.2 or later,
+ on any Python version 2.4 or later,
you are perfectly free to make use of
Python syntax and modules from more modern versions
- (for example, Python 2.4 or 2.5)
+ (for example, Python 2.5 or 2.6)
when writing your &SConscript; files
or your own local modules.
If you do this, it's usually helpful to
diff --git a/doc/user/misc.xml b/doc/user/misc.xml
index 043b5a2..f79f1cc 100644
--- a/doc/user/misc.xml
+++ b/doc/user/misc.xml
@@ -36,10 +36,10 @@
<para>
Although the &SCons; code itself will run
- on any Python version 1.5.2 or later,
+ on any Python version 2.4 or later,
you are perfectly free to make use of
Python syntax and modules from more modern versions
- (for example, Python 2.4 or 2.5)
+ (for example, Python 2.5 or 2.6)
when writing your &SConscript; files
or your own local modules.
If you do this, it's usually helpful to
@@ -253,7 +253,7 @@
<screen>
% <userinput>scons -Q</userinput>
None
- SCons.Node.FS.File exists
+ &lt;class 'SCons.Node.FS.File'&gt; exists
scons: `.' is up to date.
</screen>
diff --git a/doc/user/nodes.in b/doc/user/nodes.in
index e583ea9..c65a2ad 100644
--- a/doc/user/nodes.in
+++ b/doc/user/nodes.in
@@ -332,6 +332,51 @@
</section>
+ <section>
+ <title>&GetBuildPath;: Getting the Path From a &Node; or String</title>
+
+ <para>
+
+ <function>env.GetBuildPath(file_or_list)</function>
+ returns the path of a &Node; or a string representing a
+ path. It can also take a list of &Node;s and/or strings, and
+ returns the list of paths. If passed a single &Node;, the result
+ is the same as calling <literal>str(node)</literal> (see above).
+ The string(s) can have embedded construction variables, which are
+ expanded as usual, using the calling environment's set of
+ variables. The paths can be files or directories, and do not have
+ to exist.
+
+ </para>
+
+ <scons_example name="GetBuildPath">
+ <file name="SConstruct" printme="1">
+ env=Environment(VAR="value")
+ n=File("foo.c")
+ print env.GetBuildPath([n, "sub/dir/$VAR"])
+ </file>
+ </scons_example>
+
+ <para>
+
+ Would print the following file names:
+
+ </para>
+
+ <scons_output example="GetBuildPath" os="posix">
+ <scons_output_command>scons -Q</scons_output_command>
+ </scons_output>
+
+ <para>
+
+ There is also a function version of &GetBuildPath; which can
+ be called without an &Environment;; that uses the default SCons
+ &Environment; to do substitution on any string arguments.
+
+ </para>
+
+ </section>
+
<!--
<section>
diff --git a/doc/user/nodes.xml b/doc/user/nodes.xml
index 8192442..71ac7c1 100644
--- a/doc/user/nodes.xml
+++ b/doc/user/nodes.xml
@@ -335,6 +335,51 @@
</section>
+ <section>
+ <title>&GetBuildPath;: Getting the Path From a &Node; or String</title>
+
+ <para>
+
+ <function>env.GetBuildPath(file_or_list)</function>
+ returns the path of a &Node; or a string representing a
+ path. It can also take a list of &Node;s and/or strings, and
+ returns the list of paths. If passed a single &Node;, the result
+ is the same as calling <literal>str(node)</literal> (see above).
+ The string(s) can have embedded construction variables, which are
+ expanded as usual, using the calling environment's set of
+ variables. The paths can be files or directories, and do not have
+ to exist.
+
+ </para>
+
+ <programlisting>
+ env=Environment(VAR="value")
+ n=File("foo.c")
+ print env.GetBuildPath([n, "sub/dir/$VAR"])
+ </programlisting>
+
+ <para>
+
+ Would print the following file names:
+
+ </para>
+
+ <screen>
+ % <userinput>scons -Q</userinput>
+ ['foo.c', 'sub/dir/value']
+ scons: `.' is up to date.
+ </screen>
+
+ <para>
+
+ There is also a function version of &GetBuildPath; which can
+ be called without an &Environment;; that uses the default SCons
+ &Environment; to do substitution on any string arguments.
+
+ </para>
+
+ </section>
+
<!--
<section>
diff --git a/doc/user/parseflags.in b/doc/user/parseflags.in
index d65e5b8..2f4bea5 100644
--- a/doc/user/parseflags.in
+++ b/doc/user/parseflags.in
@@ -61,9 +61,7 @@
<file name="SConstruct" printme="1">
env = Environment()
d = env.ParseFlags("-I/opt/include -L/opt/lib -lfoo")
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -102,9 +100,7 @@
<file name="SConstruct" printme="1">
env = Environment()
d = env.ParseFlags("-whatever")
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -130,9 +126,7 @@
<file name="SConstruct" printme="1">
env = Environment()
d = env.ParseFlags(["-I/opt/include", ["-L/opt/lib", "-lfoo"]])
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -159,9 +153,7 @@
<file name="SConstruct" printme="1">
env = Environment()
d = env.ParseFlags(["!echo -I/opt/include", "!echo -L/opt/lib", "-lfoo"])
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
diff --git a/doc/user/parseflags.xml b/doc/user/parseflags.xml
index c477c98..fd15de7 100644
--- a/doc/user/parseflags.xml
+++ b/doc/user/parseflags.xml
@@ -60,9 +60,7 @@
<programlisting>
env = Environment()
d = env.ParseFlags("-I/opt/include -L/opt/lib -lfoo")
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -106,9 +104,7 @@
<programlisting>
env = Environment()
d = env.ParseFlags("-whatever")
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -132,9 +128,7 @@
<programlisting>
env = Environment()
d = env.ParseFlags(["-I/opt/include", ["-L/opt/lib", "-lfoo"]])
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
@@ -161,9 +155,7 @@
<programlisting>
env = Environment()
d = env.ParseFlags(["!echo -I/opt/include", "!echo -L/opt/lib", "-lfoo"])
- l = d.items()
- l.sort()
- for k,v in l:
+ for k,v in sorted(d.items()):
if v:
print k, v
env.MergeFlags(d)
diff --git a/doc/user/scanners.in b/doc/user/scanners.in
index 1c7ee7e..db3170a 100644
--- a/doc/user/scanners.in
+++ b/doc/user/scanners.in
@@ -329,3 +329,53 @@ over the file scanning rather than being called for each input line:
-->
</section>
+
+ <section>
+ <title>Adding a search path to a scanner: &FindPathDirs;</title>
+
+ <para>
+
+ Many scanners need to search for included files or dependencies
+ using a path variable; this is how &cv-link-CPPPATH; and
+ &cv-link-LIBPATH; work. The path to search is passed to your
+ scanner as the <literal>path</literal> argument. Path variables
+ may be lists of nodes, semicolon-separated strings, or even
+ contain SCons variables which need to be expanded. Fortunately,
+ &SCons; provides the &FindPathDirs; function which itself returns
+ a function to expand a given path (given as a SCons construction
+ variable name) to a list of paths at the time the scanner is
+ called. Deferring evaluation until that point allows, for
+ instance, the path to contain $TARGET references which differ for
+ each file scanned.
+
+ </para>
+
+ <para>
+
+ Using &FindPathDirs; is quite easy. Continuing the above example,
+ using KPATH as the construction variable with the search path
+ (analogous to &cv-link-CPPPATH;), we just modify the &Scanner;
+ constructor call to include a path keyword arg:
+
+ </para>
+
+ <scons_example name="findpathdirs">
+ <file name="SConstruct" printme="1">
+ kscan = Scanner(function = kfile_scan,
+ skeys = ['.k'],
+ path=FindPathDirs('KPATH'))
+ </file>
+ </scons_example>
+
+ <para>
+
+ FindPathDirs returns a callable object that, when called, will
+ essentially expand the elements in env['KPATH'] and tell the
+ scanner to search in those dirs. It will also properly add
+ related repository and variant dirs to the search list. As a side
+ note, the returned method stores the path in an efficient way so
+ lookups are fast even when variable substitutions may be needed.
+ This is important since many files get scanned in a typical build.
+
+ </para>
+ </section>
diff --git a/doc/user/scanners.xml b/doc/user/scanners.xml
index 7921577..2aba7d2 100644
--- a/doc/user/scanners.xml
+++ b/doc/user/scanners.xml
@@ -315,3 +315,51 @@ over the file scanning rather than being called for each input line:
-->
</section>
+
+ <section>
+ <title>Adding a search path to a scanner: &FindPathDirs;</title>
+
+ <para>
+
+ Many scanners need to search for included files or dependencies
+ using a path variable; this is how &cv-link-CPPPATH; and
+ &cv-link-LIBPATH; work. The path to search is passed to your
+ scanner as the <literal>path</literal> argument. Path variables
+ may be lists of nodes, semicolon-separated strings, or even
+ contain SCons variables which need to be expanded. Fortunately,
+ &SCons; provides the &FindPathDirs; function which itself returns
+ a function to expand a given path (given as a SCons construction
+ variable name) to a list of paths at the time the scanner is
+ called. Deferring evaluation until that point allows, for
+ instance, the path to contain $TARGET references which differ for
+ each file scanned.
+
+ </para>
+
+ <para>
+
+ Using &FindPathDirs; is quite easy. Continuing the above example,
+ using KPATH as the construction variable with the search path
+ (analogous to &cv-link-CPPPATH;), we just modify the &Scanner;
+ constructor call to include a path keyword arg:
+
+ </para>
+
+ <programlisting>
+ kscan = Scanner(function = kfile_scan,
+ skeys = ['.k'],
+ path=FindPathDirs('KPATH'))
+ </programlisting>
+
+ <para>
+
+ FindPathDirs returns a callable object that, when called, will
+ essentially expand the elements in env['KPATH'] and tell the
+ scanner to search in those dirs. It will also properly add
+ related repository and variant dirs to the search list. As a side
+ note, the returned method stores the path in an efficient way so
+ lookups are fast even when variable substitutions may be needed.
+ This is important since many files get scanned in a typical build.
+
+ </para>
+ </section>
diff --git a/doc/user/tasks.in b/doc/user/tasks.in
index fd87bd2..2945d1c 100644
--- a/doc/user/tasks.in
+++ b/doc/user/tasks.in
@@ -53,15 +53,6 @@ filename = os.path.splitext(filename)[0]+extension
import os.path
filenames = [os.path.join(prefix, x) for x in filenames]
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import os.path
-new_filenames = []
-for x in filenames:
- new_filenames.append(os.path.join(prefix, x))
-</programlisting>
</example>
<example>
@@ -70,14 +61,6 @@ for x in filenames:
if filename.find(old_prefix) == 0:
filename = filename.replace(old_prefix, new_prefix)
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import string
-if string.find(filename, old_prefix) == 0:
- filename = string.replace(filename, old_prefix, new_prefix)
-</programlisting>
</example>
<example>
@@ -87,16 +70,6 @@ of extensions</title>
import os.path
filenames = [x for x in filenames if os.path.splitext(x)[1] in extensions]
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import os.path
-new_filenames = []
-for x in filenames:
- if os.path.splitext(x)[1] in extensions:
- new_filenames.append(x)
-</programlisting>
</example>
<example>
diff --git a/doc/user/tasks.xml b/doc/user/tasks.xml
index fd87bd2..2945d1c 100644
--- a/doc/user/tasks.xml
+++ b/doc/user/tasks.xml
@@ -53,15 +53,6 @@ filename = os.path.splitext(filename)[0]+extension
import os.path
filenames = [os.path.join(prefix, x) for x in filenames]
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import os.path
-new_filenames = []
-for x in filenames:
- new_filenames.append(os.path.join(prefix, x))
-</programlisting>
</example>
<example>
@@ -70,14 +61,6 @@ for x in filenames:
if filename.find(old_prefix) == 0:
filename = filename.replace(old_prefix, new_prefix)
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import string
-if string.find(filename, old_prefix) == 0:
- filename = string.replace(filename, old_prefix, new_prefix)
-</programlisting>
</example>
<example>
@@ -87,16 +70,6 @@ of extensions</title>
import os.path
filenames = [x for x in filenames if os.path.splitext(x)[1] in extensions]
</programlisting>
-
-<simpara>or in Python 1.5.2:</simpara>
-
-<programlisting>
-import os.path
-new_filenames = []
-for x in filenames:
- if os.path.splitext(x)[1] in extensions:
- new_filenames.append(x)
-</programlisting>
</example>
<example>
diff --git a/doc/user/troubleshoot.xml b/doc/user/troubleshoot.xml
index 428aa69..468af92 100644
--- a/doc/user/troubleshoot.xml
+++ b/doc/user/troubleshoot.xml
@@ -284,11 +284,11 @@
'.spp',
'.SPP'],
'DSUFFIXES': ['.d'],
- 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
- 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
- 'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'},
+ 'Dir': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
+ 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
+ 'ENV': { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'},
'ESCAPE': &lt;function escape at 0x700000&gt;,
- 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'File': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
'HOST_ARCH': None,
'HOST_OS': None,
'IDLSUFFIXES': ['.idl', '.IDL'],
@@ -304,7 +304,7 @@
'PROGPREFIX': '',
'PROGSUFFIX': '',
'PSPAWN': &lt;function piped_env_spawn at 0x700000&gt;,
- 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
'SCANNERS': [],
'SHELL': 'sh',
'SHLIBPREFIX': '$LIBPREFIX',
@@ -314,7 +314,7 @@
'SPAWN': &lt;function spawnvpe_spawn at 0x700000&gt;,
'TARGET_ARCH': None,
'TARGET_OS': None,
- 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
+ 'TEMPFILE': &lt;class 'SCons.Platform.TempFileMunge'&gt;,
'TEMPFILEPREFIX': '@',
'TOOLS': ['install', 'install'],
'_CPPDEFFLAGS': '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
@@ -341,9 +341,9 @@
<screen>
C:\><userinput>scons</userinput>
scons: Reading SConscript files ...
- { 'BUILDERS': {'_InternalInstall': &lt;function InstallBuilderWrapper at 0x700000&gt;, 'Object': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'PCH': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'RES': &lt;SCons.Builder.BuilderBase instance at 0x700000&gt;, 'SharedObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, 'StaticObject': &lt;SCons.Builder.CompositeBuilder instance at 0x700000&gt;, '_InternalInstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;},
+ { 'BUILDERS': {'_InternalInstall': &lt;function InstallBuilderWrapper at 0x700000&gt;, 'Object': &lt;SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'PCH': &lt;SCons.Builder.BuilderBase object at 0x700000&gt;, 'RES': &lt;SCons.Builder.BuilderBase object at 0x700000&gt;, 'SharedObject': &lt;SCons.Builder.CompositeBuilder object at 0x700000&gt;, 'StaticObject': &lt;SCons.Builder.CompositeBuilder object at 0x700000&gt;, '_InternalInstallAs': &lt;function InstallAsBuilderWrapper at 0x700000&gt;},
'CC': 'cl',
- 'CCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
+ 'CCCOM': &lt;SCons.Action.FunctionAction object at 0x700000&gt;,
'CCFLAGS': ['/nologo'],
'CCPCHFLAGS': ['${(PCH and "/Yu%s /Fp%s"%(PCHSTOP or "",File(PCH))) or ""}'],
'CCPDBFLAGS': ['${(PDB and "/Z7") or ""}'],
@@ -377,13 +377,13 @@
'CXXFILESUFFIX': '.cc',
'CXXFLAGS': ['$(', '/TP', '$)'],
'DSUFFIXES': ['.d'],
- 'Dir': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
- 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'Dir': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
+ 'Dirs': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
'ENV': { 'PATH': 'C:\\WINDOWS\\System32',
'PATHEXT': '.COM;.EXE;.BAT;.CMD',
'SystemRoot': 'C:\\WINDOWS'},
'ESCAPE': &lt;function escape at 0x700000&gt;,
- 'File': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'File': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
'HOST_ARCH': '',
'HOST_OS': 'win32',
'IDLSUFFIXES': ['.idl', '.IDL'],
@@ -405,13 +405,13 @@
'PROGSUFFIX': '.exe',
'PSPAWN': &lt;function piped_spawn at 0x700000&gt;,
'RC': 'rc',
- 'RCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
+ 'RCCOM': &lt;SCons.Action.FunctionAction object at 0x700000&gt;,
'RCFLAGS': [],
'RCSUFFIXES': ['.rc', '.rc2'],
- 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller instance at 0x700000&gt;,
+ 'RDirs': &lt;SCons.Defaults.Variable_Method_Caller object at 0x700000&gt;,
'SCANNERS': [],
'SHCC': '$CC',
- 'SHCCCOM': &lt;SCons.Action.FunctionAction instance at 0x700000&gt;,
+ 'SHCCCOM': &lt;SCons.Action.FunctionAction object at 0x700000&gt;,
'SHCCFLAGS': ['$CCFLAGS'],
'SHCFLAGS': ['$CFLAGS'],
'SHCXX': '$CXX',
@@ -426,7 +426,7 @@
'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1,
'TARGET_ARCH': '',
'TARGET_OS': 'win32',
- 'TEMPFILE': &lt;class SCons.Platform.TempFileMunge at 0x700000&gt;,
+ 'TEMPFILE': &lt;class 'SCons.Platform.TempFileMunge'&gt;,
'TEMPFILEPREFIX': '@',
'TOOLS': ['msvc', 'install', 'install'],
'_CCCOMCOM': '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS',
@@ -489,7 +489,7 @@
<screen>
% <userinput>scons</userinput>
scons: Reading SConscript files ...
- {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}
+ { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
@@ -1118,14 +1118,14 @@
% <userinput>scons -Q --debug=stacktrace</userinput>
scons: *** [prog.o] Source `prog.c' not found, needed by target `prog.o'.
scons: internal stack trace:
- File "bootstrap/src/engine/SCons/Job.py", line 197, in start
+ File "bootstrap/src/engine/SCons/Job.py", line 199, in start
task.prepare()
File "bootstrap/src/engine/SCons/Script/Main.py", line 167, in prepare
return SCons.Taskmaster.OutOfDateTask.prepare(self)
- File "bootstrap/src/engine/SCons/Taskmaster.py", line 190, in prepare
+ File "bootstrap/src/engine/SCons/Taskmaster.py", line 187, in prepare
executor.prepare()
- File "bootstrap/src/engine/SCons/Executor.py", line 397, in prepare
- raise SCons.Errors.StopError, msg % (s, self.batches[0].targets[0])
+ File "bootstrap/src/engine/SCons/Executor.py", line 392, in prepare
+ raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0]))
</screen>
<para>
diff --git a/src/Announce.txt b/src/Announce.txt
new file mode 100644
index 0000000..8b6215d
--- /dev/null
+++ b/src/Announce.txt
@@ -0,0 +1,1060 @@
+
+
+ SCons - a software construction tool
+
+ Release Notes
+
+
+This is SCons, a tool for building software (and other files). SCons is
+implemented in Python, and its "configuration files" are actually Python
+scripts, allowing you to use the full power of a real scripting language
+to solve build problems. You do not, however, need to know Python to
+use SCons effectively.
+
+Please go to http://www.scons.org/download.php to get the latest production
+release of SCons.
+
+So that everyone using SCons can help each other learn how to use it more
+effectively, please go to http://scons.org/lists.php#users to sign up for
+the scons-users mailing list.
+
+
+RELEASE 2.0.0.final.0 - Mon, 14 Jun 2010 22:01:37 -0700
+
+ Please consult the RELEASE.txt file for a summary changes since the last
+ release and consult the CHANGES.txt file for complete a list of changes
+ since last release. This announcement highlights only the important
+ changes.
+
+ IMPORTANT: In 1.3.0 and 2.0.0, explicit dependencies (configured via
+ the Depends() call) are ignored for any nodes that do not have builders.
+ This known issue[1] will typically only happen if you explicitly
+ configure a builder call to create multiple output files, some of which
+ are "hidden" from SCons by not being listed in the targets list, and then
+ use Depends() to establish an explicit dependency on a "hidden" file.
+
+ [1] See http://scons.tigris.org/issues/show_bug.cgi?id=2647 for details.
+
+ Please note the following important changes scheduled for the next
+ release:
+
+ -- FEATURE THAT WILL CHANGE
+
+ Please note the following important changes since release 1.3.0:
+
+ -- SUPPORT FOR PYTHON VERSIONS PRIOR TO 2.4 HAS BEEN REMOVED
+
+ Although SCons is still tested with Python 2.3, use of Python
+ versions prior to 2.4 is deprecated.
+
+ -- DEPRECATED FEATURES WILL GENERATE MANDATORY WARNINGS IN 2.0.0
+
+ In keeping with our deprecation cycle, the following deprecated
+ features will still be supported in 2.0.0 but will generate
+ mandatory, non-disableable warnings:
+
+ -- The overrides= keyword argument to the Builder() call.
+ -- The scanner= keyword argument to the Builder() call.
+ -- The BuildDir() function and env.BuildDir() method.
+ -- The env.Copy() method.
+ -- The SourceSignatures() function and
+ env.SourceSignatures() method.
+ -- The TargetSignatures() function and
+ env.TargetSignatures() method.
+ -- The Sig module (now an unnused stub).
+ -- The --debug=dtree, --debug=stree and --debug=tree options.
+ -- The --debug=nomemoizer option.
+ -- The Options object and the related BoolOption(),
+ EnumOption(), ListOption(), PackageOption() and
+ PathOption() functions.
+
+ The mandatory warnings will be issued in order to make sure
+ users of 1.3.0 notice *prior* to the release of SCons 2.0.0, that
+ these features will be removed. In SCons 2.0.0 these features
+ will no longer work at all, and will instead generate specific
+ fatal errors when anyone tries to use them.
+
+ Please note the following important changes since release 1.2.0:
+
+ -- MICROSOFT VISUAL STUDIO VERSION/ARCH DETECTION HAS CHANGED
+
+ The way SCons detects Visual Studio on Windows has changed in
+ 1.3. By default, it should now use the latest installed
+ Visual Studio version on your machine, and compile for 32 or
+ 64 bits according to whether your OS is 32 or 64 bits (32/64
+ bit python makes no difference).
+
+ Two new variables control Visual Studio: MSVC_VERSION and
+ TARGET_ARCH. These variables ONLY take effect when passed to
+ the Environment() constructor; setting them later has no
+ effect. To use a non-default Visual Studio version, set
+ MSVC_VERSION to e.g. "8.0" or "7.1". Setting it to "xxx" (or
+ any nonexistent value) will make it print out the valid
+ versions on your system. To use a non-default architecture,
+ set TARGET_ARCH to "x86" or "x86_64" (various synonyms are
+ accepted).
+
+ Note that if you use MSVS_VERSION to build Visual Studio
+ projects from your SConstructs, MSVS_VERSION must be set to
+ the same version as MSVC_VERSION.
+
+ Support for HOST_OS,HOST_ARCH,TARGET_OS, TARGET_ARCH has been
+ added to allow specifying different target arch than the host
+ system. This is only supported for Visual Studio/Visual C++
+ at this time.
+
+ -- Support for Latex glossaries and acronyms has been added
+
+ -- VISUAL C/C++ PRECOMPILED HEADERS WILL BE REBUILT
+
+ Precompiled header files built with Visual C/C++ will be
+ rebuilt after upgrading from 1.2.0 to a later release.
+
+ This rebuild is normal and will occur because the command line
+ defined by the $PCHCOM construction variable has had the $CCFLAGS
+ variable added, and has been rearranged to put the "/Fo" output
+ flag towards the beginning of the line, consistent with the
+ related command lines for $CCCOM, $CXXCOM, etc.
+
+ -- CHANGES TO SOME LINKER COMMAND LINES WILL CAUSE RELINKING
+
+ Changes to the command line definitions for the Microsoft link.exe
+ linker, the OS/2 ilink linker and the Phar Lap linkloc linker
+ will cause targets built with those tools be to be rebuilt after
+ upgrading from 1.2.0 to a later release.
+
+ This relink is normal and will occur because the command lines for
+ these tools have been redefined to remove unnecessary nested $(
+ and $) character strings.
+
+ -- MSVS_USE_MFC_DIRS and MSVS_IGNORE_IDE_PATHS are obsoleted and
+ have no effect.
+
+ Please note the following important changes since release 1.1.0:
+
+ -- THE $CHANGED_SOURCES, $CHANGED_TARGETS, $UNCHANGED_SOURCES
+ AND $UNCHANGED_TARGETS VARIABLES WILL BECOME RESERVED
+
+ A future release (probably 1.3.0) will make the construction
+ variable names $CHANGED_SOURCES, $CHANGED_TARGETS,
+ $UNCHANGED_SOURCES and $UNCHANGED_TARGETS into reserved
+ construction variable names controlled by SCons itself (like
+ the current $SOURCE, $TARGETS, etc.).
+
+ Setting these variable names in the current release will generate
+ a warning but still set the variables. When they become reserved
+ variable names, they will generate a different warning message
+ and attempts to set these variables will be ignored.
+
+ SCons configurations that happen to use these variable names
+ should be changed to use different variable names, in order
+ to ensure that the configuration continues to work with future
+ versions of SCons.
+
+ -- THE Options OBJECT AND RELATED FUNCTIONS NOW GENERATE WARNINGS
+
+ Use of the Options object, and related functions BoolOption(),
+ EnumOption(), ListOption(), PackageOption() and PathOption()
+ were announced as deprecated in release 0.98.1. Since then,
+ however, no warning messages were ever implemented for the
+ use of these deprecated functions.
+
+ By default, release 1.2.0 prints warning messages when these
+ deprecated features are used. Warnings about all deprecated
+ features may be suppressed by using the --warn=no-deprecated
+ command-line option:
+
+ $ scons --warn=no-deprecated
+
+ Or by using the appropriate SetOption() call in any SConscript
+ file:
+
+ SetOption('warn', 'no-deprecated')
+
+ You may optionally disable just warnings about the deprecation
+ of the Options object and its related functions as follows:
+
+ SetOption('warn', 'no-deprecated-options')
+
+ The current plan is for these warnings to become mandatory
+ (non-suppressible) in release 1.3.0, and for the use of Options
+ and its related functions to generate errors in release 2.0.
+
+ Please note the following important changes since release 0.98.4:
+
+ -- scons.bat NOW RETURNS THE REAL SCONS EXIT STATUS
+
+ The scons.bat script shipped with SCons used to exit with
+ a status of 1 when it detected any failed (non-zero) exit
+ status from the underlying Python execution of SCons itself.
+ The scons.bat script now exits with the actual status
+ returned by SCons.
+
+ -- SCONS NOW WARNS WHEN TRYING TO LINK C++ AND FORTRAN OBJECT FILES
+
+ Some C++ toolchains do not understand Fortran runtimes and create
+ unpredictable executables when linking C++ and Fortran object
+ files together. SCons now issues a warning if you try to link
+ C++ and Fortran object files into the same executable:
+
+ scons: warning: Using $CXX to link Fortran and C++ code together.
+ This may generate a buggy executable if the '/usr/bin/gcc'
+ compiler does not know how to deal with Fortran runtimes.
+
+ The warning may be suppressed with either the --warning=no-link
+ or --warning=no-fortran-cxx-mix command line options, or by
+ adding either of the following lines to a SConscript file:
+
+ SetOption('warn', 'no-link')
+ SetOption('warn', 'no-fortran-cxx-mix')
+
+ Please note the following important changes since release 0.98:
+
+ -- SCONS NO LONGER SETS THE GNU TOOLCHAIN -fPIC FLAG IN $SHCXXFLAGS
+
+ The GNU toolchain support in previous versions of SCons would
+ add the -fPIC flag to the $SHCXXFLAGS construction variable.
+ The -fPIC flag has been now been removed from the default
+ $SHCXXFLAGS setting. Instead, the $SHCXXCOM construction variable
+ (the default SCons command line for compiling shared objects
+ from C++ source files) has been changed to add the $SHCCFLAGS
+ variable, which contains the -fPIC flag.
+
+ This change was made in order to make the behavior of the default
+ C++ compilation line including $SHCCFLAGS consistent with the
+ default C compilation line including $CCFLAGS.
+
+ This change should have no impact on configurations that use
+ the default $SHCXXCOM command line. It may have an impact on
+ configurations that were using the default $SHCXXFLAGS value
+ *without* the $SHCCFLAGS variable to get the -fPIC flag into a
+ custom command line. You can fix these by adding the $SHCCFLAGS
+ to the custom command line.
+
+ Adding $SHCCFLAGS is backwards compatible with older SCons
+ releases, although it might cause the -fPIC flag to be repeated
+ on the command line if you execute it on an older version of
+ SCons that sets -fPIC in both the $SHCCLAFGS and $SHCXXFLAGS
+ variables. Duplicating the -fPIC flag on the g++ command line
+ will not cause any compilation problems, but the change to the
+ command line may cause SCons to rebuild object files.
+
+ -- FORTRAN NOW COMPILES .f FILES WITH gfortran BY DEFAULT
+
+ The Fortran Tool modules have had a major overhaul with the intent
+ of making them work as-is for most configurations. In general,
+ most configurations that use default settings should not see
+ any noticeable difference.
+
+ One configuration that has changed is if you have both a gfortran
+ and g77 compiler installed. In this case, previous versions of
+ SCons would, by default, use g77 by default to compile files with
+ a .f suffix, while SCons 0.98.1 will use the gfortran compiler
+ by default. The old behavior may be preserved by explicitly
+ initializing construction environments with the 'g77' Tool module:
+
+ env = Environment(tools = ['g77', 'default'])
+
+ The above code is backwards compatible to older versions of SCons.
+
+ If you notice any other changes in the behavior of default
+ Fortran support, please let us know so we can document them in
+ these release notes for other users.
+
+ Please note the following important changes since release 0.97.0d20071212:
+
+ -- SUPPORT FOR PYTHON VERSIONS BEFORE 2.2 IS NOW DEPRECATED
+
+ SCons now prints the following warning when it is run by any
+ Python 1.5, 2.0 or 2.1 release or sub-release:
+
+ scons: warning: Support for pre-2.2 Python (VERSION) is deprecated.
+ If this will cause hardship, contact dev@scons.tigris.org.
+
+ You may disable all warnings about deprecated features by adding
+ the option "--warn=no-deprecated" to the command line or to the
+ $SCONSFLAGS environment variable:
+
+ $ scons --warn=no-deprecated
+
+ Using '--warn=no-deprecated' is compatible with earlier versions
+ of SCons.
+
+ You may also, as of this version of SCons, disable all warnings
+ about deprecated features by adding the following to any
+ SConscript file:
+
+ SetOption('warn', 'no-deprecated')
+
+ You may disable only the specific warning about running under
+ a deprecated Python version by adding the following to any
+ SConscript file:
+
+ SetOption('warn', 'no-python-version')
+
+ The warning may also be suppressed on the command line:
+
+ $ scons --warn=no-python-version
+
+ Or by specifying the --warn=no-python-version option in the
+ $SCONSFLAGS environment variable.
+
+ Using SetOption('warn', ...), and the 'no-python-version'
+ command-line option for suppressing this specific warning,
+ are *not* backwards-compatible to earlier versions of SCons.
+
+ -- THE env.Copy() METHOD IS NOW OFFICIALLY DEPRECATED
+
+ The env.Copy() method is now officially deprecated and will
+ be removed in a future release. Using the env.Copy() method
+ now generates the following message:
+
+ scons: warning: The env.Copy() method is deprecated; use the env.Clone() method instead.
+
+ You may disable all warnings about deprecated features by adding
+ the option "--warn=no-deprecated" to the command line or to the
+ $SCONSFLAGS environment variable:
+
+ $ scons --warn=no-deprecated
+
+ Using '--warn=no-deprecated' is compatible with earlier versions
+ of SCons.
+
+ You may also, as of this version of SCons, disable all warnings
+ about deprecated features by adding the following to any
+ SConscript file:
+
+ SetOption('warn', 'no-deprecated')
+
+ You may disable only the specific warning about the deprecated
+ env.Copy() method by adding the following to any SConscript
+ file:
+
+ SetOption('warn', 'no-deprecated-copy')
+
+ The warning may also be suppressed on the command line:
+
+ $ scons --warn=no-deprecated-copy
+
+ Or by specifying the --warn=no-deprecated-copy option in the
+ $SCONSFLAGS environment variable.
+
+ Using SetOption('warn', ...), and the 'no-deprecated-copy'
+ command-line option for suppressing this specific warning,
+ are *not* backwards-compatible to earlier versions of SCons.
+
+ -- THE --debug=dtree, --debug=stree AND --debug=tree OPTIONS ARE DEPRECATED
+
+ The --debug=dtree, --debug=stree and --debug=tree methods
+ are now officially deprecated and will be removed in a
+ future release. Using these options now generate a warning
+ message recommending use of the --tree=derived, --tree=all,status
+ and --tree=all options, respectively.
+
+ You may disable these warnings, and all warnings about
+ deprecated features, by adding the option "--warn=no-deprecated"
+ to the command line or to the $SCONSFLAGS environment
+ variable:
+
+ $ scons --warn=no-deprecated
+
+ Using '--warn=no-deprecated' is compatible with earlier versions
+ of SCons.
+
+ -- THE TargetSignatures() AND SourceSignatures() FUNCTIONS ARE DEPRECATED
+
+ The TargetSignatures() and SourceSignatures() functions,
+ and their corresponding env.TargetSignatures() and
+ env.SourceSignatures() methods, are now officially deprecated
+ and will be be removed in a future release. Using ahy of
+ these functions or methods now generates a message
+ similar to the following:
+
+ scons: warning: The env.TargetSignatures() method is deprecated;
+ convert your build to use the env.Decider() method instead.
+
+ You may disable all warnings about deprecated features by adding
+ the option "--warn=no-deprecated" to the command line or to the
+ $SCONSFLAGS environment variable:
+
+ $ scons --warn=no-deprecated
+
+ Using '--warn=no-deprecated' is compatible with earlier versions
+ of SCons.
+
+ You may also, as of this version of SCons, disable all warnings
+ about deprecated features by adding the following to any
+ SConscript file:
+
+ SetOption('warn', 'no-deprecated')
+
+ You may disable only the specific warning about the use of
+ TargetSignatures() or SourceSignatures() by adding the
+ following to any SConscript file:
+
+ SetOption('warn', 'no-deprecated-target-signatures')
+ SetOption('warn', 'no-deprecated-source-signatures')
+
+ The warnings may also be suppressed on the command line:
+
+ $ scons --warn=no-deprecated-target-signatures --warn=no-deprecated-source-signatures
+
+ Or by specifying these options in the $SCONSFLAGS environment
+ variable.
+
+ Using SetOption('warn', ...), or the command-line options
+ for suppressing these warnings, is *not* backwards-compatible
+ to earlier versions of SCons.
+
+ -- File(), Dir() and Entry() NOW RETURN A LIST WHEN THE INPUT IS A SEQUENCE
+
+ Previously, if these methods were passed a list, the list was
+ substituted and stringified, then passed as a single string to
+ create a File/Dir/Entry Node. This rarely if ever worked with
+ more than one element in the list. They now return a list of
+ Nodes when passed a list.
+
+ One case that works differently now is a passing in a
+ single-element sequence; that formerly was stringified
+ (returning its only element) and then a single Node would be
+ returned. Now a single-element list containing the Node will
+ be returned, for consistency.
+
+ -- THE env.subst() METHOD NOW RETURNS A LIST WHEN THE INPUT IS A SEQUENCE
+
+ The env.subst() method now returns a list with the elements
+ expanded when given a list as input. Previously, the env.subst()
+ method would always turn its result into a string.
+
+ This behavior was changed because it interfered with being able
+ to include things like lists within the expansion of variables
+ like $CPPPATH and then have SCons understand that the elements
+ of the "internal" lists still needed to be treated separately.
+ This would cause a $CPPPATH list like ['subdir1', 'subdir']
+ to show up in a command line as "-Isubdir1 subdir".
+
+ -- THE Jar() BUILDER NOW USES THE Java() BUILDER CLASSDIR BY DEFAULT
+
+ By default, the Jar() Builder will now use the class directory
+ specified when the Java() builder is called. So the following
+ input:
+
+ classes = env.Java('classes', 'src')
+ env.Jar('out.jar', classes)
+
+ Will cause "-C classes" to be passed the "jar" command invocation,
+ and the Java classes in the "out.jar" file will not be prefixed
+ "classes/".
+
+ Explicitly setting the $JARCHDIR variable overrides this default
+ behavior. The old behavior of not passing any -C option to the
+ "jar" command can be preserved by explicitly setting $JARCHDIR
+ to None:
+
+ env = Environment(JARCHDIR = None)
+
+ The above setting is compatible with older versions of SCons.
+
+ Please note the following important changes since release 0.97.0d20070918:
+
+ -- SCons REDEFINES PYTHON open() AND file() ON Windows TO NOT PASS
+ ON OPEN FILE HANDLES TO CREATED PROCESSES
+
+ On Windows systems, SCons now redefines the Python open()
+ and file() functions so that, if the Python Win32 extensions
+ are available, the file handles for any opened files will *not*
+ be inherited by subprocesses, such as the spawned compilers and
+ other tools invoked to build the software.
+
+ This prevents certain race conditions where a file handle for
+ a file opened by Python (either in a Python function action,
+ or directly in a SConscript file) could be inherited and help
+ open by a subprocess, interfering with the ability of other
+ processes to create or modify the file.
+
+ In general, this should not cause problems for the vast majority
+ of configurations. The only time this would be a problem would be
+ in the unlikely event that a process spawned by SCons specifically
+ *expected* to use an inherited file handle opened by SCons.
+
+ If the Python Win32 extensions are not installed or are an
+ earlier version that does not have the ability to disable file
+ handle inheritance, SCons will print a warning message when the
+ -j option is used. The warning message may be suppressed by
+ specifying --warn=no-parallel-support.
+
+ Please note the following important changes since release 0.97.0d20070809:
+
+ -- "content" SIGNATURES ARE NOW THE DEFAULT BEHAVIOR
+
+ The default behavior of SCons is now to use the MD5 checksum of
+ all file contents to decide if any files have changed and should
+ cause rebuilds of their source files. This means that SCons may
+ decide not to rebuild "downstream" targets if a a given input
+ file is rebuilt to the exact same contents as the last time.
+ The old behavior may preserved by explicity specifying:
+
+ TargetSignatures("build")
+
+ In any of your SConscript files.
+
+ -- TARGETS NOW IMPLICITLY DEPEND ON THE COMMAND THAT BUILDS THEM
+
+ For all targets built by calling external commands (such as a
+ compiler or other utility), SCons now adds an implicit dependency
+ on the command(s) used to build the target.
+
+ This will cause rebuilds of all targets built by external commands
+ when running SCons in a tree built by previous version of SCons,
+ in order to update the recorded signatures.
+
+ The old behavior of not having targets depend on the external
+ commands that build them can be preserved by setting a new
+ $IMPLICIT_COMMAND_DEPENDENCIES construction variable to a
+ non-True value:
+
+ env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0)
+
+ or by adding Ignore() calls for any targets where the behavior
+ is desired:
+
+ Ignore('/usr/bin/gcc', 'foo.o')
+
+ Both of these settings are compatible with older versions
+ of SCons.
+
+ -- CHANGING SourceSignature() MAY CAUSE "UNECESSARY" REBUILDS
+
+ If you change the SourceSignature() value from 'timestamp' to
+ 'MD5', SCons will now rebuild targets that were already up-to-date
+ with respect to their source files.
+
+ This will happen because SCons did not record the content
+ signatures of the input source files when the target was last
+ built--it only recorded the timestamps--and it must record them
+ to make sure the signature information is correct. However,
+ the content of source files may have changed since the last
+ timestamp build was performed, and SCons would not have any way to
+ verify that. (It would have had to open up the file and record
+ a content signature, which is one of the things you're trying to
+ avoid by specifying use of timestamps....) So in order to make
+ sure the built targets reflect the contents of the source files,
+ the targets must be rebuilt.
+
+ Change the SourceSignature() value from 'MD5' to 'timestamp'
+ should correctly not rebuild target files, because the timestamp
+ of the files is always recorded.
+
+ In previous versions of SCons, changing the SourceSignature()
+ value would lead to unpredictable behavior, usually including
+ rebuilding targets.
+
+ -- THE Return() FUNCTION NOW ACTUALLY RETURNS IMMEDIATELY
+
+ The Return() function now immediately stops processing the
+ SConscript file in which it appears and returns the values of the
+ variables named in its arguments. It used to continue processing
+ the rest of the SConscript file, and then return the values of the
+ specified variables at the point the Return() function was called.
+
+ The old behavior may be requested by adding a "stop=False"
+ keyword argument to the Return() call:
+
+ Return('value', stop=False)
+
+ The "stop=" keyword argument is *not* compatible with SCons
+ versions 0.97.0d20070809 or earlier.
+
+ Please note the following important changes since release 0.97:
+
+ -- env.CacheDir() NOW ONLY AFFECTS CONSTRUCTION ENVIRONMENT TARGETS
+
+ The env.CacheDir() method now only causes derived files to be
+ retrieved from the specified cache directory for targets built
+ with the specified specified construction environment ("env").
+
+ Previously, any call to env.CacheDir() or CacheDir() would modify
+ a global setting and cause all built targets to be retrieved
+ from the specified cache directory. This behavior was changed so
+ that env.CacheDir() would be consistent with other construction
+ environment methods, which only affect targets built with the
+ specified construction environment.
+
+ The old behavior of changing the global behavior may be preserved
+ by changing any env.CacheDir() calls to:
+
+ CacheDir('/path/to/cache/directory')
+
+ The above change is backwards-compatible and works in all earlier
+ versions of SCons that support CacheDir().
+
+ -- INTERPRETATION OF SUFFIX-LESS SOURCE ARGUMENTS HAS CHANGED
+
+ The interpretation of source arguments (files) without suffixes
+ has changed in one specific configuration.
+
+ Previously, if a Builder had a src_suffix specified (indicating
+ that source files without suffixes should have that suffix
+ appended), the suffix would only be applied to suffix-less source
+ arguments if the Builder did *not* have one or more attached
+ source Builders (that is, the Builder was not a "multi-stage"
+ Builder). So in the following configuration:
+
+ build_foo = Builder(src_suffix = '.foo')
+ build_bar = Builder(src_suffix = '.bar',
+ src_builder = build_bar)
+
+ env = Environment(BUILDERS = {
+ 'Foo' : build_foo,
+ 'Boo' : build_bar,
+ })
+
+ env.Foo('tgt1', 'src1')
+ env.Bar('tgt2', 'src2')
+
+ SCons would have expected to find a source file 'src1.foo' for the
+ env.Foo() call, but a source file 'src2' for the env.Bar() call.
+
+ This behavior has now been made consistent, so that the two
+ above calls would expect source files named 'src1.foo' and
+ 'src2.bar', respectively.
+
+ Note that, if genuinely desired, the old behavior of building
+ from a source file without a suffix at all (when the Builder has
+ a src_suffix *and* a src_builder) can be specified explicity by
+ turning the string into a File Node directly:
+
+ env.Bar('tgt2', File('src2'))
+
+ The above use of File() is backwards-compatible and will work
+ on earlier versions of SCons.
+
+ -- THE DEFAULT EXECUTION PATH FOR Solaris HAS CHANGED
+
+ On Solaris systems, SCons now adds the "/opt/SUNWspro/bin"
+ directory to the default execution $PATH variable before the
+ "/usr/ccs/bin" directory. This was done to reflect the fact
+ that /opt/SUNWspro/ is the default for SUN tools, but it may
+ cause a different compiler to be used if you have compilers
+ installed in both directories.
+
+ -- GENERATED config.h FILES NOW SAY "#define HAVE_{FEATURE} 1"
+
+ When generating a "config.h" file, SCons now defines values that
+ record the existence of a feature with a "1" value:
+
+ #define HAVE_FEATURE 1
+
+ Instead of printing the line without a "1", as it used to:
+
+ #define HAVE_FEATURE
+
+ This should not cause any problems in the normal use of "#ifdef
+ HAVE_{FEATURE}" statements interpreted by a C preprocessor, but
+ might cause a compatibility issue if a script or other utility
+ looks for an exact match of the previous text.
+
+ Please note the following planned, future changes:
+
+ -- THE Options OBJECT AND RELATED FUNCTIONS WILL BE DEPRECATED
+
+ The Options object is being replaced by a new Variables
+ object, which uses a new Variables.AddVariable() method
+ where the previous interface used Options.AddOptions().
+
+ Similarly, the following utility functions are being replaced
+ by the following similarly-named functions:
+
+ BoolOption() BoolVariable()
+ EnumOption() EnumVariable()
+ ListOption() ListVariable()
+ PackageOption() PackageVariable()
+ PathOption() PathVariable()
+
+ And also related, the options= keyword argument when creating
+ construction environments with the Environment() functions is
+ being replaced with a variables= keyword argument.
+
+ In some future release a deprecation warning will be added to
+ existing uses of the Options object, its methods, the above
+ utility functions, and the options= keyword argument of the
+ Environment() function. At some point after the deprecation
+ warning is added, the Options object, related functions and
+ options= keyword argument will be removed entirely.
+
+ You can prepare for this by changing all your uses of the Options
+ object and related functions to the Variables object and the new
+ function names, and changing any uses of the options= keyword
+ argument to variables=.
+
+ NOTE: CONVERTING TO USING THE NEW Variables OBJECT OR THE
+ RELATED *Variable() FUNCTIONS, OR USING THE NEW variable=
+ KEYWORD ARGUMENT, IS NOT BACKWARDS COMPATIBLE TO VERSIONS OF
+ SCons BEFORE 0.98. YOUR SConscript FILES WILL NOT WORK ON
+ EARLIER VERSIONS OF SCons AFTER MAKING THIS CHANGE.
+
+ If you change SConscript files in software that you make available
+ for download or otherwise distribute, other users may try to
+ build your software with an earlier version of SCons that does
+ not have the Variables object or related *Variable() functions.
+ We recommend preparing for this in one of two ways:
+
+ -- Make your SConscript files backwards-compatible by
+ modifying your calls with Python try:-except: blocks
+ as follows:
+
+ try:
+ vars = Variables('custom.py', ARGUMENTS)
+ vars.AddVariables(
+ BoolVariable('WARNINGS', 'cmopile with -Wall', 1),
+ EnumVariable('DEBUG', 'debug version', 'no'
+ allowed_values=('yes', 'no', 'full'),
+ map={}, ignorecase=0),
+ ListVariable('SHAREDLIBS',
+ 'libraries to build shared',
+ 'all',
+ names = list_of_libs),
+ PackageVariable('X11',
+ 'use X11 from here',
+ '/usr/bin/X11'),
+ PathVariable('QTDIR', 'root of Qt', qtdir),
+ )
+ except NameError:
+ vars = Options('custom.py', ARGUMENTS)
+ vars.AddOptions(
+ BoolOption('WARNINGS', 'cmopile with -Wall', 1),
+ EnumOption('DEBUG', 'debug version', 'no'
+ allowed_values=('yes', 'no', 'full'),
+ map={}, ignorecase=0),
+ ListOption('SHAREDLIBS',
+ 'libraries to build shared',
+ 'all',
+ names = list_of_libs),
+ PackageOption('X11',
+ 'use X11 from here',
+ '/usr/bin/X11'),
+ PathOption('QTDIR', 'root of Qt', qtdir),
+ )
+
+ Additionally, you can check for availability of the new
+ variables= keyword argument as follows:
+
+ try:
+ env = Environment(variables=vars)
+ except TypeError:
+ env = Environment(options=vars)
+
+ (Note that we plan to maintain the existing Options object
+ name for some time, to ensure backwards compatibility,
+ so in practice it may be easier to just continue to use
+ the old name until you're reasonably sure you won't have
+ people trying to build your software with versions of
+ SCons earlier than 0.98.1.)
+
+ -- Use the EnsureSConsVersion() function to provide a
+ descriptive error message if your SConscript files
+ are executed by an earlier version of SCons:
+
+ EnsureSConsVersion(0, 98, 1)
+
+ -- THE BuildDir() METHOD AND FUNCTION WILL BE DEPRECATED
+
+ The env.BuildDir() method and BuildDir() function are being
+ replaced by the new env.VariantDir() method and VariantDir()
+ function.
+
+ In some future release a deprecation warning will be added
+ to existing uses of the env.BuildDir() method and BuildDir()
+ function. At some point after the deprecation warning, the
+ env.Builder() method and BuildDir() function will either
+ be removed entirely or have their behavior changed.
+
+ You can prepare for this by changing all your uses of the
+ env.BuildDir() method to env.VariantDir() and uses of the
+ global BuildDir() function to VariantDir(). If you use a
+ named keyword argument of "build_dir" when calling
+ env.BuildDir() or BuildDir():
+
+ env.BuildDir(build_dir='opt', src_dir='src')
+
+ The keyword must be changed to "variant_dir":
+
+ env.VariantDir(variant_dir='opt', src_dir='src')
+
+ NOTE: CHANGING USES OF env.BuildDir() AND BuildDir() to
+ env.VariantDir() AND VariantDir() IS NOT BACKWARDS COMPATIBLE
+ TO VERSIONS OF SCons BEFORE 0.98. YOUR SConscript FILES
+ WILL NOT WORK ON EARLIER VERSIONS OF SCons AFTER MAKING
+ THIS CHANGE.
+
+ If you change SConscript files in software that you make
+ available for download or otherwise distribute, other users
+ may try to build your software with an earlier version of
+ SCons that does not have the env.VariantDir() method or
+ VariantDir() fnction. We recommend preparing for this in
+ one of two ways:
+
+ -- Make your SConscript files backwards-compatible by
+ including the following code near the beginning of your
+ top-level SConstruct file:
+
+ import SCons.Environment
+ try:
+ SCons.Environment.Environment.VariantDir
+ except AttributeError:
+ SCons.Environment.Environment.VariantDir = \
+ SCons.Environment.Environment.BuildDir
+
+ -- Use the EnsureSConsVersion() function to provide a
+ descriptive error message if your SConscript files
+ are executed by an earlier version of SCons:
+
+ EnsureSConsVersion(0, 98)
+
+ -- THE SConscript() "build_dir" KEYWORD ARGUMENT WILL BE DEPRECATED
+
+ The "build_dir" keyword argument of the SConscript function
+ and env.SConscript() method are being replaced by a new
+ "variant_dir" keyword argument.
+
+ In some future release a deprecation warning will be added
+ to existing uses of the SConscript()/env.SConscript()
+ "build_dir" keyword argument. At some point after the
+ deprecation warning, support for this keyword argument will
+ be removed entirely.
+
+ You can prepare for this by changing all your uses of the
+ SConscript()/env.SConscript() 'build_dir" keyword argument:
+
+ SConscript('src/SConscript', build_dir='opt')
+
+ To use the new "variant_dir" keyword argument:
+
+ SConscript('src/SConscript', variant_dir='opt')
+
+ NOTE: USING THE NEW "variant_dir" KEYWORD IS NOT BACKWARDS
+ COMPATIBLE TO VERSIONS OF SCons BEFORE 0.98. YOUR SConscript
+ FILES WILL NOT WORK ON EARLIER VERSIONS OF SCons AFTER
+ MAKING THIS CHANGE.
+
+ If you change SConscript files in software that you make
+ available for download or otherwise distribute, other users
+ may try to build your software with an earlier version of
+ SCons that does not support the "variant_dir" keyword.
+
+ If you can insist that users use a recent version of SCons
+ that supports "variant_dir", we recommend using the
+ EnsureSConsVersion() function to provide a descriptive error
+ message if your SConscript files are executed by an earlier
+ version of SCons:
+
+ EnsureSConsVersion(0, 98)
+
+ If you want to make sure that your SConscript files will
+ still work with earlier versions of SCons, then your best
+ bet is to continue to use the "build_dir" keyword until the
+ support is removed (which, in all likelihood, won't happen
+ for quite some time).
+
+ -- SCANNER NAMES HAVE BEEN DEPRECATED AND WILL BE REMOVED
+
+ Several internal variable names in SCons.Defaults for various
+ pre-made default Scanner objects have been deprecated and will
+ be removed in a future revision. In their place are several new
+ global variable names that are now part of the publicly-supported
+ interface:
+
+ NEW NAME DEPRECATED NAME
+ -------- ----------------------------
+ CScanner SCons.Defaults.CScan
+ DSCanner SCons.Defaults.DScan
+ SourceFileScanner SCons.Defaults.ObjSourceScan
+ ProgramScanner SCons.Defaults.ProgScan
+
+ Of these, only ObjSourceScan was probably used at all, to add
+ new mappings of file suffixes to other scanners for use by the
+ Object() Builder. This should now be done as follows:
+
+ SourceFileScanner.add_scanner('.x', XScanner)
+
+ -- THE env.Copy() METHOD WILL CHANGE OR GO AWAY ENTIRELY
+
+ The env.Copy() method (to make a copy of a construction
+ environment) is being replaced by the env.Clone() method.
+
+ As of SCons 0.98, a deprecation warning has been added to
+ current uses of the env.Copy() method. At some point in
+ the future, the env.Copy() method will either be removed
+ entirely or have its behavior changed.
+
+ You can prepare for this by changing all your uses of env.Copy()
+ to env.Clone(), which has the exact same calling arguments.
+
+ NOTE: CHANGING USES OF env.Copy() TO env.Clone() WILL MAKE
+ YOUR SConscript FILES NOT WORK ON VERSIONS OF SCons BEFORE
+ 0.96.93.
+
+ If you change SConscript files in software that you make
+ available for download or otherwise distribute, other users
+ may try to build your software with an earlier version of
+ SCons that does not have the env.Clone() method. We recommend
+ preparing for this in one of two ways:
+
+ -- Make your SConscript files backwards-compatible by
+ including the following code near the beginning of your
+ top-level SConstruct file:
+
+ import SCons.Environment
+ try:
+ SCons.Environment.Environment.Clone
+ except AttributeError:
+ SCons.Environment.Environment.Clone = \
+ SCons.Environment.Environment.Copy
+
+ -- Use the EnsureSConsVersion() function to provide a
+ descriptive error message if your SConscript files
+ are executed by an earlier version of SCons:
+
+ EnsureSConsVersion(0, 96, 93)
+
+ -- THE CheckLib Configure TEST WILL CHANGE BEHAVIOR
+
+ The CheckLib() Configure test appends the lib(s) to the
+ Environment's LIBS list in 1.3 and earlier. In 1.3 there is a
+ new CheckLib argument, append, which defaults to True to
+ preserve the old behavior. In a future release, append will
+ be changed to default to False, to conform with autoconf and
+ user expectations, since it is usually used to build up
+ library lists in a right-to-left way.
+
+
+
+ SCons is developed with an extensive regression test suite, and a
+ rigorous development methodology for continually improving that suite.
+ Because of this, SCons is of sufficient quality that you can use it
+ for real work.
+
+ The interfaces in release 1.0 will *not* be knowingly changed in
+ any new, future 1.x release. If an interface change should ever
+ become necessary due to extraordinary circumstances, the change
+ and an appropriate transition strategy will be documented in these
+ RELEASE notes.
+
+ As you use SCons, please heed the following:
+
+ - Please report any bugs or other problems that you find to our bug
+ tracker at our SourceForge project page:
+
+ http://sourceforge.net/tracker/?func=add&group_id=30337&atid=398971
+
+ We have a reliable bug-fixing methodology already in place and
+ strive to respond to problems relatively quickly.
+
+ - Documentation is spottier than we'd like. You may need to dive
+ into the source code to figure out how to do something. Asking
+ questions on the scons-users mailing list is also welcome. We
+ will be addressing the documentation in upcoming releases, but
+ would be more than glad to have your assistance in correcting this
+ problem... :-)
+
+ - The "SCons Design" documentation on the SCons web site is very
+ out of date, as we made significant changes to portions of the
+ interface as we figured out what worked and what didn't during the
+ extensive beta implementation. The "SCons Design" document should
+ be used only for historical purposes, or for just an extremely
+ general understanding of SCons' architectural goals.
+
+ - There may be performance issues. Improving SCons performance
+ is an ongoing priority. If you still find the performance
+ unacceptable, we would very much like to hear from you and learn
+ more about your configuration so we can optimize the right things.
+
+ - Error messages don't always exist where they'd be helpful.
+ Please let us know about any errors you ran into that would
+ have benefitted from a (more) descriptive message.
+
+ KNOWN PROBLEMS IN THIS RELEASE:
+
+ For a complete list of known problems, consult the SCons Issue Tracker
+ at tigris.org:
+
+ http://scons.tigris.org/project_issues.html
+
+ - Support for parallel builds (-j) does not work on WIN32 systems
+ prior to *official* Python release 2.2 (not 2.2 pre-releases).
+
+ Prior to Python 2.2, there is a bug in Python's Win32
+ implementation such that when a thread spawns an external command,
+ it blocks all threads from running. This breaks the SCons
+ multithreading architecture used to support -j builds.
+
+ We have included a patch file, os_spawnv_fix.diff, that you can
+ use if you you want to fix your version of Python to support
+ parallel builds in SCons.
+
+ - Again, the "SCons Design" documentation on the SCons web site is
+ out of date. Take what you read there with a grain of salt.
+
+ - On Win32 systems, you must put a space between the redirection
+ characters < and >, and the specified files (or construction
+ variable expansions):
+
+ command < $SOURCE > $TARGET
+
+ If you don't supply a space (for example, "<$SOURCE"), SCons will
+ not recognize the redirection.
+
+ - MSVC .res files are not rebuilt when icons change.
+
+ - The -c option does not clean up .sconsign files or directories
+ created as part of the build, and also does not clean up
+ SideEffect files (for example, Visual Studio .pdb files).
+
+ - When using multiple Repositories, changing the name of an include
+ file can cause an old version of the file to be used.
+
+ - There is currently no way to force use of a relative path (../*)
+ for directories outside the top-level SConstruct file.
+
+ - The Jar() Builder will, on its second or subsequent invocation,
+ package up the .sconsign files that SCons uses to track signatures.
+ You can work around this by using the SConsignFile() function
+ to collect all of the .sconsign information into a single file
+ outside of the directory being packaged by Jar().
+
+ - SCons does not currently have a way to detect that an intermediate
+ file has been corrupted from outside and should be rebuilt.
+
+ - Unicode characters in path names do not work in all circumstances.
+
+ - SCons does not currently automatically check out SConstruct or
+ SConscript files from SCCS, RCS or BitKeeper.
+
+ - No support yet for the following planned command-line options:
+
+ -d -e -l --list-actions --list-derived --list-where
+ -o --override -p -r -R -w --write-filenames
+ -W --warn-undefined-variables
+
+
+
+Thank you for your interest, and please let us know how we can help
+improve SCons for your needs.
+
+Steven Knight
+knight at baldmt dot com
+http://www.baldmt.com/~knight/
+
+With plenty of help from the SCons Development team:
+ Chad Austin
+ Charles Crain
+ Bill Deegan
+ Steve Leblanc
+ Greg Noel
+ Gary Oberbrunner
+ Anthony Roach
+ Greg Spencer
+ Christoph Wiedemann
+
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+src/Announce.txt 5023 2010/06/14 22:05:46 scons
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 83a1273..160a10c 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -1,5 +1,3 @@
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-# src/CHANGES.txt 4720 2010/03/24 03:14:11 jars
SCons - a software construction tool
@@ -7,6 +5,97 @@
Change Log
+RELEASE 2.0.0.final.0 - Mon, 14 Jun 2010 22:01:37 -0700
+
+ From Dirk Baechle:
+
+ - Fix XML in documentation.
+
+ From W. Trevor King:
+
+ - Revisions to README.
+
+ From Steven Knight:
+
+ - Provide forward compatibility for the 'profile' module.
+
+ - Provide forward compatibility for the 'pickle' module.
+
+ - Provide forward compatibility for the 'io' module.
+
+ - Provide forward compatibility for the 'queue' module.
+
+ - Provide forward compatibility for the 'collections' module.
+
+ - Provide forward compatibility for the 'builtins' module.
+
+ - Provide forward compatibility for 'sys.intern()'.
+
+ - Convert to os.walk() from of os.path.walk().
+
+ - Remove compatibility logic no longer needed.
+
+ - Add a '-3' option to runtest to print 3.x incompatibility warnings.
+
+ - Convert old-style classes into new-style classes.
+
+ - Fix "Ignoring corrupt sconsign entry" warnings when building
+ in a tree with a pre-2.0 .sconsign file.
+
+ - Fix propagation from environment of VS*COMNTOOLS to resolve issues
+ initializing MSVC/MSVS/SDK issues.
+
+ - Handle detecting Visual C++ on Python verions with upper-case
+ platform architectures like 'AMD64'.
+
+ From Greg Noel:
+
+ - Apply numerous Python fixers to update code to more modern idioms.
+ Find where fixers should be applied to code in test strings and
+ apply the fixers there, too.
+
+ - Write a fixer to convert string functions to string methods.
+
+ - Modify the 'dict' fixer to be less conservative.
+
+ - Modify the 'apply' fixer to handle more cases.
+
+ - Create a modified 'types' fixer that converts types to 2.x
+ equivalents rather than 3.x equivalents.
+
+ - Write a 'division' fixer to highlight uses of the old-style
+ division operator. Correct usage where needed.
+
+ - Add forward compatibility for the new 'memoryview' function
+ (which replaces the 'buffer' function).
+
+ - Add forward compatibility for the 'winreg' module.
+
+ - Remove no-longer-needed 'platform' module.
+
+ - Run tests with the '-3' option to Python 2.6 and clear up
+ various reported incompatibilities.
+
+ - Comb out code paths specialized to Pythons older than 2.4.
+
+ - Update deprecation warnings; most now become mandatory.
+
+ - Start deprecation cycle for BuildDir() and build_dir.
+
+ - Start deprecation cycle for SourceCode() and related factories
+
+ - Fixed a problem with is_Dict() not identifying some objects derived
+ from UserDict.
+
+ From Jim Randall:
+
+ - Document the AllowSubstExceptions() function in the User's Guide.
+
+ From William Deegan:
+
+ - Migrate MSVC/MSVS/SDK improvements from 1.3 branch.
+
+
RELEASE 1.3.0 - Tue, 23 Mar 2010 21:44:19 -0400
From Steven Knight:
@@ -41,9 +130,9 @@ RELEASE 1.2.0.d20100306 - Sat, 06 Mar 2010 16:18:33 -0800
file foo.tex. The builder now ignores a directory and continues
searching to find the correct file. Thanks to Lennart Sauerbeck
for the test case and initial patch
-
+
Also allow the \include of files in subdirectories when variantDir
- is used with duplicate=0. Previously latex would crash since
+ is used with duplicate=0. Previously latex would crash since
the directory in which the .aux file is written was not created.
Thanks to Stefan Hepp for finding this and part of the solution.
@@ -55,7 +144,7 @@ RELEASE 1.2.0.d20100306 - Sat, 06 Mar 2010 16:18:33 -0800
installations, as well as having only the SDK installed.
-RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
+RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
From Jim Randall:
- Fixed temp filename race condition on Windows with long cmd lines.
@@ -70,7 +159,7 @@ RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
From William Deegan:
- Final merge from vs_revamp branch to main
- - Added definition and usage of HOST_OS, HOST_ARCH, TARGET_OS,
+ - Added definition and usage of HOST_OS, HOST_ARCH, TARGET_OS,
TARGET_ARCH, currently only defined/used by Visual Studio
Compilers. This will be rolled out to other platforms/tools
in the future.
@@ -101,7 +190,7 @@ RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
- Avoid adding -gphobos to a command line multiple times
when initializing use of the DMD compiler.
-
+
From Jason Kenney:
- Sugguested HOST/TARGET OS/ARCH separation.
@@ -153,7 +242,7 @@ RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
use the output to find files TeX creates. This allows the MiKTeX
installations to find the created files
- - Notify user of Latex errors that would get buried in the
+ - Notify user of Latex errors that would get buried in the
Latex output
- Remove LATEXSUFFIXES from environments that don't initialize Tex.
@@ -161,8 +250,8 @@ RELEASE 1.2.0.d20100117 - Sun, 17 Jan 2010 14:26:59 -0800
- Add support for the glosaaries package for glossaries and acronyms
- Fix problem that pdftex, latex, and pdflatex tools by themselves did
- not create the actions for bibtex, makeindex,... by creating them
- and other environment settings in one routine called by all four
+ not create the actions for bibtex, makeindex,... by creating them
+ and other environment settings in one routine called by all four
tex tools.
- Fix problem with filenames of sideeffects when the user changes
@@ -465,7 +554,7 @@ RELEASE 1.1.0 - Thu, 09 Oct 2008 08:33:47 -0700
- Add CheckCC, CheckCXX, CheckSHCC and CheckSHCXX tests to
configuration contexts.
- - Have the --profile= argument use the much faster cProfile module
+ - Have the --profile= argument use the much faster cProfile module
(if it's available in the running Python version).
- Reorder MSVC compilation arguments so the /Fo is first.
@@ -596,19 +685,6 @@ RELEASE 1.0.1 - Sat, 06 Sep 2008 07:29:34 -0700
-RELEASE 1.0.0.d20080826 - Tue, 26 Aug 2008 09:12:40 -0700
-
- From Gary Oberbrunner:
-
- - Make Glob() sort the returned list of Files or Nodes
- to prevent spurious rebuilds.
-
- From Ian P. Cardenas:
-
- - Fix Glob() polluting LIBPATH by returning copy of list
-
-
-
RELEASE 1.0.0 - XXX
From Jared Grubb:
@@ -643,7 +719,7 @@ RELEASE 1.0.0 - XXX
- In RPCGEN tests, ignore stderr messages from older versions of
rpcgen on some versions of Mac OS X.
-
+
- Fix typos in man page descriptions of Tag() and Package(), and in
the scons-time man page.
@@ -689,7 +765,7 @@ RELEASE 1.0.0 - Sat, 09 Aug 2008 12:19:44 -0700
object, its UnknownOptions() method, and its associated
BoolVariable(), EnumVariable(), ListVariable(), PackageVariable()
and PathVariable() functions.
-
+
- Document the Progress() function.
- Reorganize the chapter and sections describing the different
@@ -1374,7 +1450,7 @@ RELEASE 0.97.0d20070809 - Fri, 10 Aug 2007 10:51:27 -0500
- Fix expansion of $TARGET, $TARGETS, $SOURCE and $SOURCES keywords in
Visual C/C++ PDB file names.
-
+
- Fix locating Visual C/C++ PDB files in build directories.
- Support an env.AddMethod() method and an AddMethod() global function
@@ -1673,7 +1749,7 @@ RELEASE 0.96.94 - Sun, 07 Jan 2007 18:36:20 -0600
From Paul:
- - When compiling resources under MinGW, make sure there's a space
+ - When compiling resources under MinGW, make sure there's a space
between the --include-dir option and its argument.
From Jay Kint:
@@ -1949,7 +2025,7 @@ RELEASE 0.96.93 - Mon, 06 Nov 2006 00:44:11 -0600
- Add an env.ParseFlags() method that provides separate logic for
parsing GNU tool chain flags into a dictionary.
-
+
- Add an env.MergeFlags() method to apply an arbitrary dictionary
of flags to a construction environment's variables.
@@ -1994,7 +2070,7 @@ RELEASE 0.96.93 - Mon, 06 Nov 2006 00:44:11 -0600
From Dobes Vandermeer:
- - Let the src_dir option to the SConscript() function affect all the
+ - Let the src_dir option to the SConscript() function affect all the
the source file paths, instead of treating all source files paths
as relative to the SConscript directory itself.
@@ -4206,7 +4282,7 @@ RELEASE 0.12 - Thu, 27 Mar 2003 23:52:09 -0600
- Change the documentation to correctly describe that the -f option
doesn't change to the directory in which the specified file lives.
-
+
- Support changing directories locally with SConscript directory
path names relative to any SConstruct file specified with -f.
This allows you to build in another directory by simply changing
@@ -4582,7 +4658,7 @@ RELEASE 0.08 - Mon, 15 Jul 2002 12:08:51 -0500
- Removed the "shared" keyword argument from the Object and
Library builders.
-
+
- Added separated StaticObject, SharedObject, StaticLibrary and
SharedLibrary builders. Made Object and Library synonyms for
StaticObject and StaticLibrary, respectively.
@@ -4857,7 +4933,7 @@ RELEASE 0.07 - Thu, 2 May 2002 13:37:16 -0500
- Fix so that Nodes can be passed to SConscript files.
From Moshe Zadka:
-
+
- Changes for official Debian packaging.
@@ -4924,7 +5000,7 @@ RELEASE 0.06 - Thu, 28 Mar 2002 01:24:29 -0600
From Anthony Roach:
- Fix: Construction variables with values of 0 were incorrectly
- interpolated as ''.
+ interpolated as ''.
- Support env['VAR'] to fetch construction variable values.
@@ -5143,15 +5219,15 @@ RELEASE 0.03 - Fri, 11 Jan 2002 01:09:30 -0600
- Fetch the location of the Microsoft Visual C++ compiler(s) from
the Registry, instead of hard-coding the location.
-
+
- Made Scanner objects take Nodes, not path names.
-
+
- Have the C Scanner cache the #include file names instead of
(re-)scanning the file each time it's called.
- Created a separate class for parent "nodes" of file system roots,
eliminating the need for separate is-parent-null checks everywhere.
-
+
- Removed defined __hash__() and __cmp() methods from FS.Entry, in
favor of Python's more efficient built-in identity comparisons.
@@ -5197,7 +5273,7 @@ RELEASE 0.02 - Sun, 23 Dec 2001 19:05:09 -0600
- Made Default() accept Nodes as arguments.
- Changed Export() to make it easier to use.
-
+
- Added the Import() and Return() methods.
@@ -5228,3 +5304,6 @@ A brief overview of important functionality available in release 0.01:
- Linux packages available in RPM and Debian format.
- Windows installer available.
+
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+src/CHANGES.txt 5023 2010/06/14 22:05:46 scons
diff --git a/src/README.txt b/src/README.txt
index 9e6eae5..7280480 100644
--- a/src/README.txt
+++ b/src/README.txt
@@ -1,10 +1,8 @@
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-# src/README.txt 4720 2010/03/24 03:14:11 jars
SCons - a software construction tool
- Version 1.3.0
+ Version 2.0.0.final.0
This is SCons, a tool for building software (and other files). SCons is
@@ -30,7 +28,7 @@ the latest version by checking the SCons download page at:
EXECUTION REQUIREMENTS
======================
-Running SCons requires Python version 1.5.2 or later. There should be
+Running SCons requires Python version 2.4 or later. There should be
no other dependencies or requirements to run SCons. (There is, however,
an additional requirement to *install* SCons from this particular
package; see the next section.)
@@ -44,37 +42,7 @@ configuration of Environment construction variables.
INSTALLATION REQUIREMENTS
=========================
-Installing SCons from this package requires the Python distutils
-package. The distutils package was not shipped as a standard part of
-Python until Python version 1.6, so if your system is running Python
-1.5.2, you may not have distutils installed. If you are running
-Python version 1.6 or later, you should be fine.
-
-NOTE TO RED HAT USERS: Red Hat shipped Python 1.5.2 as the default all
-the way up to Red Hat Linux 7.3, so you probably do *not* have distutils
-installed, unless you have already done so manually or are running Red
-Hat 8.0 or later.
-
-In this case, your options are:
-
- -- (Recommended.) Install from a pre-packaged SCons package that
- does not require distutils:
-
- Red Hat Linux scons-1.3.0-1.noarch.rpm
-
- Debian GNU/Linux scons_1.3.0-1_all.deb
- (or use apt-get)
-
- Windows scons-1.3.0.win32.exe
-
- -- (Optional.) Download the latest distutils package from the
- following URL:
-
- http://www.python.org/sigs/distutils-sig/download.html
-
- Install the distutils according to the instructions on the page.
- You can then proceed to the next section to install SCons from
- this package.
+Nothing special.
INSTALLATION
@@ -88,7 +56,7 @@ provided Python-standard setup script as follows:
By default, the above command will do the following:
- -- Install the version-numbered "scons-1.3.0" and "sconsign-1.3.0"
+ -- Install the version-numbered "scons-2.0.0.final.0" and "sconsign-2.0.0.final.0"
scripts in the default system script directory (/usr/bin or
C:\Python*\Scripts, for example). This can be disabled by
specifying the "--no-version-script" option on the command
@@ -102,17 +70,17 @@ By default, the above command will do the following:
making it the default on your system.
On UNIX or Linux systems, you can have the "scons" and "sconsign"
- scripts be hard links or symbolic links to the "scons-1.3.0" and
- "sconsign-1.3.0" scripts by specifying the "--hardlink-scons"
+ scripts be hard links or symbolic links to the "scons-2.0.0.final.0" and
+ "sconsign-2.0.0.final.0" scripts by specifying the "--hardlink-scons"
or "--symlink-scons" options on the command line.
- -- Install "scons-1.3.0.bat" and "scons.bat" wrapper scripts in the
+ -- Install "scons-2.0.0.final.0.bat" and "scons.bat" wrapper scripts in the
Python prefix directory on Windows (C:\Python*, for example).
This can be disabled by specifying the "--no-install-bat" option
on the command line.
On UNIX or Linux systems, the "--install-bat" option may be
- specified to have "scons-1.3.0.bat" and "scons.bat" files
+ specified to have "scons-2.0.0.final.0.bat" and "scons.bat" files
installed in the default system script directory, which is useful
if you want to install SCons in a shared file system directory
that can be used to execute SCons from both UNIX/Linux and
@@ -120,7 +88,7 @@ By default, the above command will do the following:
-- Install the SCons build engine (a Python module) in an
appropriate version-numbered SCons library directory
- (/usr/lib/scons-1.3.0 or C:\Python*\scons-1.3.0, for example).
+ (/usr/lib/scons-2.0.0.final.0 or C:\Python*\scons-2.0.0.final.0, for example).
See below for more options related to installing the build
engine library.
@@ -271,3 +239,5 @@ With plenty of help from the SCons Development team:
Greg Spencer
Christoph Wiedemann
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+src/README.txt 5023 2010/06/14 22:05:46 scons
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index dc81584..d8fdd9f 100644
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -1,1049 +1,111 @@
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-# src/RELEASE.txt 4720 2010/03/24 03:14:11 jars
+ A new SCons checkpoint release, 2.0.0.final.0, is now available
+ on the SCons download page:
+ http://www.scons.org/download.php
- SCons - a software construction tool
+ The primary purpose of this release is to remove support for Python
+ versions prior to 2.4 and streamline the SCons code base using more
+ modern python idioms.
- Release Notes
+ IMPORTANT: In 1.3.0 and 2.0.0, explicit dependencies (configured via
+ the Depends() call) are ignored for any nodes that do not have builders.
+ This known issue[1] will typically only happen if you explicitly
+ configure a builder call to create multiple output files, some of which
+ are "hidden" from SCons by not being listed in the targets list, and then
+ use Depends() to establish an explicit dependency on a "hidden" file.
+ [1] See http://scons.tigris.org/issues/show_bug.cgi?id=2647 for details.
-This is SCons, a tool for building software (and other files). SCons is
-implemented in Python, and its "configuration files" are actually Python
-scripts, allowing you to use the full power of a real scripting language
-to solve build problems. You do not, however, need to know Python to
-use SCons effectively.
+ A SCons "checkpoint release" is intended to provide early access to
+ new features so they can be tested in the field before being released
+ for adoption by other software distributions.
-So that everyone using SCons can help each other learn how to use it
-more effectively, please sign up for the scons-users mailing list using
-the instructions on the following page:
+ Note that a checkpoint release is developed using the same test-driven
+ development methodology as all SCons releases. Existing SCons
+ functionality should all work as it does in previous releases (except
+ for any changes identified in the release notes) and early adopters
+ should be able to use a checkpoint release safely for production work
+ with existing SConscript files. If not, it represents not only a bug
+ in SCons but also a hole in the regression test suite, and we want to
+ hear about it.
- http://scons.org/lists.php
+ New features may be more lightly tested than in past releases,
+ especially as concerns their interaction with all of the other
+ functionality in SCons. We are especially interested in hearing bug
+ reports about new functionality.
+ We do not recommend that downstream distributions (Debian, Fedora,
+ etc.) package a checkpoint release, mainly to avoid confusing the
+ "public" release numbering with the long checkpoint release names.
+ Here is a summary of the changes since 1.3:
-RELEASE 1.3.0 - Tue, 23 Mar 2010 21:44:19 -0400
+ NEW FUNCTIONALITY
- Please consult the CHANGES.txt file for a list of specific changes
- since last release.
+ - There should be no new functionality or bug fixes in this checkpoint.
+ Bug fixes will be found in the 1.3.1 series of checkpoints.
- Please note the following important changes in this release:
+ DEPRECATED FUNCTIONALITY
- -- DEPRECATED FEATURES WILL GENERATE MANDATORY WARNINGS IN 1.3.0
+ - All features or usages deprecated in 1.3 should have been removed.
+ Uses of formerly-deprecated features should get an error.
- In keeping with our deprecation cycle, the following deprecated
- features will still be supported in 1.3.0 but will generate
- mandatory, non-disableable warnings:
+ - The BuildDir() method and the build_dir option now get warnings.
- -- Support for Python versions 1.5, 1.6, 2.0, 2.1, 2.2, and 2.3.
- -- The overrides= keyword argument to the Builder() call.
- -- The scanner= keyword argument to the Builder() call.
- -- The BuildDir() function and env.BuildDir() method.
- -- The env.Copy() method.
- -- The SourceSignatures() function and
- env.SourceSignatures() method.
- -- The TargetSignatures() function and
- env.TargetSignatures() method.
- -- The Sig module (now an unnused stub).
- -- The --debug=dtree, --debug=stree and --debug=tree options.
- -- The --debug=nomemoizer option.
- -- The Options object and the related BoolOption(),
- EnumOption(), ListOption(), PackageOption() and
- PathOption() functions.
+ - The SourceCode() function and its associated factory functions have
+ started their deprecation cycle and can have a warning enabled.
- The mandatory warnings will be issued in order to make sure
- users of 1.3.0 notice *prior* to the release of SCons 2.0.0, that
- these features will be removed. In SCons 2.0.0 these features
- will no longer work at all, and will instead generate specific
- fatal errors when anyone tries to use them.
+ CHANGED/ENHANCED EXISTING FUNCTIONALITY
- Please note the following important changes since release 1.2.0:
+ - Any Command() or env.Command() calls that use the following Action
+ factory functions will have their targets rebuilt when upgrading
+ from any pre-2.0 release:
- -- Support for Latex glosseries and acronyms has been added
+ Chmod()
+ Copy()
+ Delete()
+ Mkdir()
+ Move()
+ Touch()
- -- MICROSOFT VISUAL STUDIO VERSION/ARCH DETECTION HAS CHANGED
+ (The rebuild occurs because the underlying Python class that
+ implements these functions has been changed to a new-style Python
+ class, and that changes the Python byte code and therefore the
+ build signature of the functions.)
- The way SCons detects Visual Studio on Windows has changed in
- 1.3. By default, it should now use the latest installed
- Visual Studio version on your machine, and compile for 32 or
- 64 bits according to whether your OS is 32 or 64 bits (32/64
- bit python makes no difference).
+ FIXES
- Two new variables control Visual Studio: MSVC_VERSION and
- TARGET_ARCH. These variables ONLY take effect when passed to
- the Environment() constructor; setting them later has no
- effect. To use a non-default Visual Studio version, set
- MSVC_VERSION to e.g. "8.0" or "7.1". Setting it to "xxx" (or
- any nonexistent value) will make it print out the valid
- versions on your system. To use a non-default architecture,
- set TARGET_ARCH to "x86" or "x86_64" (various synonyms are
- accepted).
+ - MSVC/MSVS/SDK support has been improved. A number of issues with
+ determining the correct version and architecture have been resolved.
- In addition, MSVC_USE_SCRIPT can be used to bypass the
- above autodetection; setting it to the path of a Visual
- Studio .bat file (e.g. vcvars.bat) will cause SCons to
- run that bat file and extract the relevant variables
- from the result (typically %INCLUDE%, %LIB%, and %PATH%).
- Setting MSVC_USE_SCRIPT to None bypasses the Visual Studio
- autodetection entirely; use this if you are importing
- the shell env and running SCons in a Visual Studio cmd window.
+ IMPROVEMENTS
- Note that if you use MSVS_VERSION to build Visual Studio
- projects from your SConstructs, MSVS_VERSION must be set to
- the same version as MSVC_VERSION.
+ - Support for Python versions prior to 2.4 has been removed. As of
+ this writing, we believe that SCons will still work with Python 2.3,
+ but this is not guaranteed.
+ - Code paths that included special cases for older Python versions have
+ been streamlined.
+ - The code base has been converted to use more modern idioms. Although
+ we don't have any direct measurements (yet), we believe that SCons
+ startup time should be decreased and the overall code should run faster.
- Support for HOST_OS,HOST_ARCH,TARGET_OS, TARGET_ARCH has been
- added to allow specifying different target arch than the host
- system. This is only supported for Visual Studio/Visual C++
- at this time.
+ PACKAGING
- -- VISUAL C/C++ PRECOMPILED HEADERS WILL BE REBUILT
+ - No changes.
- Precompiled header files built with Visual C/C++ will be
- rebuilt after upgrading from 1.2.0 to a later release.
+ DOCUMENTATION
- This rebuild is normal and will occur because the command line
- defined by the $PCHCOM construction variable has had the $CCFLAGS
- variable added, and has been rearranged to put the "/Fo" output
- flag towards the beginning of the line, consistent with the
- related command lines for $CCCOM, $CXXCOM, etc.
+ - The entries for SourceCode() and its associated factory functions now
+ state that the functions are deprecated.
- -- CHANGES TO SOME LINKER COMMAND LINES WILL CAUSE RELINKING
+ DEVELOPMENT
- Changes to the command line definitions for the Microsoft link.exe
- linker, the OS/2 ilink linker and the Phar Lap linkloc linker
- will cause targets built with those tools be to be rebuilt after
- upgrading from 1.2.0 to a later release.
+ - Code no longer has to be compatible with Python versions back to 1.5.2.
+ Although code is tested with Python 2.3 and is still believed to work,
+ the official new floor is Python 2.4.
- This relink is normal and will occur because the command lines for
- these tools have been redefined to remove unnecessary nested $(
- and $) character strings.
-
- -- MSVS_USE_MFC_DIRS and MSVS_IGNORE_IDE_PATHS are obsoleted and
- have no effect.
-
- Please note the following important changes since release 1.1.0:
-
- -- THE $CHANGED_SOURCES, $CHANGED_TARGETS, $UNCHANGED_SOURCES
- AND $UNCHANGED_TARGETS VARIABLES WILL BECOME RESERVED
-
- A future release (probably 1.3.0) will make the construction
- variable names $CHANGED_SOURCES, $CHANGED_TARGETS,
- $UNCHANGED_SOURCES and $UNCHANGED_TARGETS into reserved
- construction variable names controlled by SCons itself (like
- the current $SOURCE, $TARGETS, etc.).
-
- Setting these variable names in the current release will generate
- a warning but still set the variables. When they become reserved
- variable names, they will generate a different warning message
- and attempts to set these variables will be ignored.
-
- SCons configurations that happen to use these variable names
- should be changed to use different variable names, in order
- to ensure that the configuration continues to work with future
- versions of SCons.
-
- -- THE Options OBJECT AND RELATED FUNCTIONS NOW GENERATE WARNINGS
-
- Use of the Options object, and related functions BoolOption(),
- EnumOption(), ListOption(), PackageOption() and PathOption()
- were announced as deprecated in release 0.98.1. Since then,
- however, no warning messages were ever implemented for the
- use of these deprecated functions.
-
- By default, release 1.2.0 prints warning messages when these
- deprecated features are used. Warnings about all deprecated
- features may be suppressed by using the --warn=no-deprecated
- command-line option:
-
- $ scons --warn=no-deprecated
-
- Or by using the appropriate SetOption() call in any SConscript
- file:
-
- SetOption('warn', 'no-deprecated')
-
- You may optionally disable just warnings about the deprecation
- of the Options object and its related functions as follows:
-
- SetOption('warn', 'no-deprecated-options')
-
- The current plan is for these warnings to become mandatory
- (non-suppressible) in release 1.3.0, and for the use of Options
- and its related functions to generate errors in release 2.0.
-
- Please note the following important changes since release 0.98.4:
-
- -- scons.bat NOW RETURNS THE REAL SCONS EXIT STATUS
-
- The scons.bat script shipped with SCons used to exit with
- a status of 1 when it detected any failed (non-zero) exit
- status from the underlying Python execution of SCons itself.
- The scons.bat script now exits with the actual status
- returned by SCons.
-
- -- SCONS NOW WARNS WHEN TRYING TO LINK C++ AND FORTRAN OBJECT FILES
-
- Some C++ toolchains do not understand Fortran runtimes and create
- unpredictable executables when linking C++ and Fortran object
- files together. SCons now issues a warning if you try to link
- C++ and Fortran object files into the same executable:
-
- scons: warning: Using $CXX to link Fortran and C++ code together.
- This may generate a buggy executable if the '/usr/bin/gcc'
- compiler does not know how to deal with Fortran runtimes.
-
- The warning may be suppressed with either the --warning=no-link
- or --warning=no-fortran-cxx-mix command line options, or by
- adding either of the following lines to a SConscript file:
-
- SetOption('warn', 'no-link')
- SetOption('warn', 'no-fortran-cxx-mix')
-
- Please note the following important changes since release 0.98:
-
- -- SCONS NO LONGER SETS THE GNU TOOLCHAIN -fPIC FLAG IN $SHCXXFLAGS
-
- The GNU toolchain support in previous versions of SCons would
- add the -fPIC flag to the $SHCXXFLAGS construction variable.
- The -fPIC flag has been now been removed from the default
- $SHCXXFLAGS setting. Instead, the $SHCXXCOM construction variable
- (the default SCons command line for compiling shared objects
- from C++ source files) has been changed to add the $SHCCFLAGS
- variable, which contains the -fPIC flag.
-
- This change was made in order to make the behavior of the default
- C++ compilation line including $SHCCFLAGS consistent with the
- default C compilation line including $CCFLAGS.
-
- This change should have no impact on configurations that use
- the default $SHCXXCOM command line. It may have an impact on
- configurations that were using the default $SHCXXFLAGS value
- *without* the $SHCCFLAGS variable to get the -fPIC flag into a
- custom command line. You can fix these by adding the $SHCCFLAGS
- to the custom command line.
-
- Adding $SHCCFLAGS is backwards compatible with older SCons
- releases, although it might cause the -fPIC flag to be repeated
- on the command line if you execute it on an older version of
- SCons that sets -fPIC in both the $SHCCLAFGS and $SHCXXFLAGS
- variables. Duplicating the -fPIC flag on the g++ command line
- will not cause any compilation problems, but the change to the
- command line may cause SCons to rebuild object files.
-
- -- FORTRAN NOW COMPILES .f FILES WITH gfortran BY DEFAULT
-
- The Fortran Tool modules have had a major overhaul with the intent
- of making them work as-is for most configurations. In general,
- most configurations that use default settings should not see
- any noticeable difference.
-
- One configuration that has changed is if you have both a gfortran
- and g77 compiler installed. In this case, previous versions of
- SCons would, by default, use g77 by default to compile files with
- a .f suffix, while SCons 0.98.1 will use the gfortran compiler
- by default. The old behavior may be preserved by explicitly
- initializing construction environments with the 'g77' Tool module:
-
- env = Environment(tools = ['g77', 'default'])
-
- The above code is backwards compatible to older versions of SCons.
-
- If you notice any other changes in the behavior of default
- Fortran support, please let us know so we can document them in
- these release notes for other users.
-
- Please note the following important changes since release 0.97.0d20071212:
-
- -- SUPPORT FOR PYTHON VERSIONS BEFORE 2.2 IS NOW DEPRECATED
-
- SCons now prints the following warning when it is run by any
- Python 1.5, 2.0 or 2.1 release or sub-release:
-
- scons: warning: Support for pre-2.2 Python (VERSION) is deprecated.
- If this will cause hardship, contact dev@scons.tigris.org.
-
- You may disable all warnings about deprecated features by adding
- the option "--warn=no-deprecated" to the command line or to the
- $SCONSFLAGS environment variable:
-
- $ scons --warn=no-deprecated
-
- Using '--warn=no-deprecated' is compatible with earlier versions
- of SCons.
-
- You may also, as of this version of SCons, disable all warnings
- about deprecated features by adding the following to any
- SConscript file:
-
- SetOption('warn', 'no-deprecated')
-
- You may disable only the specific warning about running under
- a deprecated Python version by adding the following to any
- SConscript file:
-
- SetOption('warn', 'no-python-version')
-
- The warning may also be suppressed on the command line:
-
- $ scons --warn=no-python-version
-
- Or by specifying the --warn=no-python-version option in the
- $SCONSFLAGS environment variable.
-
- Using SetOption('warn', ...), and the 'no-python-version'
- command-line option for suppressing this specific warning,
- are *not* backwards-compatible to earlier versions of SCons.
-
- -- THE env.Copy() METHOD IS NOW OFFICIALLY DEPRECATED
-
- The env.Copy() method is now officially deprecated and will
- be removed in a future release. Using the env.Copy() method
- now generates the following message:
-
- scons: warning: The env.Copy() method is deprecated; use the env.Clone() method instead.
-
- You may disable all warnings about deprecated features by adding
- the option "--warn=no-deprecated" to the command line or to the
- $SCONSFLAGS environment variable:
-
- $ scons --warn=no-deprecated
-
- Using '--warn=no-deprecated' is compatible with earlier versions
- of SCons.
-
- You may also, as of this version of SCons, disable all warnings
- about deprecated features by adding the following to any
- SConscript file:
-
- SetOption('warn', 'no-deprecated')
-
- You may disable only the specific warning about the deprecated
- env.Copy() method by adding the following to any SConscript
- file:
-
- SetOption('warn', 'no-deprecated-copy')
-
- The warning may also be suppressed on the command line:
-
- $ scons --warn=no-deprecated-copy
-
- Or by specifying the --warn=no-deprecated-copy option in the
- $SCONSFLAGS environment variable.
-
- Using SetOption('warn', ...), and the 'no-deprecated-copy'
- command-line option for suppressing this specific warning,
- are *not* backwards-compatible to earlier versions of SCons.
-
- -- THE --debug=dtree, --debug=stree AND --debug=tree OPTIONS ARE DEPRECATED
-
- The --debug=dtree, --debug=stree and --debug=tree methods
- are now officially deprecated and will be removed in a
- future release. Using these options now generate a warning
- message recommending use of the --tree=derived, --tree=all,status
- and --tree=all options, respectively.
-
- You may disable these warnings, and all warnings about
- deprecated features, by adding the option "--warn=no-deprecated"
- to the command line or to the $SCONSFLAGS environment
- variable:
-
- $ scons --warn=no-deprecated
-
- Using '--warn=no-deprecated' is compatible with earlier versions
- of SCons.
-
- -- THE TargetSignatures() AND SourceSignatures() FUNCTIONS ARE DEPRECATED
-
- The TargetSignatures() and SourceSignatures() functions,
- and their corresponding env.TargetSignatures() and
- env.SourceSignatures() methods, are now officially deprecated
- and will be be removed in a future release. Using ahy of
- these functions or methods now generates a message
- similar to the following:
-
- scons: warning: The env.TargetSignatures() method is deprecated;
- convert your build to use the env.Decider() method instead.
-
- You may disable all warnings about deprecated features by adding
- the option "--warn=no-deprecated" to the command line or to the
- $SCONSFLAGS environment variable:
-
- $ scons --warn=no-deprecated
-
- Using '--warn=no-deprecated' is compatible with earlier versions
- of SCons.
-
- You may also, as of this version of SCons, disable all warnings
- about deprecated features by adding the following to any
- SConscript file:
-
- SetOption('warn', 'no-deprecated')
-
- You may disable only the specific warning about the use of
- TargetSignatures() or SourceSignatures() by adding the
- following to any SConscript file:
-
- SetOption('warn', 'no-deprecated-target-signatures')
- SetOption('warn', 'no-deprecated-source-signatures')
-
- The warnings may also be suppressed on the command line:
-
- $ scons --warn=no-deprecated-target-signatures --warn=no-deprecated-source-signatures
-
- Or by specifying these options in the $SCONSFLAGS environment
- variable.
-
- Using SetOption('warn', ...), or the command-line options
- for suppressing these warnings, is *not* backwards-compatible
- to earlier versions of SCons.
-
- -- File(), Dir() and Entry() NOW RETURN A LIST WHEN THE INPUT IS A SEQUENCE
-
- Previously, if these methods were passed a list, the list was
- substituted and stringified, then passed as a single string to
- create a File/Dir/Entry Node. This rarely if ever worked with
- more than one element in the list. They now return a list of
- Nodes when passed a list.
-
- One case that works differently now is a passing in a
- single-element sequence; that formerly was stringified
- (returning its only element) and then a single Node would be
- returned. Now a single-element list containing the Node will
- be returned, for consistency.
-
- -- THE env.subst() METHOD NOW RETURNS A LIST WHEN THE INPUT IS A SEQUENCE
-
- The env.subst() method now returns a list with the elements
- expanded when given a list as input. Previously, the env.subst()
- method would always turn its result into a string.
-
- This behavior was changed because it interfered with being able
- to include things like lists within the expansion of variables
- like $CPPPATH and then have SCons understand that the elements
- of the "internal" lists still needed to be treated separately.
- This would cause a $CPPPATH list like ['subdir1', 'subdir']
- to show up in a command line as "-Isubdir1 subdir".
-
- -- THE Jar() BUILDER NOW USES THE Java() BUILDER CLASSDIR BY DEFAULT
-
- By default, the Jar() Builder will now use the class directory
- specified when the Java() builder is called. So the following
- input:
-
- classes = env.Java('classes', 'src')
- env.Jar('out.jar', classes)
-
- Will cause "-C classes" to be passed the "jar" command invocation,
- and the Java classes in the "out.jar" file will not be prefixed
- "classes/".
-
- Explicitly setting the $JARCHDIR variable overrides this default
- behavior. The old behavior of not passing any -C option to the
- "jar" command can be preserved by explicitly setting $JARCHDIR
- to None:
-
- env = Environment(JARCHDIR = None)
-
- The above setting is compatible with older versions of SCons.
-
- Please note the following important changes since release 0.97.0d20070918:
-
- -- SCons REDEFINES PYTHON open() AND file() ON Windows TO NOT PASS
- ON OPEN FILE HANDLES TO CREATED PROCESSES
-
- On Windows systems, SCons now redefines the Python open()
- and file() functions so that, if the Python Win32 extensions
- are available, the file handles for any opened files will *not*
- be inherited by subprocesses, such as the spawned compilers and
- other tools invoked to build the software.
-
- This prevents certain race conditions where a file handle for
- a file opened by Python (either in a Python function action,
- or directly in a SConscript file) could be inherited and help
- open by a subprocess, interfering with the ability of other
- processes to create or modify the file.
-
- In general, this should not cause problems for the vast majority
- of configurations. The only time this would be a problem would be
- in the unlikely event that a process spawned by SCons specifically
- *expected* to use an inherited file handle opened by SCons.
-
- If the Python Win32 extensions are not installed or are an
- earlier version that does not have the ability to disable file
- handle inheritance, SCons will print a warning message when the
- -j option is used. The warning message may be suppressed by
- specifying --warn=no-parallel-support.
-
- Please note the following important changes since release 0.97.0d20070809:
-
- -- "content" SIGNATURES ARE NOW THE DEFAULT BEHAVIOR
-
- The default behavior of SCons is now to use the MD5 checksum of
- all file contents to decide if any files have changed and should
- cause rebuilds of their source files. This means that SCons may
- decide not to rebuild "downstream" targets if a a given input
- file is rebuilt to the exact same contents as the last time.
- The old behavior may preserved by explicity specifying:
-
- TargetSignatures("build")
-
- In any of your SConscript files.
-
- -- TARGETS NOW IMPLICITLY DEPEND ON THE COMMAND THAT BUILDS THEM
-
- For all targets built by calling external commands (such as a
- compiler or other utility), SCons now adds an implicit dependency
- on the command(s) used to build the target.
-
- This will cause rebuilds of all targets built by external commands
- when running SCons in a tree built by previous version of SCons,
- in order to update the recorded signatures.
-
- The old behavior of not having targets depend on the external
- commands that build them can be preserved by setting a new
- $IMPLICIT_COMMAND_DEPENDENCIES construction variable to a
- non-True value:
-
- env = Environment(IMPLICIT_COMMAND_DEPENDENCIES = 0)
-
- or by adding Ignore() calls for any targets where the behavior
- is desired:
-
- Ignore('/usr/bin/gcc', 'foo.o')
-
- Both of these settings are compatible with older versions
- of SCons.
-
- -- CHANGING SourceSignature() MAY CAUSE "UNECESSARY" REBUILDS
-
- If you change the SourceSignature() value from 'timestamp' to
- 'MD5', SCons will now rebuild targets that were already up-to-date
- with respect to their source files.
-
- This will happen because SCons did not record the content
- signatures of the input source files when the target was last
- built--it only recorded the timestamps--and it must record them
- to make sure the signature information is correct. However,
- the content of source files may have changed since the last
- timestamp build was performed, and SCons would not have any way to
- verify that. (It would have had to open up the file and record
- a content signature, which is one of the things you're trying to
- avoid by specifying use of timestamps....) So in order to make
- sure the built targets reflect the contents of the source files,
- the targets must be rebuilt.
-
- Change the SourceSignature() value from 'MD5' to 'timestamp'
- should correctly not rebuild target files, because the timestamp
- of the files is always recorded.
-
- In previous versions of SCons, changing the SourceSignature()
- value would lead to unpredictable behavior, usually including
- rebuilding targets.
-
- -- THE Return() FUNCTION NOW ACTUALLY RETURNS IMMEDIATELY
-
- The Return() function now immediately stops processing the
- SConscript file in which it appears and returns the values of the
- variables named in its arguments. It used to continue processing
- the rest of the SConscript file, and then return the values of the
- specified variables at the point the Return() function was called.
-
- The old behavior may be requested by adding a "stop=False"
- keyword argument to the Return() call:
-
- Return('value', stop=False)
-
- The "stop=" keyword argument is *not* compatible with SCons
- versions 0.97.0d20070809 or earlier.
-
- Please note the following important changes since release 0.97:
-
- -- env.CacheDir() NOW ONLY AFFECTS CONSTRUCTION ENVIRONMENT TARGETS
-
- The env.CacheDir() method now only causes derived files to be
- retrieved from the specified cache directory for targets built
- with the specified specified construction environment ("env").
-
- Previously, any call to env.CacheDir() or CacheDir() would modify
- a global setting and cause all built targets to be retrieved
- from the specified cache directory. This behavior was changed so
- that env.CacheDir() would be consistent with other construction
- environment methods, which only affect targets built with the
- specified construction environment.
-
- The old behavior of changing the global behavior may be preserved
- by changing any env.CacheDir() calls to:
-
- CacheDir('/path/to/cache/directory')
-
- The above change is backwards-compatible and works in all earlier
- versions of SCons that support CacheDir().
-
- -- INTERPRETATION OF SUFFIX-LESS SOURCE ARGUMENTS HAS CHANGED
-
- The interpretation of source arguments (files) without suffixes
- has changed in one specific configuration.
-
- Previously, if a Builder had a src_suffix specified (indicating
- that source files without suffixes should have that suffix
- appended), the suffix would only be applied to suffix-less source
- arguments if the Builder did *not* have one or more attached
- source Builders (that is, the Builder was not a "multi-stage"
- Builder). So in the following configuration:
-
- build_foo = Builder(src_suffix = '.foo')
- build_bar = Builder(src_suffix = '.bar',
- src_builder = build_bar)
-
- env = Environment(BUILDERS = {
- 'Foo' : build_foo,
- 'Boo' : build_bar,
- })
-
- env.Foo('tgt1', 'src1')
- env.Bar('tgt2', 'src2')
-
- SCons would have expected to find a source file 'src1.foo' for the
- env.Foo() call, but a source file 'src2' for the env.Bar() call.
-
- This behavior has now been made consistent, so that the two
- above calls would expect source files named 'src1.foo' and
- 'src2.bar', respectively.
-
- Note that, if genuinely desired, the old behavior of building
- from a source file without a suffix at all (when the Builder has
- a src_suffix *and* a src_builder) can be specified explicity by
- turning the string into a File Node directly:
-
- env.Bar('tgt2', File('src2'))
-
- The above use of File() is backwards-compatible and will work
- on earlier versions of SCons.
-
- -- THE DEFAULT EXECUTION PATH FOR Solaris HAS CHANGED
-
- On Solaris systems, SCons now adds the "/opt/SUNWspro/bin"
- directory to the default execution $PATH variable before the
- "/usr/ccs/bin" directory. This was done to reflect the fact
- that /opt/SUNWspro/ is the default for SUN tools, but it may
- cause a different compiler to be used if you have compilers
- installed in both directories.
-
- -- GENERATED config.h FILES NOW SAY "#define HAVE_{FEATURE} 1"
-
- When generating a "config.h" file, SCons now defines values that
- record the existence of a feature with a "1" value:
-
- #define HAVE_FEATURE 1
-
- Instead of printing the line without a "1", as it used to:
-
- #define HAVE_FEATURE
-
- This should not cause any problems in the normal use of "#ifdef
- HAVE_{FEATURE}" statements interpreted by a C preprocessor, but
- might cause a compatibility issue if a script or other utility
- looks for an exact match of the previous text.
-
- Please note the following planned, future changes:
-
- -- THE Options OBJECT AND RELATED FUNCTIONS WILL BE DEPRECATED
-
- The Options object is being replaced by a new Variables
- object, which uses a new Variables.AddVariable() method
- where the previous interface used Options.AddOptions().
-
- Similarly, the following utility functions are being replaced
- by the following similarly-named functions:
-
- BoolOption() BoolVariable()
- EnumOption() EnumVariable()
- ListOption() ListVariable()
- PackageOption() PackageVariable()
- PathOption() PathVariable()
-
- And also related, the options= keyword argument when creating
- construction environments with the Environment() functions is
- being replaced with a variables= keyword argument.
-
- In some future release a deprecation warning will be added to
- existing uses of the Options object, its methods, the above
- utility functions, and the options= keyword argument of the
- Environment() function. At some point after the deprecation
- warning is added, the Options object, related functions and
- options= keyword argument will be removed entirely.
-
- You can prepare for this by changing all your uses of the Options
- object and related functions to the Variables object and the new
- function names, and changing any uses of the options= keyword
- argument to variables=.
-
- NOTE: CONVERTING TO USING THE NEW Variables OBJECT OR THE
- RELATED *Variable() FUNCTIONS, OR USING THE NEW variable=
- KEYWORD ARGUMENT, IS NOT BACKWARDS COMPATIBLE TO VERSIONS OF
- SCons BEFORE 0.98. YOUR SConscript FILES WILL NOT WORK ON
- EARLIER VERSIONS OF SCons AFTER MAKING THIS CHANGE.
-
- If you change SConscript files in software that you make available
- for download or otherwise distribute, other users may try to
- build your software with an earlier version of SCons that does
- not have the Variables object or related *Variable() functions.
- We recommend preparing for this in one of two ways:
-
- -- Make your SConscript files backwards-compatible by
- modifying your calls with Python try:-except: blocks
- as follows:
-
- try:
- vars = Variables('custom.py', ARGUMENTS)
- vars.AddVariables(
- BoolVariable('WARNINGS', 'cmopile with -Wall', 1),
- EnumVariable('DEBUG', 'debug version', 'no'
- allowed_values=('yes', 'no', 'full'),
- map={}, ignorecase=0),
- ListVariable('SHAREDLIBS',
- 'libraries to build shared',
- 'all',
- names = list_of_libs),
- PackageVariable('X11',
- 'use X11 from here',
- '/usr/bin/X11'),
- PathVariable('QTDIR', 'root of Qt', qtdir),
- )
- except NameError:
- vars = Options('custom.py', ARGUMENTS)
- vars.AddOptions(
- BoolOption('WARNINGS', 'cmopile with -Wall', 1),
- EnumOption('DEBUG', 'debug version', 'no'
- allowed_values=('yes', 'no', 'full'),
- map={}, ignorecase=0),
- ListOption('SHAREDLIBS',
- 'libraries to build shared',
- 'all',
- names = list_of_libs),
- PackageOption('X11',
- 'use X11 from here',
- '/usr/bin/X11'),
- PathOption('QTDIR', 'root of Qt', qtdir),
- )
-
- Additionally, you can check for availability of the new
- variables= keyword argument as follows:
-
- try:
- env = Environment(variables=vars)
- except TypeError:
- env = Environment(options=vars)
-
- (Note that we plan to maintain the existing Options object
- name for some time, to ensure backwards compatibility,
- so in practice it may be easier to just continue to use
- the old name until you're reasonably sure you won't have
- people trying to build your software with versions of
- SCons earlier than 0.98.1.)
-
- -- Use the EnsureSConsVersion() function to provide a
- descriptive error message if your SConscript files
- are executed by an earlier version of SCons:
-
- EnsureSConsVersion(0, 98, 1)
-
- -- THE BuildDir() METHOD AND FUNCTION WILL BE DEPRECATED
-
- The env.BuildDir() method and BuildDir() function are being
- replaced by the new env.VariantDir() method and VariantDir()
- function.
-
- In some future release a deprecation warning will be added
- to existing uses of the env.BuildDir() method and BuildDir()
- function. At some point after the deprecation warning, the
- env.Builder() method and BuildDir() function will either
- be removed entirely or have their behavior changed.
-
- You can prepare for this by changing all your uses of the
- env.BuildDir() method to env.VariantDir() and uses of the
- global BuildDir() function to VariantDir(). If you use a
- named keyword argument of "build_dir" when calling
- env.BuildDir() or BuildDir():
-
- env.BuildDir(build_dir='opt', src_dir='src')
-
- The keyword must be changed to "variant_dir":
-
- env.VariantDir(variant_dir='opt', src_dir='src')
-
- NOTE: CHANGING USES OF env.BuildDir() AND BuildDir() to
- env.VariantDir() AND VariantDir() IS NOT BACKWARDS COMPATIBLE
- TO VERSIONS OF SCons BEFORE 0.98. YOUR SConscript FILES
- WILL NOT WORK ON EARLIER VERSIONS OF SCons AFTER MAKING
- THIS CHANGE.
-
- If you change SConscript files in software that you make
- available for download or otherwise distribute, other users
- may try to build your software with an earlier version of
- SCons that does not have the env.VariantDir() method or
- VariantDir() fnction. We recommend preparing for this in
- one of two ways:
-
- -- Make your SConscript files backwards-compatible by
- including the following code near the beginning of your
- top-level SConstruct file:
-
- import SCons.Environment
- try:
- SCons.Environment.Environment.VariantDir
- except AttributeError:
- SCons.Environment.Environment.VariantDir = \
- SCons.Environment.Environment.BuildDir
-
- -- Use the EnsureSConsVersion() function to provide a
- descriptive error message if your SConscript files
- are executed by an earlier version of SCons:
-
- EnsureSConsVersion(0, 98)
-
- -- THE SConscript() "build_dir" KEYWORD ARGUMENT WILL BE DEPRECATED
-
- The "build_dir" keyword argument of the SConscript function
- and env.SConscript() method are being replaced by a new
- "variant_dir" keyword argument.
-
- In some future release a deprecation warning will be added
- to existing uses of the SConscript()/env.SConscript()
- "build_dir" keyword argument. At some point after the
- deprecation warning, support for this keyword argument will
- be removed entirely.
-
- You can prepare for this by changing all your uses of the
- SConscript()/env.SConscript() 'build_dir" keyword argument:
-
- SConscript('src/SConscript', build_dir='opt')
-
- To use the new "variant_dir" keyword argument:
-
- SConscript('src/SConscript', variant_dir='opt')
-
- NOTE: USING THE NEW "variant_dir" KEYWORD IS NOT BACKWARDS
- COMPATIBLE TO VERSIONS OF SCons BEFORE 0.98. YOUR SConscript
- FILES WILL NOT WORK ON EARLIER VERSIONS OF SCons AFTER
- MAKING THIS CHANGE.
-
- If you change SConscript files in software that you make
- available for download or otherwise distribute, other users
- may try to build your software with an earlier version of
- SCons that does not support the "variant_dir" keyword.
-
- If you can insist that users use a recent version of SCons
- that supports "variant_dir", we recommend using the
- EnsureSConsVersion() function to provide a descriptive error
- message if your SConscript files are executed by an earlier
- version of SCons:
-
- EnsureSConsVersion(0, 98)
-
- If you want to make sure that your SConscript files will
- still work with earlier versions of SCons, then your best
- bet is to continue to use the "build_dir" keyword until the
- support is removed (which, in all likelihood, won't happen
- for quite some time).
-
- -- SCANNER NAMES HAVE BEEN DEPRECATED AND WILL BE REMOVED
-
- Several internal variable names in SCons.Defaults for various
- pre-made default Scanner objects have been deprecated and will
- be removed in a future revision. In their place are several new
- global variable names that are now part of the publicly-supported
- interface:
-
- NEW NAME DEPRECATED NAME
- -------- ----------------------------
- CScanner SCons.Defaults.CScan
- DSCanner SCons.Defaults.DScan
- SourceFileScanner SCons.Defaults.ObjSourceScan
- ProgramScanner SCons.Defaults.ProgScan
-
- Of these, only ObjSourceScan was probably used at all, to add
- new mappings of file suffixes to other scanners for use by the
- Object() Builder. This should now be done as follows:
-
- SourceFileScanner.add_scanner('.x', XScanner)
-
- -- THE env.Copy() METHOD WILL CHANGE OR GO AWAY ENTIRELY
-
- The env.Copy() method (to make a copy of a construction
- environment) is being replaced by the env.Clone() method.
-
- As of SCons 0.98, a deprecation warning has been added to
- current uses of the env.Copy() method. At some point in
- the future, the env.Copy() method will either be removed
- entirely or have its behavior changed.
-
- You can prepare for this by changing all your uses of env.Copy()
- to env.Clone(), which has the exact same calling arguments.
-
- NOTE: CHANGING USES OF env.Copy() TO env.Clone() WILL MAKE
- YOUR SConscript FILES NOT WORK ON VERSIONS OF SCons BEFORE
- 0.96.93.
-
- If you change SConscript files in software that you make
- available for download or otherwise distribute, other users
- may try to build your software with an earlier version of
- SCons that does not have the env.Clone() method. We recommend
- preparing for this in one of two ways:
-
- -- Make your SConscript files backwards-compatible by
- including the following code near the beginning of your
- top-level SConstruct file:
-
- import SCons.Environment
- try:
- SCons.Environment.Environment.Clone
- except AttributeError:
- SCons.Environment.Environment.Clone = \
- SCons.Environment.Environment.Copy
-
- -- Use the EnsureSConsVersion() function to provide a
- descriptive error message if your SConscript files
- are executed by an earlier version of SCons:
-
- EnsureSConsVersion(0, 96, 93)
-
- -- THE CheckLib Configure TEST WILL CHANGE BEHAVIOR
-
- The CheckLib() Configure test appends the lib(s) to the
- Environment's LIBS list in 1.3 and earlier. In 1.3 there is a
- new CheckLib argument, append, which defaults to True to
- preserve the old behavior. In a future release, append will
- be changed to default to False, to conform with autoconf and
- user expectations, since it is usually used to build up
- library lists in a right-to-left way.
-
-
-
- SCons is developed with an extensive regression test suite, and a
- rigorous development methodology for continually improving that suite.
- Because of this, SCons is of sufficient quality that you can use it
- for real work.
-
- The interfaces in release 1.0 will *not* be knowingly changed in
- any new, future 1.x release. If an interface change should ever
- become necessary due to extraordinary circumstances, the change
- and an appropriate transition strategy will be documented in these
- RELEASE notes.
-
- As you use SCons, please heed the following:
-
- - Please report any bugs or other problems that you find to our bug
- tracker at our SourceForge project page:
-
- http://sourceforge.net/tracker/?func=add&group_id=30337&atid=398971
-
- We have a reliable bug-fixing methodology already in place and
- strive to respond to problems relatively quickly.
-
- - Documentation is spottier than we'd like. You may need to dive
- into the source code to figure out how to do something. Asking
- questions on the scons-users mailing list is also welcome. We
- will be addressing the documentation in upcoming releases, but
- would be more than glad to have your assistance in correcting this
- problem... :-)
-
- - The "SCons Design" documentation on the SCons web site is very
- out of date, as we made significant changes to portions of the
- interface as we figured out what worked and what didn't during the
- extensive beta implementation. The "SCons Design" document should
- be used only for historical purposes, or for just an extremely
- general understanding of SCons' architectural goals.
-
- - There may be performance issues. Improving SCons performance
- is an ongoing priority. If you still find the performance
- unacceptable, we would very much like to hear from you and learn
- more about your configuration so we can optimize the right things.
-
- - Error messages don't always exist where they'd be helpful.
- Please let us know about any errors you ran into that would
- have benefitted from a (more) descriptive message.
-
- KNOWN PROBLEMS IN THIS RELEASE:
-
- For a complete list of known problems, consult the SCons Issue Tracker
- at tigris.org:
-
- http://scons.tigris.org/project_issues.html
-
- - Support for parallel builds (-j) does not work on WIN32 systems
- prior to *official* Python release 2.2 (not 2.2 pre-releases).
-
- Prior to Python 2.2, there is a bug in Python's Win32
- implementation such that when a thread spawns an external command,
- it blocks all threads from running. This breaks the SCons
- multithreading architecture used to support -j builds.
-
- We have included a patch file, os_spawnv_fix.diff, that you can
- use if you you want to fix your version of Python to support
- parallel builds in SCons.
-
- - Again, the "SCons Design" documentation on the SCons web site is
- out of date. Take what you read there with a grain of salt.
-
- - On Win32 systems, you must put a space between the redirection
- characters < and >, and the specified files (or construction
- variable expansions):
-
- command < $SOURCE > $TARGET
-
- If you don't supply a space (for example, "<$SOURCE"), SCons will
- not recognize the redirection.
-
- - MSVC .res files are not rebuilt when icons change.
-
- - The -c option does not clean up .sconsign files or directories
- created as part of the build, and also does not clean up
- SideEffect files (for example, Visual Studio .pdb files).
-
- - When using multiple Repositories, changing the name of an include
- file can cause an old version of the file to be used.
-
- - There is currently no way to force use of a relative path (../*)
- for directories outside the top-level SConstruct file.
-
- - The Jar() Builder will, on its second or subsequent invocation,
- package up the .sconsign files that SCons uses to track signatures.
- You can work around this by using the SConsignFile() function
- to collect all of the .sconsign information into a single file
- outside of the directory being packaged by Jar().
-
- - SCons does not currently have a way to detect that an intermediate
- file has been corrupted from outside and should be rebuilt.
-
- - Unicode characters in path names do not work in all circumstances.
-
- - SCons does not currently automatically check out SConstruct or
- SConscript files from SCCS, RCS or BitKeeper.
-
- - No support yet for the following planned command-line options:
-
- -d -e -l --list-actions --list-derived --list-where
- -o --override -p -r -R -w --write-filenames
- -W --warn-undefined-variables
-
-
-
-Thank you for your interest, and please let us know how we can help
-improve SCons for your needs.
-
-Steven Knight
-knight at baldmt dot com
-http://www.baldmt.com/~knight/
-
-With plenty of help from the SCons Development team:
- Chad Austin
- Charles Crain
- Bill Deegan
- Steve Leblanc
- Greg Noel
- Gary Oberbrunner
- Anthony Roach
- Greg Spencer
- Christoph Wiedemann
+ Thanks to Greg Noel, Steven Knight, Dirk Baechle, William Deegan,and
+ W. Trevor King for their contributions to this release.
+Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
+src/RELEASE.txt 5023 2010/06/14 22:05:46 scons
diff --git a/src/engine/MANIFEST-xml.in b/src/engine/MANIFEST-xml.in
index f6ce08a..97f77e5 100644
--- a/src/engine/MANIFEST-xml.in
+++ b/src/engine/MANIFEST-xml.in
@@ -22,7 +22,6 @@ SCons/Tool/ar.xml
SCons/Tool/as.xml
SCons/Tool/bcc32.xml
SCons/Tool/c++.xml
-SCons/Tool/c++.xml
SCons/Tool/cc.xml
SCons/Tool/cvf.xml
SCons/Tool/default.xml
diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in
index 2185d30..dd0feaf 100644
--- a/src/engine/MANIFEST.in
+++ b/src/engine/MANIFEST.in
@@ -2,16 +2,13 @@ SCons/__init__.py
SCons/Action.py
SCons/Builder.py
SCons/compat/__init__.py
+SCons/compat/_scons_builtins.py
+SCons/compat/_scons_collections.py
+SCons/compat/_scons_dbm.py
SCons/compat/_scons_hashlib.py
-SCons/compat/_scons_itertools.py
-SCons/compat/_scons_optparse.py
+SCons/compat/_scons_io.py
SCons/compat/_scons_sets.py
-SCons/compat/_scons_sets15.py
-SCons/compat/_scons_shlex.py
SCons/compat/_scons_subprocess.py
-SCons/compat/_scons_textwrap.py
-SCons/compat/_scons_UserString.py
-SCons/compat/builtins.py
SCons/CacheDir.py
SCons/Conftest.py
SCons/cpp.py
diff --git a/src/engine/README.txt b/src/engine/README.txt
index 48690fc..f74ddd2 100644
--- a/src/engine/README.txt
+++ b/src/engine/README.txt
@@ -5,12 +5,12 @@
### A SEPARATE BUILD ENGINE PACKAGE IN THE FUTURE.
###
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-# src/engine/README.txt 4720 2010/03/24 03:14:11 jars
+# src/engine/README.txt 5023 2010/06/14 22:05:46 scons
SCons - a software construction tool
- Version 1.3.0
+ Version 2.0.0.final.0
This is an alpha release of the SCons build engine, a Python extension
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 3e766d9..7cad8a5 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -97,13 +97,15 @@ way for wrapping up the functions.
# 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__ = "src/engine/SCons/Action.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Action.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
-import cPickle
import dis
import os
+# compat layer imports "cPickle" for us if it's available.
+import pickle
import re
-import string
import sys
import subprocess
@@ -117,7 +119,7 @@ import SCons.Subst
is_String = SCons.Util.is_String
is_List = SCons.Util.is_List
-class _null:
+class _null(object):
pass
print_actions = 1
@@ -153,7 +155,7 @@ else:
else:
result.append(c)
i = i+1
- return string.join(result, '')
+ return ''.join(result)
strip_quotes = re.compile('^[\'"](.*)[\'"]$')
@@ -208,8 +210,8 @@ def _object_contents(obj):
except AttributeError:
# Should be a pickable Python object.
try:
- return cPickle.dumps(obj)
- except (cPickle.PicklingError, TypeError):
+ return pickle.dumps(obj)
+ except (pickle.PicklingError, TypeError):
# This is weird, but it seems that nested classes
# are unpickable. The Python docs say it should
# always be a PicklingError, but some Python
@@ -249,19 +251,19 @@ def _code_contents(code):
# Note that we also always ignore the first entry of co_consts
# which contains the function doc string. We assume that the
# function does not access its doc string.
- contents.append(',(' + string.join(map(_object_contents,code.co_consts[1:]),',') + ')')
+ contents.append(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')')
# The code contents depends on the variable names used to
# accessed global variable, as changing the variable name changes
# the variable actually accessed and therefore changes the
# function result.
- contents.append(',(' + string.join(map(_object_contents,code.co_names),',') + ')')
+ contents.append(',(' + ','.join(map(_object_contents,code.co_names)) + ')')
# The code contents depends on its actual code!!!
contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')')
- return string.join(contents, '')
+ return ''.join(contents)
def _function_contents(func):
@@ -271,7 +273,7 @@ def _function_contents(func):
# The function contents depends on the value of defaults arguments
if func.func_defaults:
- contents.append(',(' + string.join(map(_object_contents,func.func_defaults),',') + ')')
+ contents.append(',(' + ','.join(map(_object_contents,func.func_defaults)) + ')')
else:
contents.append(',()')
@@ -284,12 +286,12 @@ def _function_contents(func):
#xxx = [_object_contents(x.cell_contents) for x in closure]
try:
- xxx = map(lambda x: _object_contents(x.cell_contents), closure)
+ xxx = [_object_contents(x.cell_contents) for x in closure]
except AttributeError:
xxx = []
- contents.append(',(' + string.join(xxx, ',') + ')')
+ contents.append(',(' + ','.join(xxx) + ')')
- return string.join(contents, '')
+ return ''.join(contents)
def _actionAppend(act1, act2):
@@ -299,7 +301,7 @@ def _actionAppend(act1, act2):
a1 = Action(act1)
a2 = Action(act2)
if a1 is None or a2 is None:
- raise TypeError, "Cannot append %s to %s" % (type(act1), type(act2))
+ raise TypeError("Cannot append %s to %s" % (type(act1), type(act2)))
if isinstance(a1, ListAction):
if isinstance(a2, ListAction):
return ListAction(a1.list + a2.list)
@@ -353,8 +355,7 @@ def _do_create_action(act, kw):
return act
if is_List(act):
- #TODO(1.5) return CommandAction(act, **kw)
- return apply(CommandAction, (act,), kw)
+ return CommandAction(act, **kw)
if callable(act):
try:
@@ -378,10 +379,9 @@ def _do_create_action(act, kw):
# like a function or a CommandGenerator in that variable
# instead of a string.
return LazyAction(var, kw)
- commands = string.split(str(act), '\n')
+ commands = str(act).split('\n')
if len(commands) == 1:
- #TODO(1.5) return CommandAction(commands[0], **kw)
- return apply(CommandAction, (commands[0],), kw)
+ return CommandAction(commands[0], **kw)
# The list of string commands may include a LazyAction, so we
# reprocess them via _do_create_list_action.
return _do_create_list_action(commands, kw)
@@ -409,7 +409,7 @@ def Action(act, *args, **kw):
return _do_create_list_action(act, kw)
return _do_create_action(act, kw)
-class ActionBase:
+class ActionBase(object):
"""Base class for all types of action objects that can be held by
other objects (Builders, Executors, etc.) This provides the
common methods for manipulating and combining those actions."""
@@ -434,7 +434,7 @@ class ActionBase:
if is_String(vl): vl = (vl,)
for v in vl:
result.append(env.subst('${'+v+'}'))
- return string.join(result, '')
+ return ''.join(result)
def __add__(self, other):
return _actionAppend(self, other)
@@ -450,7 +450,7 @@ class ActionBase:
# and CommandGeneratorAction will use this env
# when it calls its _generate method.
self.presub_env = env
- lines = string.split(str(self), '\n')
+ lines = str(self).split('\n')
self.presub_env = None # don't need this any more
return lines
@@ -497,7 +497,7 @@ class _ActionAction(ActionBase):
SCons.Util.AddMethod(self, batch_key, 'batch_key')
def print_cmd_line(self, s, target, source, env):
- sys.stdout.write(s + "\n")
+ sys.stdout.write(s + u"\n")
def __call__(self, target, source, env,
exitstatfunc=_null,
@@ -534,9 +534,9 @@ class _ActionAction(ActionBase):
if executor:
target = executor.get_all_targets()
source = executor.get_all_sources()
- t = string.join(map(str, target), ' and ')
- l = string.join(self.presub_lines(env), '\n ')
- out = "Building %s with action:\n %s\n" % (t, l)
+ t = ' and '.join(map(str, target))
+ l = '\n '.join(self.presub_lines(env))
+ out = u"Building %s with action:\n %s\n" % (t, l)
sys.stdout.write(out)
cmd = None
if show and self.strfunction:
@@ -590,7 +590,7 @@ def _string_from_cmd_list(cmd_list):
if ' ' in arg or '\t' in arg:
arg = '"' + arg + '"'
cl.append(arg)
- return string.join(cl)
+ return ' '.join(cl)
# A fiddlin' little function that has an 'import SCons.Environment' which
# can't be moved to the top level without creating an import loop. Since
@@ -617,7 +617,7 @@ def get_default_ENV(env):
# it in the long run as more and more places use subprocess, but I'm sure
# it'll have to be tweaked to get the full desired functionality.
# one special arg (so far?), 'error', to tell what to do with exceptions.
-def _subproc(env, cmd, error = 'ignore', **kw):
+def _subproc(scons_env, cmd, error = 'ignore', **kw):
"""Do common setup for a subprocess.Popen() call"""
# allow std{in,out,err} to be "'devnull'"
io = kw.get('stdin')
@@ -632,7 +632,7 @@ def _subproc(env, cmd, error = 'ignore', **kw):
# Figure out what shell environment to use
ENV = kw.get('env', None)
- if ENV is None: ENV = get_default_ENV(env)
+ if ENV is None: ENV = get_default_ENV(scons_env)
# Ensure that the ENV values are all strings:
new_env = {}
@@ -642,7 +642,7 @@ def _subproc(env, cmd, error = 'ignore', **kw):
# because that's a pretty common list-like value to stick
# in an environment variable:
value = SCons.Util.flatten_sequence(value)
- new_env[key] = string.join(map(str, value), os.pathsep)
+ new_env[key] = os.pathsep.join(map(str, value))
else:
# It's either a string or something else. If it's a string,
# we still want to call str() because it might be a *Unicode*
@@ -655,16 +655,16 @@ def _subproc(env, cmd, error = 'ignore', **kw):
try:
#FUTURE return subprocess.Popen(cmd, **kw)
- return apply(subprocess.Popen, (cmd,), kw)
+ return subprocess.Popen(cmd, **kw)
except EnvironmentError, e:
if error == 'raise': raise
# return a dummy Popen instance that only returns error
- class dummyPopen:
+ class dummyPopen(object):
def __init__(self, e): self.exception = e
def communicate(self): return ('','')
def wait(self): return -self.exception.errno
stdin = None
- class f:
+ class f(object):
def read(self): return ''
def readline(self): return ''
stdout = stderr = f()
@@ -684,17 +684,16 @@ class CommandAction(_ActionAction):
# variables.
if __debug__: logInstanceCreation(self, 'Action.CommandAction')
- #TODO(1.5) _ActionAction.__init__(self, **kw)
- apply(_ActionAction.__init__, (self,), kw)
+ _ActionAction.__init__(self, **kw)
if is_List(cmd):
- if filter(is_List, cmd):
- raise TypeError, "CommandAction should be given only " \
- "a single command"
+ if list(filter(is_List, cmd)):
+ raise TypeError("CommandAction should be given only " \
+ "a single command")
self.cmd_list = cmd
def __str__(self):
if is_List(self.cmd_list):
- return string.join(map(str, self.cmd_list), ' ')
+ return ' '.join(map(str, self.cmd_list))
return str(self.cmd_list)
def process(self, target, source, env, executor=None):
@@ -704,7 +703,7 @@ class CommandAction(_ActionAction):
result = env.subst_list(self.cmd_list, 0, target, source)
silent = None
ignore = None
- while 1:
+ while True:
try: c = result[0][0][0]
except IndexError: c = None
if c == '@': silent = 1
@@ -771,7 +770,7 @@ class CommandAction(_ActionAction):
# path list, because that's a pretty common list-like
# value to stick in an environment variable:
value = flatten_sequence(value)
- ENV[key] = string.join(map(str, value), os.pathsep)
+ ENV[key] = os.pathsep.join(map(str, value))
else:
# If it isn't a string or a list, then we just coerce
# it to a string, which is the proper way to handle
@@ -782,7 +781,7 @@ class CommandAction(_ActionAction):
if executor:
target = executor.get_all_targets()
source = executor.get_all_sources()
- cmd_list, ignore, silent = self.process(target, map(rfile, source), env, executor)
+ cmd_list, ignore, silent = self.process(target, list(map(rfile, source)), env, executor)
# Use len() to filter out any "command" that's zero-length.
for cmd_line in filter(len, cmd_list):
@@ -806,7 +805,7 @@ class CommandAction(_ActionAction):
from SCons.Subst import SUBST_SIG
cmd = self.cmd_list
if is_List(cmd):
- cmd = string.join(map(str, cmd))
+ cmd = ' '.join(map(str, cmd))
else:
cmd = str(cmd)
if executor:
@@ -859,8 +858,7 @@ class CommandGeneratorAction(ActionBase):
source=source,
env=env,
for_signature=for_signature)
- #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw)
- gen_cmd = apply(Action, (ret,), self.gen_kw)
+ gen_cmd = Action(ret, **self.gen_kw)
if not gen_cmd:
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
return gen_cmd
@@ -885,7 +883,9 @@ class CommandGeneratorAction(ActionBase):
show=_null, execute=_null, chdir=_null, executor=None):
act = self._generate(target, source, env, 0, executor)
if act is None:
- raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
+ raise UserError("While building `%s': "
+ "Cannot deduce file extension from source files: %s"
+ % (repr(list(map(str, target))), repr(list(map(str, source)))))
return act(target, source, env, exitstatfunc, presub,
show, execute, chdir, executor)
@@ -930,7 +930,7 @@ class LazyAction(CommandGeneratorAction, CommandAction):
def __init__(self, var, kw):
if __debug__: logInstanceCreation(self, 'Action.LazyAction')
#FUTURE CommandAction.__init__(self, '${'+var+'}', **kw)
- apply(CommandAction.__init__, (self, '${'+var+'}'), kw)
+ CommandAction.__init__(self, '${'+var+'}', **kw)
self.var = SCons.Util.to_String(var)
self.gen_kw = kw
@@ -945,8 +945,7 @@ class LazyAction(CommandGeneratorAction, CommandAction):
c = env.get(self.var, '')
else:
c = ''
- #TODO(1.5) gen_cmd = Action(c, **self.gen_kw)
- gen_cmd = apply(Action, (c,), self.gen_kw)
+ gen_cmd = Action(c, **self.gen_kw)
if not gen_cmd:
raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
return gen_cmd
@@ -955,10 +954,8 @@ class LazyAction(CommandGeneratorAction, CommandAction):
return self._generate_cache(env)
def __call__(self, target, source, env, *args, **kw):
- args = (self, target, source, env) + args
c = self.get_parent_class(env)
- #TODO(1.5) return c.__call__(*args, **kw)
- return apply(c.__call__, args, kw)
+ return c.__call__(self, target, source, env, *args, **kw)
def get_presig(self, target, source, env):
c = self.get_parent_class(env)
@@ -986,8 +983,7 @@ class FunctionAction(_ActionAction):
# This is weird, just do the best we can.
self.funccontents = _object_contents(execfunction)
- #TODO(1.5) _ActionAction.__init__(self, **kw)
- apply(_ActionAction.__init__, (self,), kw)
+ _ActionAction.__init__(self, **kw)
def function_name(self):
try:
@@ -1018,7 +1014,7 @@ class FunctionAction(_ActionAction):
else:
s = str_for_display()
return s
- return '[' + string.join(map(quote, a), ", ") + ']'
+ return '[' + ", ".join(map(quote, a)) + ']'
try:
strfunc = self.execfunction.strfunction
except AttributeError:
@@ -1045,7 +1041,7 @@ class FunctionAction(_ActionAction):
if executor:
target = executor.get_all_targets()
source = executor.get_all_sources()
- rsources = map(rfile, source)
+ rsources = list(map(rfile, source))
try:
result = self.execfunction(target=target, source=rsources, env=env)
except KeyboardInterrupt, e:
@@ -1095,40 +1091,34 @@ class FunctionAction(_ActionAction):
class ListAction(ActionBase):
"""Class for lists of other actions."""
- def __init__(self, list):
+ def __init__(self, actionlist):
if __debug__: logInstanceCreation(self, 'Action.ListAction')
def list_of_actions(x):
if isinstance(x, ActionBase):
return x
return Action(x)
- self.list = map(list_of_actions, list)
+ self.list = list(map(list_of_actions, actionlist))
# our children will have had any varlist
# applied; we don't need to do it again
self.varlist = ()
self.targets = '$TARGETS'
def genstring(self, target, source, env):
- return string.join(map(lambda a, t=target, s=source, e=env:
- a.genstring(t, s, e),
- self.list),
- '\n')
+ return '\n'.join([a.genstring(target, source, env) for a in self.list])
def __str__(self):
- return string.join(map(str, self.list), '\n')
+ return '\n'.join(map(str, self.list))
def presub_lines(self, env):
return SCons.Util.flatten_sequence(
- map(lambda a, env=env: a.presub_lines(env), self.list))
+ [a.presub_lines(env) for a in self.list])
def get_presig(self, target, source, env):
"""Return the signature contents of this action list.
Simple concatenation of the signatures of the elements.
"""
- return string.join(map(lambda x, t=target, s=source, e=env:
- x.get_contents(t, s, e),
- self.list),
- "")
+ return "".join([x.get_contents(target, source, env) for x in self.list])
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
show=_null, execute=_null, chdir=_null, executor=None):
@@ -1153,9 +1143,9 @@ class ListAction(ActionBase):
for act in self.list:
for var in act.get_varlist(target, source, env, executor):
result[var] = True
- return result.keys()
+ return list(result.keys())
-class ActionCaller:
+class ActionCaller(object):
"""A class for delaying calling an Action function with specific
(positional and keyword) arguments until the Action is actually
executed.
@@ -1204,9 +1194,7 @@ class ActionCaller:
return self.parent.convert(s)
def subst_args(self, target, source, env):
- return map(lambda x, self=self, t=target, s=source, e=env:
- self.subst(x, t, s, e),
- self.args)
+ return [self.subst(x, target, source, env) for x in self.args]
def subst_kw(self, target, source, env):
kw = {}
@@ -1217,20 +1205,17 @@ class ActionCaller:
def __call__(self, target, source, env, executor=None):
args = self.subst_args(target, source, env)
kw = self.subst_kw(target, source, env)
- #TODO(1.5) return self.parent.actfunc(*args, **kw)
- return apply(self.parent.actfunc, args, kw)
+ return self.parent.actfunc(*args, **kw)
def strfunction(self, target, source, env):
args = self.subst_args(target, source, env)
kw = self.subst_kw(target, source, env)
- #TODO(1.5) return self.parent.strfunc(*args, **kw)
- return apply(self.parent.strfunc, args, kw)
+ return self.parent.strfunc(*args, **kw)
def __str__(self):
- #TODO(1.5) return self.parent.strfunc(*self.args, **self.kw)
- return apply(self.parent.strfunc, self.args, self.kw)
+ return self.parent.strfunc(*self.args, **self.kw)
-class ActionFactory:
+class ActionFactory(object):
"""A factory class that will wrap up an arbitrary function
as an SCons-executable Action object.
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index d910b25..2541572 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -21,7 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/ActionTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/ActionTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
# Define a null function and a null class for use as builder actions.
# Where these are defined in the file seems to affect their byte-code
@@ -30,18 +32,17 @@ __revision__ = "src/engine/SCons/ActionTests.py 4720 2010/03/24 03:14:11 jars"
def GlobalFunc():
pass
-class GlobalActFunc:
+class GlobalActFunc(object):
def __call__(self):
pass
+import collections
+import io
import os
import re
-import StringIO
-import string
import sys
import types
import unittest
-import UserDict
import SCons.Action
import SCons.Environment
@@ -68,16 +69,16 @@ try:
except:
pass
f.close()
-if os.environ.has_key( 'ACTPY_PIPE' ):
- if os.environ.has_key( 'PIPE_STDOUT_FILE' ):
+if 'ACTPY_PIPE' in os.environ:
+ if 'PIPE_STDOUT_FILE' in os.environ:
stdout_msg = open(os.environ['PIPE_STDOUT_FILE'], 'r').read()
else:
- stdout_msg = "act.py: stdout: executed act.py %s\\n" % string.join(sys.argv[1:])
+ stdout_msg = "act.py: stdout: executed act.py %s\\n" % ' '.join(sys.argv[1:])
sys.stdout.write( stdout_msg )
- if os.environ.has_key( 'PIPE_STDERR_FILE' ):
+ if 'PIPE_STDERR_FILE' in os.environ:
stderr_msg = open(os.environ['PIPE_STDERR_FILE'], 'r').read()
else:
- stderr_msg = "act.py: stderr: executed act.py %s\\n" % string.join(sys.argv[1:])
+ stderr_msg = "act.py: stderr: executed act.py %s\\n" % ' '.join(sys.argv[1:])
sys.stderr.write( stderr_msg )
sys.exit(0)
""")
@@ -98,9 +99,9 @@ scons_env = SCons.Environment.Environment()
# Capture all the stuff the Actions will print,
# so it doesn't clutter the output.
-sys.stdout = StringIO.StringIO()
+sys.stdout = io.StringIO()
-class CmdStringHolder:
+class CmdStringHolder(object):
def __init__(self, cmd, literal=None):
self.data = str(cmd)
self.literal = literal
@@ -125,7 +126,7 @@ class CmdStringHolder:
else:
return self.data
-class Environment:
+class Environment(object):
def __init__(self, **kw):
self.d = {}
self.d['SHELL'] = scons_env['SHELL']
@@ -147,11 +148,11 @@ class Environment:
def __setitem__(self, item, value):
self.d[item] = value
def has_key(self, item):
- return self.d.has_key(item)
+ return item in self.d
def get(self, key, value=None):
return self.d.get(key, value)
def items(self):
- return self.d.items()
+ return list(self.d.items())
def Dictionary(self):
return self.d
def Clone(self, **kw):
@@ -169,7 +170,7 @@ class Environment:
d['SOURCE'] = d['SOURCES'][0]
return d
-class DummyNode:
+class DummyNode(object):
def __init__(self, name):
self.name = name
def str_for_display(self):
@@ -192,8 +193,7 @@ _null = SCons.Action._null
def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw):
def call_action(a, pos_call=pos_call, str_call=str_call, kw=kw):
- #FUTURE a = SCons.Action.Action(*a, **kw)
- a = apply(SCons.Action.Action, a, kw)
+ a = SCons.Action.Action(*a, **kw)
# returned object must provide these entry points
assert hasattr(a, '__call__')
assert hasattr(a, 'get_contents')
@@ -229,7 +229,7 @@ def test_positional_args(pos_callback, cmd, **kw):
"""Test that Action() returns the expected type and that positional args work.
"""
#FUTURE act = SCons.Action.Action(cmd, **kw)
- act = apply(SCons.Action.Action, (cmd,), kw)
+ act = SCons.Action.Action(cmd, **kw)
pos_callback(act)
assert act.varlist is (), act.varlist
@@ -237,7 +237,7 @@ def test_positional_args(pos_callback, cmd, **kw):
# only valid cmdstrfunc is None
def none(a): pass
#FUTURE test_varlist(pos_callback, none, cmd, None, **kw)
- apply(test_varlist, (pos_callback, none, cmd, None), kw)
+ test_varlist(pos_callback, none, cmd, None, **kw)
else:
# _ActionAction should have set these
assert hasattr(act, 'strfunction')
@@ -251,31 +251,31 @@ def test_positional_args(pos_callback, cmd, **kw):
assert hasattr(a, 'strfunction')
assert a.cmdstr == 'cmdstr', a.cmdstr
#FUTURE test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw)
- apply(test_varlist, (pos_callback, cmdstr, cmd, 'cmdstr'), kw)
+ test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw)
def fun(): pass
def strfun(a, fun=fun):
assert a.strfunction is fun, a.strfunction
assert a.cmdstr == _null, a.cmdstr
#FUTURE test_varlist(pos_callback, strfun, cmd, fun, **kw)
- apply(test_varlist, (pos_callback, strfun, cmd, fun), kw)
+ test_varlist(pos_callback, strfun, cmd, fun, **kw)
def none(a):
assert hasattr(a, 'strfunction')
assert a.cmdstr is None, a.cmdstr
#FUTURE test_varlist(pos_callback, none, cmd, None, **kw)
- apply(test_varlist, (pos_callback, none, cmd, None), kw)
+ test_varlist(pos_callback, none, cmd, None, **kw)
"""Test handling of bad cmdstrfunc arguments """
try:
#FUTURE a = SCons.Action.Action(cmd, [], **kw)
- a = apply(SCons.Action.Action, (cmd, []), kw)
+ a = SCons.Action.Action(cmd, [], **kw)
except SCons.Errors.UserError, e:
s = str(e)
m = 'Invalid command display variable'
- assert string.find(s, m) != -1, 'Unexpected string: %s' % s
+ assert s.find(m) != -1, 'Unexpected string: %s' % s
else:
- raise Exception, "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
return act
@@ -305,7 +305,9 @@ class ActionTestCase(unittest.TestCase):
# a singleton list returns the contained action
test_positional_args(cmd_action, ["string"])
- if hasattr(types, 'UnicodeType'):
+ try: unicode
+ except NameError: pass
+ else:
a2 = eval("SCons.Action.Action(u'string')")
assert isinstance(a2, SCons.Action.CommandAction), a2
@@ -490,9 +492,9 @@ class _ActionActionTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
s = str(e)
m = 'Cannot have both strfunction and cmdstr args to Action()'
- assert string.find(s, m) != -1, 'Unexpected string: %s' % s
+ assert s.find(m) != -1, 'Unexpected string: %s' % s
else:
- raise Exception, "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def test___cmp__(self):
"""Test Action comparison
@@ -514,7 +516,7 @@ class _ActionActionTestCase(unittest.TestCase):
pass
a = SCons.Action.Action(execfunc)
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
a.print_cmd_line("foo bar", None, None, None)
s = sio.getvalue()
@@ -541,22 +543,22 @@ class _ActionActionTestCase(unittest.TestCase):
env = Environment()
def execfunc(target, source, env):
- assert type(target) is type([]), type(target)
- assert type(source) is type([]), type(source)
+ assert isinstance(target, list), type(target)
+ assert isinstance(source, list), type(source)
return 7
a = SCons.Action.Action(execfunc)
def firstfunc(target, source, env):
- assert type(target) is type([]), type(target)
- assert type(source) is type([]), type(source)
+ assert isinstance(target, list), type(target)
+ assert isinstance(source, list), type(source)
return 0
def lastfunc(target, source, env):
- assert type(target) is type([]), type(target)
- assert type(source) is type([]), type(source)
+ assert isinstance(target, list), type(target)
+ assert isinstance(source, list), type(source)
return 9
b = SCons.Action.Action([firstfunc, execfunc, lastfunc])
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env)
assert result.status == 7, result
@@ -566,14 +568,14 @@ class _ActionActionTestCase(unittest.TestCase):
a.chdir = 'xyz'
expect = "os.chdir(%s)\nexecfunc(['out'], ['in'])\nos.chdir(%s)\n"
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == expect % (repr('xyz'), repr(test.workpath())), s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env, chdir='sub')
assert result.status == 7, result.status
@@ -582,7 +584,7 @@ class _ActionActionTestCase(unittest.TestCase):
a.chdir = None
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = b("out", "in", env)
assert result.status == 7, result.status
@@ -591,14 +593,14 @@ class _ActionActionTestCase(unittest.TestCase):
SCons.Action.execute_actions = 0
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env)
assert result == 0, result
s = sio.getvalue()
assert s == "execfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = b("out", "in", env)
assert result == 0, result
@@ -608,35 +610,35 @@ class _ActionActionTestCase(unittest.TestCase):
SCons.Action.print_actions_presub = 1
SCons.Action.execute_actions = 1
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == "Building out with action:\n execfunc(target, source, env)\nexecfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env, presub=0)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == "execfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env, presub=1)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == "Building out with action:\n execfunc(target, source, env)\nexecfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = b(["out"], "in", env, presub=1)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == "Building out with action:\n firstfunc(target, source, env)\nfirstfunc(['out'], ['in'])\nBuilding out with action:\n execfunc(target, source, env)\nexecfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = b(["out", "list"], "in", env, presub=1)
assert result.status == 7, result.status
@@ -645,14 +647,14 @@ class _ActionActionTestCase(unittest.TestCase):
a2 = SCons.Action.Action(execfunc)
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a2("out", "in", env)
assert result.status == 7, result.status
s = sio.getvalue()
assert s == "Building out with action:\n execfunc(target, source, env)\nexecfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a2("out", "in", env, presub=0)
assert result.status == 7, result.status
@@ -661,14 +663,14 @@ class _ActionActionTestCase(unittest.TestCase):
SCons.Action.execute_actions = 0
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a2("out", "in", env, presub=0)
assert result == 0, result
s = sio.getvalue()
assert s == "execfunc(['out'], ['in'])\n", s
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
result = a("out", "in", env, presub=0, execute=1, show=0)
assert result.status == 7, result.status
@@ -752,8 +754,7 @@ class _ActionActionTestCase(unittest.TestCase):
sum = act1 + act2
assert isinstance(sum, SCons.Action.ListAction), str(sum)
assert len(sum.list) == 3, len(sum.list)
- assert map(lambda x: isinstance(x, SCons.Action.ActionBase),
- sum.list) == [ 1, 1, 1 ]
+ assert [isinstance(x, SCons.Action.ActionBase) for x in sum.list] == [ 1, 1, 1 ]
sum = act1 + act1
assert isinstance(sum, SCons.Action.ListAction), str(sum)
@@ -949,17 +950,17 @@ class CommandActionTestCase(unittest.TestCase):
s = act.strfunction([], [], env)
assert s == "sf was called", s
- class actclass1:
+ class actclass1(object):
def __init__(self, targets, sources, env):
pass
def __call__(self):
return 1
- class actclass2:
+ class actclass2(object):
def __init__(self, targets, sources, env):
self.strfunction = 5
def __call__(self):
return 2
- class actclass3:
+ class actclass3(object):
def __init__(self, targets, sources, env):
pass
def __call__(self):
@@ -967,7 +968,7 @@ class CommandActionTestCase(unittest.TestCase):
def strfunction(self, targets, sources, env):
return 'actclass3 on %s to get %s'%(str(sources[0]),
str(targets[0]))
- class actclass4:
+ class actclass4(object):
def __init__(self, targets, sources, env):
pass
def __call__(self):
@@ -1050,7 +1051,7 @@ class CommandActionTestCase(unittest.TestCase):
cmd3 = r'%s %s %s ${TARGETS}' % (_python_, act_py, outfile)
act = SCons.Action.CommandAction(cmd3)
- r = act(map(DummyNode, ['aaa', 'bbb']), [], env.Clone())
+ r = act(list(map(DummyNode, ['aaa', 'bbb'])), [], env.Clone())
assert r == 0
c = test.read(outfile, 'r')
assert c == "act.py: 'aaa' 'bbb'\n", c
@@ -1077,7 +1078,7 @@ class CommandActionTestCase(unittest.TestCase):
act = SCons.Action.CommandAction(cmd5)
env5 = Environment()
- if scons_env.has_key('ENV'):
+ if 'ENV' in scons_env:
env5['ENV'] = scons_env['ENV']
PATH = scons_env['ENV'].get('PATH', '')
else:
@@ -1096,7 +1097,7 @@ class CommandActionTestCase(unittest.TestCase):
c = test.read(outfile, 'r')
assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy5'\n", c
- class Obj:
+ class Obj(object):
def __init__(self, str):
self._str = str
def __str__(self):
@@ -1127,6 +1128,10 @@ class CommandActionTestCase(unittest.TestCase):
# Newer cygwin seems to return 126 for following
expect_nonexecutable_file = 126
expect_nonexecutable_dir = 127
+ elif sys.platform.find('sunos') != -1:
+ expect_nonexistent = 1
+ expect_nonexecutable_file = 1
+ expect_nonexecutable_dir = 1
else:
expect_nonexistent = 127
expect_nonexecutable_file = 126
@@ -1254,7 +1259,7 @@ class CommandActionTestCase(unittest.TestCase):
def test_set_handler(self):
"""Test setting the command handler...
"""
- class Test:
+ class Test(object):
def __init__(self):
self.executed = 0
t=Test()
@@ -1265,7 +1270,7 @@ class CommandActionTestCase(unittest.TestCase):
def escape_func(cmd):
return '**' + cmd + '**'
- class LiteralStr:
+ class LiteralStr(object):
def __init__(self, x):
self.data = x
def __str__(self):
@@ -1332,8 +1337,8 @@ class CommandActionTestCase(unittest.TestCase):
# that scheme, then all of the '__t1__' and '__s6__' file names
# in the asserts below would change to 't1' and 's6' and the
# like.
- t = map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6'])
- s = map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6'])
+ t = list(map(DummyNode, ['t1', 't2', 't3', 't4', 't5', 't6']))
+ s = list(map(DummyNode, ['s1', 's2', 's3', 's4', 's5', 's6']))
env = Environment()
a = SCons.Action.CommandAction(["$TARGET"])
@@ -1451,7 +1456,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
assert self.dummy==2, self.dummy
del self.dummy
- class DummyFile:
+ class DummyFile(object):
def __init__(self, t):
self.t = t
def rfile(self):
@@ -1505,9 +1510,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def f_global(target, source, env, for_signature):
return SCons.Action.Action(GlobalFunc)
- # TODO(1.5):
- #def f_local(target, source, env, for_signature):
- def f_local(target, source, env, for_signature, LocalFunc=LocalFunc):
+ def f_local(target, source, env, for_signature):
return SCons.Action.Action(LocalFunc)
env = Environment(XYZ = 'foo')
@@ -1523,12 +1526,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase):
def f_global(target, source, env, for_signature):
return SCons.Action.Action(GlobalFunc, varlist=['XYZ'])
- # TODO(1.5):
- #def f_local(target, source, env, for_signature):
- def f_local(target, source, env, for_signature, LocalFunc=LocalFunc):
+ def f_local(target, source, env, for_signature):
return SCons.Action.Action(LocalFunc, varlist=['XYZ'])
- matches_foo = map(lambda x: x + "foo", func_matches)
+ matches_foo = [x + "foo" for x in func_matches]
a = self.factory(f_global)
c = a.get_contents(target=[], source=[], env=env)
@@ -1570,7 +1571,7 @@ class FunctionActionTestCase(unittest.TestCase):
s = str(a)
assert s == "func1(target, source, env)", s
- class class1:
+ class class1(object):
def __call__(self):
pass
a = SCons.Action.FunctionAction(class1(), {})
@@ -1614,7 +1615,7 @@ class FunctionActionTestCase(unittest.TestCase):
c = test.read(outfile2, 'r')
assert c == "function1\n", c
- class class1a:
+ class class1a(object):
def __init__(self, target, source, env):
open(env['out'], 'w').write("class1a\n")
@@ -1624,7 +1625,7 @@ class FunctionActionTestCase(unittest.TestCase):
c = test.read(outfile, 'r')
assert c == "class1a\n", c
- class class1b:
+ class class1b(object):
def __call__(self, target, source, env):
open(env['out'], 'w').write("class1b\n")
return 2
@@ -1676,7 +1677,7 @@ class FunctionActionTestCase(unittest.TestCase):
c = a.get_contents(target=[], source=[], env=Environment())
assert c in func_matches, repr(c)
- matches_foo = map(lambda x: x + "foo", func_matches)
+ matches_foo = [x + "foo" for x in func_matches]
a = factory(GlobalFunc, varlist=['XYZ'])
c = a.get_contents(target=[], source=[], env=Environment())
@@ -1692,14 +1693,14 @@ class FunctionActionTestCase(unittest.TestCase):
c = a.get_contents(target=[], source=[], env=Environment(XYZ='foo'))
assert c in matches_foo, repr(c)
- class Foo:
+ class Foo(object):
def get_contents(self, target, source, env):
return 'xyzzy'
a = factory(Foo())
c = a.get_contents(target=[], source=[], env=Environment())
assert c == 'xyzzy', repr(c)
- class LocalClass:
+ class LocalClass(object):
def LocalMethod(self):
pass
lc = LocalClass()
@@ -1781,12 +1782,12 @@ class ListActionTestCase(unittest.TestCase):
open(env['out'], 'a').write("function2\n")
return 0
- class class2a:
+ class class2a(object):
def __call__(self, target, source, env):
open(env['out'], 'a').write("class2a\n")
return 0
- class class2b:
+ class class2b(object):
def __init__(self, target, source, env):
open(env['out'], 'a').write("class2b\n")
act = SCons.Action.ListAction([cmd2, function2, class2a(), class2b])
@@ -1892,7 +1893,7 @@ class LazyActionTestCase(unittest.TestCase):
c = a.get_contents(target=[], source=[], env=env)
assert c in func_matches, repr(c)
- matches_foo = map(lambda x: x + "foo", func_matches)
+ matches_foo = [x + "foo" for x in func_matches]
env = Environment(FOO = factory(GlobalFunc, varlist=['XYZ']))
c = a.get_contents(target=[], source=[], env=env)
@@ -1938,7 +1939,7 @@ class ActionCallerTestCase(unittest.TestCase):
"d\x00\x00S"
]
- class LocalActFunc:
+ class LocalActFunc(object):
def __call__(self):
pass
@@ -2096,7 +2097,7 @@ if __name__ == "__main__":
ActionCompareTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 7a9a028..3b4f2e8 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -96,12 +96,10 @@ There are the following methods for internal use within this module:
# 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__ = "src/engine/SCons/Builder.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Builder.py 5023 2010/06/14 22:05:46 scons"
-import UserDict
-import UserList
+import collections
import SCons.Action
from SCons.Debug import logInstanceCreation
@@ -113,17 +111,16 @@ import SCons.Node.FS
import SCons.Util
import SCons.Warnings
-class _Null:
+class _Null(object):
pass
_null = _Null
def match_splitext(path, suffixes = []):
if suffixes:
- matchsuf = filter(lambda S,path=path: path[-len(S):] == S,
- suffixes)
+ matchsuf = [S for S in suffixes if path[-len(S):] == S]
if matchsuf:
- suf = max(map(None, map(len, matchsuf), matchsuf))[1]
+ suf = max([(len(_f),_f) for _f in matchsuf])[1]
return [path[:-len(suf)], path[-len(suf):]]
return SCons.Util.splitext(path)
@@ -139,7 +136,7 @@ class DictCmdGenerator(SCons.Util.Selector):
self.source_ext_match = source_ext_match
def src_suffixes(self):
- return self.keys()
+ return list(self.keys())
def add_action(self, suffix, action):
"""Add a suffix-action pair to the mapping.
@@ -156,22 +153,25 @@ class DictCmdGenerator(SCons.Util.Selector):
for src in map(str, source):
my_ext = match_splitext(src, suffixes)[1]
if ext and my_ext != ext:
- raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" % (repr(map(str, target)), src, ext, my_ext))
+ raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s"
+ % (repr(list(map(str, target))), src, ext, my_ext))
ext = my_ext
else:
ext = match_splitext(str(source[0]), self.src_suffixes())[1]
if not ext:
#return ext
- raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
+ raise UserError("While building `%s': "
+ "Cannot deduce file extension from source files: %s"
+ % (repr(list(map(str, target))), repr(list(map(str, source)))))
try:
ret = SCons.Util.Selector.__call__(self, env, source, ext)
except KeyError, e:
- raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e[0], e[1], e[2]))
+ 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." % \
- (repr(map(str, target)), repr(map(str, source)), ext, repr(self.keys())))
+ (repr(list(map(str, target))), repr(list(map(str, source))), ext, repr(list(self.keys()))))
return ret
class CallableSelector(SCons.Util.Selector):
@@ -197,7 +197,7 @@ class DictEmitter(SCons.Util.Selector):
target, source = emitter(target, source, env)
return (target, source)
-class ListEmitter(UserList.UserList):
+class ListEmitter(collections.UserList):
"""A callable list of emitters that calls each in sequence,
returning the result.
"""
@@ -215,7 +215,7 @@ misleading_keywords = {
'sources' : 'source',
}
-class OverrideWarner(UserDict.UserDict):
+class OverrideWarner(collections.UserDict):
"""A class for warning about keyword arguments that we use as
overrides in a Builder call.
@@ -224,14 +224,14 @@ class OverrideWarner(UserDict.UserDict):
warnings once, no matter how many Builders are invoked.
"""
def __init__(self, dict):
- UserDict.UserDict.__init__(self, dict)
+ collections.UserDict.__init__(self, dict)
if __debug__: logInstanceCreation(self, 'Builder.OverrideWarner')
self.already_warned = None
def warn(self):
if self.already_warned:
return
for k in self.keys():
- if misleading_keywords.has_key(k):
+ if k in misleading_keywords:
alt = misleading_keywords[k]
msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k)
SCons.Warnings.warn(SCons.Warnings.MisleadingKeywordsWarning, msg)
@@ -240,14 +240,14 @@ class OverrideWarner(UserDict.UserDict):
def Builder(**kw):
"""A factory for builder objects."""
composite = None
- if kw.has_key('generator'):
- if kw.has_key('action'):
- raise UserError, "You must not specify both an action and a generator."
+ if 'generator' in kw:
+ if 'action' in kw:
+ raise UserError("You must not specify both an action and a generator.")
kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'], {})
del kw['generator']
- elif kw.has_key('action'):
+ elif 'action' in kw:
source_ext_match = kw.get('source_ext_match', 1)
- if kw.has_key('source_ext_match'):
+ if 'source_ext_match' in kw:
del kw['source_ext_match']
if SCons.Util.is_Dict(kw['action']):
composite = DictCmdGenerator(kw['action'], source_ext_match)
@@ -256,7 +256,7 @@ def Builder(**kw):
else:
kw['action'] = SCons.Action.Action(kw['action'])
- if kw.has_key('emitter'):
+ if 'emitter' in kw:
emitter = kw['emitter']
if SCons.Util.is_String(emitter):
# This allows users to pass in an Environment
@@ -265,14 +265,14 @@ def Builder(**kw):
# a callable to use as the actual emitter.
var = SCons.Util.get_environment_var(emitter)
if not var:
- raise UserError, "Supplied emitter '%s' does not appear to refer to an Environment variable" % emitter
+ raise UserError("Supplied emitter '%s' does not appear to refer to an Environment variable" % emitter)
kw['emitter'] = EmitterProxy(var)
elif SCons.Util.is_Dict(emitter):
kw['emitter'] = DictEmitter(emitter)
elif SCons.Util.is_List(emitter):
kw['emitter'] = ListEmitter(emitter)
- result = apply(BuilderBase, (), kw)
+ result = BuilderBase(**kw)
if not composite is None:
result = CompositeBuilder(result, composite)
@@ -289,7 +289,7 @@ def _node_errors(builder, env, tlist, slist):
# were specified.
for t in tlist:
if t.side_effect:
- raise UserError, "Multiple ways to build the same target were specified for: %s" % t
+ raise UserError("Multiple ways to build the same target were specified for: %s" % t)
if t.has_explicit_builder():
if not t.env is None and not t.env is env:
action = t.builder.action
@@ -301,24 +301,24 @@ def _node_errors(builder, env, tlist, slist):
SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg)
else:
msg = "Two environments with different actions were specified for the same target: %s" % t
- raise UserError, msg
+ raise UserError(msg)
if builder.multi:
if t.builder != builder:
msg = "Two different builders (%s and %s) were specified for the same target: %s" % (t.builder.get_name(env), builder.get_name(env), t)
- raise UserError, msg
+ raise UserError(msg)
# TODO(batch): list constructed each time!
if t.get_executor().get_all_targets() != tlist:
- msg = "Two different target lists have a target in common: %s (from %s and from %s)" % (t, map(str, t.get_executor().get_all_targets()), map(str, tlist))
- raise UserError, msg
+ msg = "Two different target lists have a target in common: %s (from %s and from %s)" % (t, list(map(str, t.get_executor().get_all_targets())), list(map(str, tlist)))
+ raise UserError(msg)
elif t.sources != slist:
- msg = "Multiple ways to build the same target were specified for: %s (from %s and from %s)" % (t, map(str, t.sources), map(str, slist))
- raise UserError, msg
+ msg = "Multiple ways to build the same target were specified for: %s (from %s and from %s)" % (t, list(map(str, t.sources)), list(map(str, slist)))
+ raise UserError(msg)
if builder.single_source:
if len(slist) > 1:
- raise UserError, "More than one source given for single-source builder: targets=%s sources=%s" % (map(str,tlist), map(str,slist))
+ raise UserError("More than one source given for single-source builder: targets=%s sources=%s" % (list(map(str,tlist)), list(map(str,slist))))
-class EmitterProxy:
+class EmitterProxy(object):
"""This is a callable class that can act as a
Builder emitter. It holds on to a string that
is a key into an Environment dictionary, and will
@@ -334,7 +334,7 @@ class EmitterProxy:
# Recursively substitute the variable.
# We can't use env.subst() because it deals only
# in strings. Maybe we should change that?
- while SCons.Util.is_String(emitter) and env.has_key(emitter):
+ while SCons.Util.is_String(emitter) and emitter in env:
emitter = env[emitter]
if callable(emitter):
target, source = emitter(target, source, env)
@@ -348,7 +348,7 @@ class EmitterProxy:
def __cmp__(self, other):
return cmp(self.var, other.var)
-class BuilderBase:
+class BuilderBase(object):
"""Base class for Builders, objects that create output
nodes (files) from input nodes (files).
"""
@@ -387,14 +387,14 @@ class BuilderBase:
suffix = CallableSelector(suffix)
self.env = env
self.single_source = single_source
- if overrides.has_key('overrides'):
- SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
+ if 'overrides' in overrides:
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedBuilderKeywordsWarning,
"The \"overrides\" keyword to Builder() creation has been deprecated;\n" +\
"\tspecify the items as keyword arguments to the Builder() call instead.")
overrides.update(overrides['overrides'])
del overrides['overrides']
- if overrides.has_key('scanner'):
- SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
+ if 'scanner' in overrides:
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedBuilderKeywordsWarning,
"The \"scanner\" keyword to Builder() creation has been deprecated;\n"
"\tuse: source_scanner or target_scanner as appropriate.")
del overrides['scanner']
@@ -427,7 +427,7 @@ class BuilderBase:
self.src_builder = src_builder
def __nonzero__(self):
- raise InternalError, "Do not test for the Node.builder attribute directly; use Node.has_builder() instead"
+ raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead")
def get_name(self, env):
"""Attempts to get the name of the Builder.
@@ -438,8 +438,8 @@ class BuilderBase:
name (if there is one) or the name of the class (by default)."""
try:
- index = env['BUILDERS'].values().index(self)
- return env['BUILDERS'].keys()[index]
+ index = list(env['BUILDERS'].values()).index(self)
+ return list(env['BUILDERS'].keys())[index]
except (AttributeError, KeyError, TypeError, ValueError):
try:
return self.name
@@ -493,7 +493,7 @@ class BuilderBase:
except IndexError:
tlist = []
else:
- splitext = lambda S,self=self,env=env: self.splitext(S,env)
+ splitext = lambda S: self.splitext(S,env)
tlist = [ t_from_s(pre, suf, splitext) ]
else:
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
@@ -573,8 +573,8 @@ class BuilderBase:
if executor is None:
if not self.action:
fmt = "Builder %s must have an action to build %s."
- raise UserError, fmt % (self.get_name(env or self.env),
- map(str,tlist))
+ raise UserError(fmt % (self.get_name(env or self.env),
+ list(map(str,tlist))))
key = self.action.batch_key(env or self.env, tlist, slist)
if key:
try:
@@ -611,7 +611,7 @@ class BuilderBase:
ekw = self.executor_kw.copy()
ekw['chdir'] = chdir
if kw:
- if kw.has_key('srcdir'):
+ if 'srcdir' in kw:
def prependDirIfRelative(f, srcdir=kw['srcdir']):
import os.path
if SCons.Util.is_String(f) and not os.path.isabs(f):
@@ -619,7 +619,7 @@ class BuilderBase:
return f
if not SCons.Util.is_List(source):
source = [source]
- source = map(prependDirIfRelative, source)
+ source = list(map(prependDirIfRelative, source))
del kw['srcdir']
if self.overrides:
env_kw = self.overrides.copy()
@@ -658,9 +658,7 @@ class BuilderBase:
src_suffix = []
elif not SCons.Util.is_List(src_suffix):
src_suffix = [ src_suffix ]
- adjust = lambda suf, s=self: \
- callable(suf) and suf or s.adjust_suffix(suf)
- self.src_suffix = map(adjust, src_suffix)
+ self.src_suffix = [callable(suf) and suf or self.adjust_suffix(suf) for suf in src_suffix]
def get_src_suffix(self, env):
"""Get the first src_suffix in the list of src_suffixes."""
@@ -723,7 +721,7 @@ class BuilderBase:
lengths = list(set(map(len, src_suffixes)))
def match_src_suffix(name, src_suffixes=src_suffixes, lengths=lengths):
- node_suffixes = map(lambda l, n=name: n[-l:], lengths)
+ node_suffixes = [name[-l:] for l in lengths]
for suf in src_suffixes:
if suf in node_suffixes:
return suf
@@ -749,8 +747,7 @@ class BuilderBase:
# target, then filter out any sources that this
# Builder isn't capable of building.
if len(tlist) > 1:
- mss = lambda t, m=match_src_suffix: m(t.name)
- tlist = filter(mss, tlist)
+ tlist = [t for t in tlist if match_src_suffix(t.name)]
result.extend(tlist)
else:
result.append(s)
@@ -819,7 +816,7 @@ class BuilderBase:
return memo_dict[memo_key]
except KeyError:
pass
- suffixes = map(lambda x, s=self, e=env: e.subst(x), self.src_suffix)
+ suffixes = [env.subst(x) for x in self.src_suffix]
memo_dict[memo_key] = suffixes
return suffixes
@@ -838,7 +835,7 @@ class BuilderBase:
sdict[s] = 1
for builder in self.get_src_builders(env):
for s in builder.src_suffixes(env):
- if not sdict.has_key(s):
+ if s not in sdict:
sdict[s] = 1
suffixes.append(s)
return suffixes
@@ -857,6 +854,8 @@ class CompositeBuilder(SCons.Util.Proxy):
self.cmdgen = cmdgen
self.builder = builder
+ __call__ = SCons.Util.Delegate('__call__')
+
def add_action(self, suffix, action):
self.cmdgen.add_action(suffix, action)
self.set_src_suffix(self.cmdgen.src_suffixes())
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index 4ccded6..a2f8caa 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -21,7 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/BuilderTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/BuilderTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
# Define a null function for use as a builder action.
# Where this is defined in the file seems to affect its
@@ -30,13 +32,12 @@ __revision__ = "src/engine/SCons/BuilderTests.py 4720 2010/03/24 03:14:11 jars"
def Func():
pass
+import collections
+import io
import os.path
import re
import sys
-import types
-import StringIO
import unittest
-import UserList
import TestCmd
@@ -47,7 +48,7 @@ import SCons.Errors
import SCons.Subst
import SCons.Util
-sys.stdout = StringIO.StringIO()
+sys.stdout = io.StringIO()
# Initial setup of the common environment for all tests,
# a temporary working directory containing a
@@ -70,7 +71,7 @@ scons_env = SCons.Environment.Environment()
env_arg2nodes_called = None
-class Environment:
+class Environment(object):
def __init__(self, **kw):
self.d = {}
self.d['SHELL'] = scons_env['SHELL']
@@ -118,21 +119,23 @@ class Environment:
self.d[item] = var
def __getitem__(self, item):
return self.d[item]
+ def __contains__(self, item):
+ return self.d.__contains__(item)
def has_key(self, item):
- return self.d.has_key(item)
+ return item in self.d
def keys(self):
- return self.d.keys()
+ return list(self.d.keys())
def get(self, key, value=None):
return self.d.get(key, value)
def Override(self, overrides):
- env = apply(Environment, (), self.d)
+ env = Environment(**self.d)
env.d.update(overrides)
env.scanner = self.scanner
return env
def _update(self, dict):
self.d.update(dict)
def items(self):
- return self.d.items()
+ return list(self.d.items())
def sig_dict(self):
d = {}
for k,v in self.items(): d[k] = v
@@ -144,7 +147,7 @@ class Environment:
def __cmp__(self, other):
return cmp(self.scanner, other.scanner) or cmp(self.d, other.d)
-class MyAction:
+class MyAction(object):
def __init__(self, action):
self.action = action
def __call__(self, *args, **kw):
@@ -152,7 +155,7 @@ class MyAction:
def get_executor(self, env, overrides, tlist, slist, executor_kw):
return ['executor'] + [self.action]
-class MyNode_without_target_from_source:
+class MyNode_without_target_from_source(object):
def __init__(self, name):
self.name = name
self.sources = []
@@ -215,7 +218,7 @@ class BuilderTestCase(unittest.TestCase):
exc_caught = 1
assert exc_caught, "did not catch expected InternalError exception"
- class Node:
+ class Node(object):
pass
n = Node()
@@ -250,12 +253,12 @@ class BuilderTestCase(unittest.TestCase):
assert not hasattr(n2, 'env')
l = [1]
- ul = UserList.UserList([2])
+ ul = collections.UserList([2])
try:
l.extend(ul)
except TypeError:
def mystr(l):
- return str(map(str, l))
+ return str(list(map(str, l)))
else:
mystr = str
@@ -264,14 +267,14 @@ class BuilderTestCase(unittest.TestCase):
tlist = builder(env, target = [nnn1, nnn2], source = [])
s = mystr(tlist)
assert s == "['nnn1', 'nnn2']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['nnn1', 'nnn2'], l
tlist = builder(env, target = 'n3', source = 'n4')
s = mystr(tlist)
assert s == "['n3']", s
target = tlist[0]
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n3'], l
assert target.name == 'n3'
assert target.sources[0].name == 'n4'
@@ -279,7 +282,7 @@ class BuilderTestCase(unittest.TestCase):
tlist = builder(env, target = 'n4 n5', source = ['n6 n7'])
s = mystr(tlist)
assert s == "['n4 n5']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n4 n5'], l
target = tlist[0]
assert target.name == 'n4 n5'
@@ -288,7 +291,7 @@ class BuilderTestCase(unittest.TestCase):
tlist = builder(env, target = ['n8 n9'], source = 'n10 n11')
s = mystr(tlist)
assert s == "['n8 n9']", s
- l = map(str, tlist)
+ l = list(map(str, tlist))
assert l == ['n8 n9'], l
target = tlist[0]
assert target.name == 'n8 n9'
@@ -302,7 +305,8 @@ class BuilderTestCase(unittest.TestCase):
#be = target.get_build_env()
#assert be['VAR'] == 'foo', be['VAR']
- if not hasattr(types, 'UnicodeType'):
+ try: unicode
+ except NameError:
uni = str
else:
uni = unicode
@@ -340,7 +344,7 @@ class BuilderTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
pass
else:
- raise "Did not catch expected UserError."
+ raise Exception("Did not catch expected UserError.")
builder = SCons.Builder.Builder(action="foo")
target = builder(env, None, source='n22', srcdir='src_dir')[0]
@@ -419,7 +423,7 @@ class BuilderTestCase(unittest.TestCase):
def test_target_factory(self):
"""Test a Builder that creates target nodes of a specified class
"""
- class Foo:
+ class Foo(object):
pass
def FooFactory(target):
global Foo
@@ -431,7 +435,7 @@ class BuilderTestCase(unittest.TestCase):
def test_source_factory(self):
"""Test a Builder that creates source nodes of a specified class
"""
- class Foo:
+ class Foo(object):
pass
def FooFactory(source):
global Foo
@@ -564,13 +568,11 @@ class BuilderTestCase(unittest.TestCase):
"Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path
b2 = SCons.Builder.Builder(src_suffix = '.2', src_builder = b1)
- r = b2.src_suffixes(env)
- r.sort()
+ r = sorted(b2.src_suffixes(env))
assert r == ['.2', '.c'], r
b3 = SCons.Builder.Builder(action = {'.3a' : '', '.3b' : ''})
- s = b3.src_suffixes(env)
- s.sort()
+ s = sorted(b3.src_suffixes(env))
assert s == ['.3a', '.3b'], s
b4 = SCons.Builder.Builder(src_suffix = '$XSUFFIX')
@@ -618,7 +620,7 @@ class BuilderTestCase(unittest.TestCase):
src_suffix='.obj',
suffix='.exe')
tgt = b2(env, target=None, source=['foo$OBJSUFFIX'])
- s = map(str, tgt[0].sources)
+ s = list(map(str, tgt[0].sources))
assert s == ['foo.obj'], s
def test_suffix(self):
@@ -704,21 +706,10 @@ class BuilderTestCase(unittest.TestCase):
tgt.build()
assert env['CNT'][0] == 2
tgts = builder(env, None, infiles[2:4])
- try:
- [].extend(UserList.UserList())
- except TypeError:
- # Old Python version (1.5.2) that can't handle extending
- # a list with list-like objects. That means the return
- # value from the builder call is a real list with Nodes,
- # and doesn't have a __str__() method that stringifies
- # the individual elements. Since we're gong to drop 1.5.2
- # support anyway, don't bother trying to test for it.
- pass
- else:
- s = map(str, tgts)
- expect = [test.workpath('2.out'), test.workpath('3.out')]
- expect = map(os.path.normcase, expect)
- assert map(os.path.normcase, s) == expect, s
+ s = list(map(str, tgts))
+ expect = [test.workpath('2.out'), test.workpath('3.out')]
+ expect = list(map(os.path.normcase, expect))
+ assert list(map(os.path.normcase, s)) == expect, s
for t in tgts: t.prepare()
tgts[0].build()
tgts[1].build()
@@ -744,7 +735,7 @@ class BuilderTestCase(unittest.TestCase):
for t in target:
open(str(t), 'w').write("function2\n")
for t in tlist:
- if not t in map(str, target):
+ if not t in list(map(str, target)):
open(t, 'w').write("function2\n")
return 1
@@ -773,7 +764,7 @@ class BuilderTestCase(unittest.TestCase):
for t in target:
open(str(t), 'w').write("function3\n")
for t in tlist:
- if not t in map(str, target):
+ if not t in list(map(str, target)):
open(t, 'w').write("function3\n")
return 1
@@ -811,17 +802,17 @@ class BuilderTestCase(unittest.TestCase):
tgt = builder2(env, target='baz', source=sources)[0]
s = str(tgt)
assert s == 'baz', s
- s = map(str, tgt.sources)
+ s = list(map(str, tgt.sources))
assert s == ['test.foo', 'test2.foo', 'test3.txt', 'test4.foo'], s
- s = map(str, tgt.sources[0].sources)
+ s = list(map(str, tgt.sources[0].sources))
assert s == ['test.bar'], s
tgt = builder2(env, None, 'aaa.bar')[0]
s = str(tgt)
assert s == 'aaa', s
- s = map(str, tgt.sources)
+ s = list(map(str, tgt.sources))
assert s == ['aaa.foo'], s
- s = map(str, tgt.sources[0].sources)
+ s = list(map(str, tgt.sources[0].sources))
assert s == ['aaa.bar'], s
builder3 = SCons.Builder.Builder(action='bld3')
@@ -841,17 +832,17 @@ class BuilderTestCase(unittest.TestCase):
tgt = builder6(env, 'test', 'test.i')[0]
s = str(tgt)
assert s == 'test.exe', s
- s = map(str, tgt.sources)
+ s = list(map(str, tgt.sources))
assert s == ['test_wrap.obj'], s
- s = map(str, tgt.sources[0].sources)
+ s = list(map(str, tgt.sources[0].sources))
assert s == ['test_wrap.c'], s
- s = map(str, tgt.sources[0].sources[0].sources)
+ s = list(map(str, tgt.sources[0].sources[0].sources))
assert s == ['test.i'], s
def test_target_scanner(self):
"""Testing ability to set target and source scanners through a builder."""
global instanced
- class TestScanner:
+ class TestScanner(object):
pass
tscan = TestScanner()
sscan = TestScanner()
@@ -893,7 +884,7 @@ class BuilderTestCase(unittest.TestCase):
def test_src_scanner(slf):
"""Testing ability to set a source file scanner through a builder."""
- class TestScanner:
+ class TestScanner(object):
def key(self, env):
return 'TestScannerkey'
def instance(self, env):
@@ -922,7 +913,7 @@ class BuilderTestCase(unittest.TestCase):
# An Environment that has suffix-specified SCANNERS should
# provide a source scanner to the target.
- class EnvTestScanner:
+ class EnvTestScanner(object):
def key(self, env):
return '.y'
def instance(self, env):
@@ -1030,8 +1021,7 @@ class BuilderTestCase(unittest.TestCase):
bld.set_src_suffix(['.bar', '.foo'])
r = bld.get_src_suffix(env)
assert r == '.bar', r
- r = bld.src_suffixes(env)
- r.sort()
+ r = sorted(bld.src_suffixes(env))
assert r == ['.bar', '.foo'], r
# adjust_suffix normalizes the suffix, adding a `.' if needed
@@ -1151,8 +1141,7 @@ class BuilderTestCase(unittest.TestCase):
assert r is None, r
r = builder.get_src_suffix(env)
assert r == '.src_sfx1', r
- r = builder.src_suffixes(env)
- r.sort()
+ r = sorted(builder.src_suffixes(env))
assert r == ['.src_sfx1', '.src_sfx2'], r
@@ -1198,14 +1187,14 @@ class BuilderTestCase(unittest.TestCase):
tgt = builder(env, target='foo3', source='bar', foo=1)
assert len(tgt) == 2, len(tgt)
- assert 'foo3' in map(str, tgt), map(str, tgt)
- assert 'bar1' in map(str, tgt), map(str, tgt)
+ assert 'foo3' in list(map(str, tgt)), list(map(str, tgt))
+ assert 'bar1' in list(map(str, tgt)), list(map(str, tgt))
tgt = builder(env, target='foo4', source='bar', bar=1)[0]
assert str(tgt) == 'foo4', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
- assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
- assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+ assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+ assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
env2=Environment(FOO=emit)
builder2=SCons.Builder.Builder(action='foo',
@@ -1226,14 +1215,14 @@ class BuilderTestCase(unittest.TestCase):
tgt = builder2(env2, target='foo6', source='bar', foo=2)
assert len(tgt) == 2, len(tgt)
- assert 'foo6' in map(str, tgt), map(str, tgt)
- assert 'bar2' in map(str, tgt), map(str, tgt)
+ assert 'foo6' in list(map(str, tgt)), list(map(str, tgt))
+ assert 'bar2' in list(map(str, tgt)), list(map(str, tgt))
tgt = builder2(env2, target='foo7', source='bar', bar=1)[0]
assert str(tgt) == 'foo7', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
- assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
- assert 'bar' in map(str, tgt.sources), map(str, tgt.sources)
+ assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
+ assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources))
def test_emitter_preserve_builder(self):
"""Test an emitter not overwriting a newly-set builder"""
@@ -1262,12 +1251,12 @@ class BuilderTestCase(unittest.TestCase):
env = Environment()
def emit4a(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4a-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4a-' + x[:-3] for x in source]
return (target, source)
def emit4b(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4b-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4b-' + x[:-3] for x in source]
return (target, source)
builder = SCons.Builder.Builder(action='foo',
@@ -1283,8 +1272,8 @@ class BuilderTestCase(unittest.TestCase):
assert str(tgt) == 'ccc', str(tgt)
def emit4c(target, source, env):
- source = map(str, source)
- target = map(lambda x: 'emit4c-' + x[:-3], source)
+ source = list(map(str, source))
+ target = ['emit4c-' + x[:-3] for x in source]
return (target, source)
builder.add_emitter('.4c', emit4c)
@@ -1296,29 +1285,29 @@ class BuilderTestCase(unittest.TestCase):
env = Environment()
def emit1a(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit1a-' + x[:-2], source)
+ source = list(map(str, source))
+ target = target + ['emit1a-' + x[:-2] for x in source]
return (target, source)
def emit1b(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit1b-' + x[:-2], source)
+ source = list(map(str, source))
+ target = target + ['emit1b-' + x[:-2] for x in source]
return (target, source)
builder1 = SCons.Builder.Builder(action='foo',
emitter=[emit1a, emit1b],
node_factory=MyNode)
tgts = builder1(env, target='target-1', source='aaa.1')
- tgts = map(str, tgts)
+ tgts = list(map(str, tgts))
assert tgts == ['target-1', 'emit1a-aaa', 'emit1b-aaa'], tgts
# Test a list of emitter functions through the environment.
def emit2a(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit2a-' + x[:-2], source)
+ source = list(map(str, source))
+ target = target + ['emit2a-' + x[:-2] for x in source]
return (target, source)
def emit2b(target, source, env):
- source = map(str, source)
- target = target + map(lambda x: 'emit2b-' + x[:-2], source)
+ source = list(map(str, source))
+ target = target + ['emit2b-' + x[:-2] for x in source]
return (target, source)
builder2 = SCons.Builder.Builder(action='foo',
emitter='$EMITTERLIST',
@@ -1327,7 +1316,7 @@ class BuilderTestCase(unittest.TestCase):
env = Environment(EMITTERLIST = [emit2a, emit2b])
tgts = builder2(env, target='target-2', source='aaa.2')
- tgts = map(str, tgts)
+ tgts = list(map(str, tgts))
assert tgts == ['target-2', 'emit2a-aaa', 'emit2b-aaa'], tgts
def test_emitter_TARGET_SOURCE(self):
@@ -1345,8 +1334,8 @@ class BuilderTestCase(unittest.TestCase):
targets = builder(env, target = 'TTT', source ='SSS')
sources = targets[0].sources
- targets = map(str, targets)
- sources = map(str, sources)
+ targets = list(map(str, targets))
+ sources = list(map(str, sources))
assert targets == ['TTT', 'SSS.s1', 'TTT.t1'], targets
assert sources == ['SSS', 'TTT.t2', 'SSS.s2'], targets
@@ -1358,53 +1347,53 @@ class BuilderTestCase(unittest.TestCase):
tgt = b(env, None, 'aaa')[0]
assert str(tgt) == 'aaa.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'aaa', list(map(str, tgt.sources))
tgt = b(env, None, 'bbb.c')[0]
assert str(tgt) == 'bbb.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'bbb.c', list(map(str, tgt.sources))
tgt = b(env, None, 'ccc.x.c')[0]
assert str(tgt) == 'ccc.x.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'ccc.x.c', list(map(str, tgt.sources))
tgt = b(env, None, ['d0.c', 'd1.c'])[0]
assert str(tgt) == 'd0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'd0.c', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'd1.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'd0.c', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'd1.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source='eee')[0]
assert str(tgt) == 'eee.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'eee', list(map(str, tgt.sources))
tgt = b(env, target = None, source='fff.c')[0]
assert str(tgt) == 'fff.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'fff.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source='ggg.x.c')[0]
assert str(tgt) == 'ggg.x.o', str(tgt)
- assert len(tgt.sources) == 1, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 1, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'ggg.x.c', list(map(str, tgt.sources))
tgt = b(env, target = None, source=['h0.c', 'h1.c'])[0]
assert str(tgt) == 'h0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'h0.c', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'h1.c', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'h0.c', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'h1.c', list(map(str, tgt.sources))
w = b(env, target='i0.w', source=['i0.x'])[0]
y = b(env, target='i1.y', source=['i1.z'])[0]
tgt = b(env, None, source=[w, y])[0]
assert str(tgt) == 'i0.o', str(tgt)
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'i0.w', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'i1.y', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'i0.w', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'i1.y', list(map(str, tgt.sources))
def test_get_name(self):
"""Test getting name of builder.
@@ -1642,7 +1631,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/CacheDir.py b/src/engine/SCons/CacheDir.py
index 6977621..6b2e174 100644
--- a/src/engine/SCons/CacheDir.py
+++ b/src/engine/SCons/CacheDir.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/CacheDir.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/CacheDir.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
CacheDir support
@@ -29,7 +29,6 @@ CacheDir support
import os.path
import stat
-import string
import sys
import SCons.Action
@@ -101,7 +100,7 @@ def CachePushFunc(target, source, env):
# has beaten us creating the directory.
if not fs.isdir(cachedir):
msg = errfmt % (str(target), cachefile)
- raise SCons.Errors.EnvironmentError, msg
+ raise SCons.Errors.EnvironmentError(msg)
try:
if fs.islink(t.path):
@@ -122,7 +121,7 @@ def CachePushFunc(target, source, env):
CachePush = SCons.Action.Action(CachePushFunc, None)
-class CacheDir:
+class CacheDir(object):
def __init__(self, path):
try:
@@ -158,7 +157,7 @@ class CacheDir:
return None, None
sig = node.get_cachedir_bsig()
- subdir = string.upper(sig[0])
+ subdir = sig[0].upper()
dir = os.path.join(self.path, subdir)
return dir, os.path.join(dir, sig)
diff --git a/src/engine/SCons/CacheDirTests.py b/src/engine/SCons/CacheDirTests.py
index 1bac2bc..c741ab7 100644
--- a/src/engine/SCons/CacheDirTests.py
+++ b/src/engine/SCons/CacheDirTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/CacheDirTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/CacheDirTests.py 5023 2010/06/14 22:05:46 scons"
import os.path
import shutil
@@ -34,7 +34,7 @@ import SCons.CacheDir
built_it = None
-class Action:
+class Action(object):
def __call__(self, targets, sources, env, **kw):
global built_it
if kw.get('execute', 1):
@@ -45,7 +45,7 @@ class Action:
def get_contents(self, target, source, env):
return ''
-class Builder:
+class Builder(object):
def __init__(self, environment, action):
self.env = environment
self.action = action
@@ -53,7 +53,7 @@ class Builder:
self.source_scanner = None
self.target_scanner = None
-class Environment:
+class Environment(object):
def __init__(self, cachedir):
self.cachedir = cachedir
def Override(self, overrides):
@@ -286,7 +286,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Conftest.py b/src/engine/SCons/Conftest.py
index e995e77..04a6bc2 100644
--- a/src/engine/SCons/Conftest.py
+++ b/src/engine/SCons/Conftest.py
@@ -101,7 +101,6 @@ Autoconf-like configuration support; low level implementation of tests.
#
import re
-import string
from types import IntType
#
@@ -230,7 +229,7 @@ int main()
def _check_empty_program(context, comp, text, language, use_shared = False):
"""Return 0 on success, 1 otherwise."""
- if not context.env.has_key(comp) or not context.env[comp]:
+ if comp not in context.env or not context.env[comp]:
# The compiler construction variable is not set or empty
return 1
@@ -636,7 +635,7 @@ return 0;
""" % (call or "")
if call:
- i = string.find(call, "\n")
+ i = call.find("\n")
if i > 0:
calltext = call[:i] + ".."
elif call[-1] == ';':
@@ -723,14 +722,14 @@ def _Have(context, key, have, comment = None):
Give "have" as is should appear in the header file, include quotes
when desired and escape special characters!
"""
- key_up = string.upper(key)
+ key_up = key.upper()
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
context.havedict[key_up] = have
if have == 1:
line = "#define %s 1\n" % key_up
elif have == 0:
line = "/* #undef %s */\n" % key_up
- elif type(have) == IntType:
+ elif isinstance(have, IntType):
line = "#define %s %d\n" % (key_up, have)
else:
line = "#define %s %s\n" % (key_up, str(have))
@@ -755,7 +754,7 @@ def _LogFailed(context, text, msg):
"""
if LogInputFiles:
context.Log("Failed program was:\n")
- lines = string.split(text, '\n')
+ lines = text.split('\n')
if len(lines) and lines[-1] == '':
lines = lines[:-1] # remove trailing empty line
n = 1
diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py
index afff44b..ec7dbbd 100644
--- a/src/engine/SCons/Debug.py
+++ b/src/engine/SCons/Debug.py
@@ -1,7 +1,6 @@
"""SCons.Debug
-Code for debugging SCons internal things. Not everything here is
-guaranteed to work all the way back to Python 1.5.2, and shouldn't be
+Code for debugging SCons internal things. Shouldn't be
needed by most users.
"""
@@ -29,42 +28,31 @@ needed by most users.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Debug.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Debug.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import sys
import time
-
-# Recipe 14.10 from the Python Cookbook.
-try:
- import weakref
-except ImportError:
- def logInstanceCreation(instance, name=None):
- pass
-else:
- def logInstanceCreation(instance, name=None):
- if name is None:
- name = instance.__class__.__name__
- if not tracked_classes.has_key(name):
- tracked_classes[name] = []
- tracked_classes[name].append(weakref.ref(instance))
-
-
+import weakref
tracked_classes = {}
+def logInstanceCreation(instance, name=None):
+ if name is None:
+ name = instance.__class__.__name__
+ if name not in tracked_classes:
+ tracked_classes[name] = []
+ tracked_classes[name].append(weakref.ref(instance))
+
def string_to_classes(s):
if s == '*':
- c = tracked_classes.keys()
- c.sort()
- return c
+ return sorted(tracked_classes.keys())
else:
- return string.split(s)
+ return s.split()
def fetchLoggedInstances(classes="*"):
classnames = string_to_classes(classes)
- return map(lambda cn: (cn, len(tracked_classes[cn])), classnames)
+ return [(cn, len(tracked_classes[cn])) for cn in classnames]
def countLoggedInstances(classes, file=sys.stdout):
for classname in string_to_classes(classes):
@@ -94,8 +82,12 @@ if sys.platform[:5] == "linux":
# Linux doesn't actually support memory usage stats from getrusage().
def memory():
mstr = open('/proc/self/stat').read()
- mstr = string.split(mstr)[22]
+ mstr = mstr.split()[22]
return int(mstr)
+elif sys.platform[:6] == 'darwin':
+ #TODO really get memory stats for OS X
+ def memory():
+ return 0
else:
try:
import resource
@@ -149,21 +141,15 @@ def caller_trace(back=0):
# print a single caller and its callers, if any
def _dump_one_caller(key, file, level=0):
- l = []
- for c,v in caller_dicts[key].items():
- l.append((-v,c))
- l.sort()
leader = ' '*level
- for v,c in l:
+ 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 caller_dicts.has_key(c):
+ if c in caller_dicts:
_dump_one_caller(c, file, level+1)
# print each call tree
def dump_caller_counts(file=sys.stdout):
- keys = caller_bases.keys()
- keys.sort()
- for k in keys:
+ for k in sorted(caller_bases.keys()):
file.write("Callers of %s:%d(%s), %d calls:\n"
% (func_shorten(k) + (caller_bases[k],)))
_dump_one_caller(k, file)
@@ -175,15 +161,12 @@ shorten_list = [
]
if os.sep != '/':
- def platformize(t):
- return (string.replace(t[0], '/', os.sep), t[1])
- shorten_list = map(platformize, shorten_list)
- del platformize
+ shorten_list = [(t[0].replace('/', os.sep), t[1]) for t in shorten_list]
def func_shorten(func_tuple):
f = func_tuple[0]
for t in shorten_list:
- i = string.find(f, t[0])
+ i = f.find(t[0])
if i >= 0:
if t[1]:
i = i + len(t[0])
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index c353134..8530aa3 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -31,19 +31,16 @@ 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__ = "src/engine/SCons/Defaults.py 4720 2010/03/24 03:14:11 jars"
-
+__revision__ = "src/engine/SCons/Defaults.py 5023 2010/06/14 22:05:46 scons"
import os
-import os.path
import errno
import shutil
import stat
-import string
import time
-import types
import sys
import SCons.Action
@@ -88,7 +85,7 @@ def DefaultEnvironment(*args, **kw):
global _default_env
if not _default_env:
import SCons.Util
- _default_env = apply(SCons.Environment.Environment, args, kw)
+ _default_env = SCons.Environment.Environment(*args, **kw)
if SCons.Util.md5:
_default_env.Decider('MD5')
else:
@@ -120,7 +117,7 @@ def SharedFlagChecker(source, target, env):
except AttributeError:
shared = None
if not shared:
- raise SCons.Errors.UserError, "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])
+ raise SCons.Errors.UserError("Source file: %s is static and is not compatible with shared target: %s" % (src, target[0]))
SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
@@ -165,7 +162,7 @@ def get_paths_str(dest):
elem_strs = []
for element in dest:
elem_strs.append('"' + str(element) + '"')
- return '[' + string.join(elem_strs, ', ') + ']'
+ return '[' + ', '.join(elem_strs) + ']'
else:
return '"' + str(dest) + '"'
@@ -225,7 +222,8 @@ def mkdir_func(dest):
os.makedirs(str(entry))
except os.error, e:
p = str(entry)
- if (e[0] == errno.EEXIST or (sys.platform=='win32' and e[0]==183)) \
+ if (e.args[0] == errno.EEXIST or
+ (sys.platform=='win32' and e.args[0]==183)) \
and os.path.isdir(str(entry)):
pass # not an error if already exists
else:
@@ -315,16 +313,16 @@ def _concat_ixes(prefix, list, suffix, env):
return result
-def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
+def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
"""
- This is a wrapper around _concat()/_concat_ixes() that checks for the
- existence of prefixes or suffixes on list elements and strips them
+ This is a wrapper around _concat()/_concat_ixes() that checks for
+ the existence of prefixes or suffixes on list items and strips them
where it finds them. This is used by tools (like the GNU linker)
that need to turn something like 'libfoo.a' into '-lfoo'.
"""
- if not list:
- return list
+ if not itms:
+ return itms
if not callable(c):
env_c = env['_concat']
@@ -337,11 +335,11 @@ def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
else:
c = _concat_ixes
- stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
- stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
+ stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes)))
+ stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes)))
stripped = []
- for l in SCons.PathList.PathList(list).subst_path(env, None, None):
+ for l in SCons.PathList.PathList(itms).subst_path(env, None, None):
if isinstance(l, SCons.Node.FS.File):
stripped.append(l)
continue
@@ -374,7 +372,7 @@ def processDefines(defs):
if SCons.Util.is_List(defs):
l = []
for d in defs:
- if SCons.Util.is_List(d) or type(d) is types.TupleType:
+ if SCons.Util.is_List(d) or isinstance(d, tuple):
l.append(str(d[0]) + '=' + str(d[1]))
else:
l.append(str(d))
@@ -386,10 +384,7 @@ def processDefines(defs):
# Consequently, we have to sort the keys to ensure a
# consistent order...
l = []
- keys = defs.keys()
- keys.sort()
- for k in keys:
- v = defs[k]
+ for k,v in sorted(defs.items()):
if v is None:
l.append(str(k))
else:
@@ -405,7 +400,7 @@ def _defines(prefix, defs, suffix, env, c=_concat_ixes):
return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
-class NullCmdGenerator:
+class NullCmdGenerator(object):
"""This is a callable class that can be used in place of other
command generators if you don't want them to do anything.
@@ -423,7 +418,7 @@ class NullCmdGenerator:
def __call__(self, target, source, env, for_signature=None):
return self.cmd
-class Variable_Method_Caller:
+class Variable_Method_Caller(object):
"""A class for finding a construction variable on the stack and
calling one of its methods.
@@ -439,18 +434,18 @@ class Variable_Method_Caller:
self.variable = variable
self.method = method
def __call__(self, *args, **kw):
- try: 1/0
+ try: 1//0
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
variable = self.variable
while frame:
- if frame.f_locals.has_key(variable):
+ if variable in frame.f_locals:
v = frame.f_locals[variable]
if v:
method = getattr(v, self.method)
- return apply(method, args, kw)
+ return method(*args, **kw)
frame = frame.f_back
return None
diff --git a/src/engine/SCons/DefaultsTests.py b/src/engine/SCons/DefaultsTests.py
index 348d54d..20501bc 100644
--- a/src/engine/SCons/DefaultsTests.py
+++ b/src/engine/SCons/DefaultsTests.py
@@ -21,17 +21,15 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/DefaultsTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/DefaultsTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import os
-import os.path
-import string
-import StringIO
import sys
-import types
import unittest
-from UserDict import UserDict
+from collections import UserDict
import TestCmd
@@ -83,7 +81,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index ac6de99..50a357d 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -30,9 +30,8 @@ Environment
# 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__ = "src/engine/SCons/Environment.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Environment.py 5023 2010/06/14 22:05:46 scons"
import copy
@@ -40,8 +39,7 @@ import os
import sys
import re
import shlex
-import string
-from UserDict import UserDict
+from collections import UserDict
import SCons.Action
import SCons.Builder
@@ -61,7 +59,7 @@ import SCons.Tool
import SCons.Util
import SCons.Warnings
-class _Null:
+class _Null(object):
pass
_null = _Null
@@ -98,11 +96,11 @@ def apply_tools(env, tools, toolpath):
if not tools:
return
# Filter out null tools from the list.
- for tool in filter(None, tools):
- if SCons.Util.is_List(tool) or type(tool)==type(()):
+ for tool in [_f for _f in tools if _f]:
+ if SCons.Util.is_List(tool) or isinstance(tool, tuple):
toolname = tool[0]
toolargs = tool[1] # should be a dict of kw args
- tool = apply(env.Tool, [toolname], toolargs)
+ tool = env.Tool(toolname, **toolargs)
else:
env.Tool(tool)
@@ -173,7 +171,7 @@ def _delete_duplicates(l, keep_last):
l.reverse()
for i in l:
try:
- if not seen.has_key(i):
+ if i not in seen:
result.append(i)
seen[i]=1
except TypeError:
@@ -196,7 +194,7 @@ def _delete_duplicates(l, keep_last):
# BuilderWrapper a subclass that overrides __call__() to enforce specific
# Builder calling conventions, simplified some of our higher-layer code.
-class MethodWrapper:
+class MethodWrapper(object):
"""
A generic Wrapper class that associates a method (which can
actually be any callable) with an object. As part of creating this
@@ -221,7 +219,7 @@ class MethodWrapper:
def __call__(self, *args, **kwargs):
nargs = (self.object,) + args
- return apply(self.method, nargs, kwargs)
+ return self.method(*nargs, **kwargs)
def clone(self, new_object):
"""
@@ -257,7 +255,7 @@ class BuilderWrapper(MethodWrapper):
target = [target]
if source is not None and not SCons.Util.is_List(source):
source = [source]
- return apply(MethodWrapper.__call__, (self, target, source) + args, kw)
+ return MethodWrapper.__call__(self, target, source, *args, **kw)
def __repr__(self):
return '<BuilderWrapper %s>' % repr(self.name)
@@ -271,7 +269,7 @@ class BuilderWrapper(MethodWrapper):
elif name == 'builder':
return self.method
else:
- raise AttributeError, name
+ raise AttributeError(name)
def __setattr__(self, name, value):
if name == 'env':
@@ -290,7 +288,7 @@ class BuilderWrapper(MethodWrapper):
# future, so leave it for now.
#def execute(self, **kw):
# kw['env'] = self.env
- # apply(self.builder.execute, (), kw)
+ # self.builder.execute(**kw)
class BuilderDict(UserDict):
"""This is a dictionary-like class used by an Environment to hold
@@ -337,7 +335,7 @@ def is_valid_construction_var(varstr):
-class SubstitutionEnvironment:
+class SubstitutionEnvironment(object):
"""Base class for different flavors of construction environments.
This class contains a minimal set of methods that handle contruction
@@ -395,7 +393,7 @@ class SubstitutionEnvironment:
# Freeze the keys of self._special_set in a list for use by
# methods that need to check. (Empirically, list scanning has
# gotten better than dict.has_key() in Python 2.5.)
- self._special_set_keys = self._special_set.keys()
+ self._special_set_keys = list(self._special_set.keys())
def __cmp__(self, other):
return cmp(self._dict, other._dict)
@@ -419,7 +417,7 @@ class SubstitutionEnvironment:
# list works a little better in Python 2.5, but that has the
# disadvantage of maybe getting out of sync if we ever add more
# variable names. Using self._special_set.has_key() works a
- # little better in Python 2.4, but is worse then this test.
+ # little better in Python 2.4, but is worse than this test.
# So right now it seems like a good trade-off, but feel free to
# revisit this with bench/env.__setitem__.py as needed (and
# as newer versions of Python come out).
@@ -430,9 +428,9 @@ class SubstitutionEnvironment:
# key and we don't need to check. If we do check, using a
# global, pre-compiled regular expression directly is more
# efficient than calling another function or a method.
- if not self._dict.has_key(key) \
+ if key not in self._dict \
and not _is_valid_var.match(key):
- raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
+ raise SCons.Errors.UserError("Illegal construction variable `%s'" % key)
self._dict[key] = value
def get(self, key, default=None):
@@ -440,13 +438,13 @@ class SubstitutionEnvironment:
return self._dict.get(key, default)
def has_key(self, key):
- return self._dict.has_key(key)
+ return key in self._dict
def __contains__(self, key):
return self._dict.__contains__(key)
def items(self):
- return self._dict.items()
+ return list(self._dict.items())
def arg2nodes(self, args, node_factory=_null, lookup_list=_null, **kw):
if node_factory is _null:
@@ -471,7 +469,7 @@ class SubstitutionEnvironment:
if SCons.Util.is_String(n):
# n = self.subst(n, raw=1, **kw)
kw['raw'] = 1
- n = apply(self.subst, (n,), kw)
+ n = self.subst(n, **kw)
if node_factory:
n = node_factory(n)
if SCons.Util.is_List(n):
@@ -481,7 +479,7 @@ class SubstitutionEnvironment:
elif node_factory:
# v = node_factory(self.subst(v, raw=1, **kw))
kw['raw'] = 1
- v = node_factory(apply(self.subst, (v,), kw))
+ v = node_factory(self.subst(v, **kw))
if SCons.Util.is_List(v):
nodes.extend(v)
else:
@@ -566,7 +564,7 @@ class SubstitutionEnvironment:
# We have an object plus a string, or multiple
# objects that we need to smush together. No choice
# but to make them into a string.
- p = string.join(map(SCons.Util.to_String_for_subst, p), '')
+ p = ''.join(map(SCons.Util.to_String_for_subst, p))
else:
p = s(p)
r.append(p)
@@ -586,12 +584,11 @@ class SubstitutionEnvironment:
# othewise force a shell
if not SCons.Util.is_List(command): kw['shell'] = True
# run constructed command
- #TODO(1.5) p = SCons.Action._subproc(self, command, **kw)
- p = apply(SCons.Action._subproc, (self, command), kw)
+ p = SCons.Action._subproc(self, command, **kw)
out,err = p.communicate()
status = p.wait()
if err:
- sys.stderr.write(err)
+ sys.stderr.write(unicode(err))
if status:
raise OSError("'%s' exited %d" % (command, status))
return out
@@ -610,8 +607,7 @@ class SubstitutionEnvironment:
Removes the specified function's MethodWrapper from the
added_methods list, so we don't re-bind it when making a clone.
"""
- is_not_func = lambda dm, f=function: not dm.method is f
- self.added_methods = filter(is_not_func, self.added_methods)
+ self.added_methods = [dm for dm in self.added_methods if not dm.method is function]
def Override(self, overrides):
"""
@@ -664,15 +660,13 @@ class SubstitutionEnvironment:
'RPATH' : [],
}
- # The use of the "me" parameter to provide our own name for
- # recursion is an egregious hack to support Python 2.1 and before.
- def do_parse(arg, me, self = self, dict = dict):
+ def do_parse(arg):
# if arg is a sequence, recurse with each element
if not arg:
return
if not SCons.Util.is_String(arg):
- for t in arg: me(t, me)
+ for t in arg: do_parse(t)
return
# if arg is a command, execute it
@@ -681,11 +675,11 @@ class SubstitutionEnvironment:
# utility function to deal with -D option
def append_define(name, dict = dict):
- t = string.split(name, '=')
+ t = name.split('=')
if len(t) == 1:
dict['CPPDEFINES'].append(name)
else:
- dict['CPPDEFINES'].append([t[0], string.join(t[1:], '=')])
+ dict['CPPDEFINES'].append([t[0], '='.join(t[1:])])
# Loop through the flags and add them to the appropriate option.
# This tries to strike a balance between checking for all possible
@@ -791,7 +785,7 @@ class SubstitutionEnvironment:
dict['CCFLAGS'].append(arg)
for arg in flags:
- do_parse(arg, do_parse)
+ do_parse(arg)
return dict
def MergeFlags(self, args, unique=1, dict=None):
@@ -807,7 +801,7 @@ class SubstitutionEnvironment:
if not SCons.Util.is_Dict(args):
args = self.ParseFlags(args)
if not unique:
- apply(self.Append, (), args)
+ self.Append(**args)
return self
for key, value in args.items():
if not value:
@@ -866,21 +860,10 @@ class SubstitutionEnvironment:
# if not pathval:
# continue
# if prepend:
-# apply(self.PrependENVPath, (pathname, pathval))
+# self.PrependENVPath(pathname, pathval)
# else:
-# apply(self.AppendENVPath, (pathname, pathval))
-
+# self.AppendENVPath(pathname, pathval)
-# Used by the FindSourceFiles() method, below.
-# Stuck here for support of pre-2.2 Python versions.
-def build_source(ss, result):
- for s in ss:
- if isinstance(s, SCons.Node.FS.Dir):
- build_source(s.all_children(), result)
- elif s.has_builder():
- build_source(s.sources, result)
- elif isinstance(s.disambiguate(), SCons.Node.FS.File):
- result.append(s)
def default_decide_source(dependency, target, prev_ni):
f = SCons.Defaults.DefaultEnvironment().decide_source
@@ -979,15 +962,15 @@ class Base(SubstitutionEnvironment):
# Apply the passed-in and customizable variables to the
# environment before calling the tools, because they may use
# some of them during initialization.
- if kw.has_key('options'):
+ if 'options' in kw:
# Backwards compatibility: they may stll be using the
# old "options" keyword.
variables = kw['options']
del kw['options']
- apply(self.Replace, (), kw)
- keys = kw.keys()
+ self.Replace(**kw)
+ keys = list(kw.keys())
if variables:
- keys = keys + variables.keys()
+ keys = keys + list(variables.keys())
variables.Update(self)
save = {}
@@ -1100,7 +1083,7 @@ class Base(SubstitutionEnvironment):
for scanner in scanners:
for k in scanner.get_skeys(self):
if k and self['PLATFORM'] == 'win32':
- k = string.lower(k)
+ k = k.lower()
result[k] = scanner
self._memo['_gsm'] = result
@@ -1111,7 +1094,7 @@ class Base(SubstitutionEnvironment):
"""Find the appropriate scanner given a key (usually a file suffix).
"""
if skey and self['PLATFORM'] == 'win32':
- skey = string.lower(skey)
+ skey = skey.lower()
return self._gsm().get(skey)
def scanner_map_delete(self, kw=None):
@@ -1240,13 +1223,13 @@ class Base(SubstitutionEnvironment):
"""
orig = ''
- if self._dict.has_key(envname) and self._dict[envname].has_key(name):
+ if envname in self._dict and name in self._dict[envname]:
orig = self._dict[envname][name]
nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing,
canonicalize=self._canonicalize)
- if not self._dict.has_key(envname):
+ if envname not in self._dict:
self._dict[envname] = {}
self._dict[envname][name] = nv
@@ -1261,7 +1244,7 @@ class Base(SubstitutionEnvironment):
for key, val in kw.items():
if SCons.Util.is_List(val):
val = _delete_duplicates(val, delete_existing)
- if not self._dict.has_key(key) or self._dict[key] in ('', None):
+ if key not in self._dict or self._dict[key] in ('', None):
self._dict[key] = val
elif SCons.Util.is_Dict(self._dict[key]) and \
SCons.Util.is_Dict(val):
@@ -1271,9 +1254,9 @@ class Base(SubstitutionEnvironment):
if not SCons.Util.is_List(dk):
dk = [dk]
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
else:
- val = filter(lambda x, dk=dk: x not in dk, val)
+ val = [x for x in val if x not in dk]
self._dict[key] = dk + val
else:
dk = self._dict[key]
@@ -1281,14 +1264,14 @@ class Base(SubstitutionEnvironment):
# By elimination, val is not a list. Since dk is a
# list, wrap val in a list first.
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
self._dict[key] = dk + [val]
else:
if not val in dk:
self._dict[key] = dk + [val]
else:
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
self._dict[key] = dk + val
self.scanner_map_delete(kw)
@@ -1327,12 +1310,12 @@ class Base(SubstitutionEnvironment):
new = {}
for key, value in kw.items():
new[key] = SCons.Subst.scons_subst_once(value, self, key)
- apply(clone.Replace, (), new)
+ clone.Replace(**new)
apply_tools(clone, tools, toolpath)
# apply them again in case the tools overwrote them
- apply(clone.Replace, (), new)
+ clone.Replace(**new)
# Finally, apply any flags to be merged in
if parse_flags: clone.MergeFlags(parse_flags)
@@ -1346,7 +1329,7 @@ class Base(SubstitutionEnvironment):
msg = "The env.Copy() method is deprecated; use the env.Clone() method instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedCopyWarning, msg)
_warn_copy_deprecated = False
- return apply(self.Clone, args, kw)
+ return self.Clone(*args, **kw)
def _changed_build(self, dependency, target, prev_ni):
if dependency.changed_state(target, prev_ni):
@@ -1383,7 +1366,7 @@ class Base(SubstitutionEnvironment):
copy_function = self._copy2_from_cache
if function in ('MD5', 'content'):
if not SCons.Util.md5:
- raise UserError, "MD5 signatures are not available in this version of Python."
+ raise UserError("MD5 signatures are not available in this version of Python.")
function = self._changed_content
elif function == 'MD5-timestamp':
function = self._changed_timestamp_then_content
@@ -1393,7 +1376,7 @@ class Base(SubstitutionEnvironment):
elif function == 'timestamp-match':
function = self._changed_timestamp_match
elif not callable(function):
- raise UserError, "Unknown Decider value %s" % repr(function)
+ raise UserError("Unknown Decider value %s" % repr(function))
# We don't use AddMethod because we don't want to turn the
# function, which only expects three arguments, into a bound
@@ -1416,7 +1399,7 @@ class Base(SubstitutionEnvironment):
def Dictionary(self, *args):
if not args:
return self._dict
- dlist = map(lambda x, s=self: s._dict[x], args)
+ dlist = [self._dict[x] for x in args]
if len(dlist) == 1:
dlist = dlist[0]
return dlist
@@ -1472,7 +1455,7 @@ class Base(SubstitutionEnvironment):
return env.MergeFlags(cmd, unique)
function = parse_conf
if SCons.Util.is_List(command):
- command = string.join(command)
+ command = ' '.join(command)
command = self.subst(command)
return function(self, self.backtick(command))
@@ -1494,23 +1477,25 @@ class Base(SubstitutionEnvironment):
raise
return
lines = SCons.Util.LogicalLines(fp).readlines()
- lines = filter(lambda l: l[0] != '#', lines)
+ lines = [l for l in lines if l[0] != '#']
tdlist = []
for line in lines:
try:
- target, depends = string.split(line, ':', 1)
- except (AttributeError, TypeError, ValueError):
- # Python 1.5.2 throws TypeError if line isn't a string,
- # Python 2.x throws AttributeError because it tries
- # to call line.split(). Either can throw ValueError
- # if the line doesn't split into two or more elements.
+ target, depends = line.split(':', 1)
+ except (AttributeError, ValueError):
+ # Throws AttributeError if line isn't a string. Can throw
+ # ValueError if line doesn't split into two or more elements.
pass
else:
- tdlist.append((string.split(target), string.split(depends)))
+ tdlist.append((target.split(), depends.split()))
if only_one:
- targets = reduce(lambda x, y: x+y, map(lambda p: p[0], tdlist))
+ targets = []
+ for td in tdlist:
+ targets.extend(td[0])
if len(targets) > 1:
- raise SCons.Errors.UserError, "More than one dependency target found in `%s': %s" % (filename, targets)
+ raise SCons.Errors.UserError(
+ "More than one dependency target found in `%s': %s"
+ % (filename, targets))
for target, depends in tdlist:
self.Depends(target, depends)
@@ -1596,13 +1581,13 @@ class Base(SubstitutionEnvironment):
"""
orig = ''
- if self._dict.has_key(envname) and self._dict[envname].has_key(name):
+ if envname in self._dict and name in self._dict[envname]:
orig = self._dict[envname][name]
nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing,
canonicalize=self._canonicalize)
- if not self._dict.has_key(envname):
+ if envname not in self._dict:
self._dict[envname] = {}
self._dict[envname][name] = nv
@@ -1617,7 +1602,7 @@ class Base(SubstitutionEnvironment):
for key, val in kw.items():
if SCons.Util.is_List(val):
val = _delete_duplicates(val, not delete_existing)
- if not self._dict.has_key(key) or self._dict[key] in ('', None):
+ if key not in self._dict or self._dict[key] in ('', None):
self._dict[key] = val
elif SCons.Util.is_Dict(self._dict[key]) and \
SCons.Util.is_Dict(val):
@@ -1627,9 +1612,9 @@ class Base(SubstitutionEnvironment):
if not SCons.Util.is_List(dk):
dk = [dk]
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
else:
- val = filter(lambda x, dk=dk: x not in dk, val)
+ val = [x for x in val if x not in dk]
self._dict[key] = val + dk
else:
dk = self._dict[key]
@@ -1637,14 +1622,14 @@ class Base(SubstitutionEnvironment):
# By elimination, val is not a list. Since dk is a
# list, wrap val in a list first.
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
self._dict[key] = [val] + dk
else:
if not val in dk:
self._dict[key] = [val] + dk
else:
if delete_existing:
- dk = filter(lambda x, val=val: x not in val, dk)
+ dk = [x for x in dk if x not in val]
self._dict[key] = val + dk
self.scanner_map_delete(kw)
@@ -1690,9 +1675,9 @@ class Base(SubstitutionEnvironment):
def SetDefault(self, **kw):
for k in kw.keys():
- if self._dict.has_key(k):
+ if k in self._dict:
del kw[k]
- apply(self.Replace, (), kw)
+ self.Replace(**kw)
def _find_toolpath_dir(self, tp):
return self.fs.Dir(self.subst(tp)).srcnode().abspath
@@ -1702,8 +1687,8 @@ class Base(SubstitutionEnvironment):
tool = self.subst(tool)
if toolpath is None:
toolpath = self.get('toolpath', [])
- toolpath = map(self._find_toolpath_dir, toolpath)
- tool = apply(SCons.Tool.Tool, (tool, toolpath), kw)
+ toolpath = list(map(self._find_toolpath_dir, toolpath))
+ tool = SCons.Tool.Tool(tool, toolpath, **kw)
tool(self)
def WhereIs(self, prog, path=None, pathext=None, reject=[]):
@@ -1741,15 +1726,15 @@ class Base(SubstitutionEnvironment):
if SCons.Util.is_String(a):
a = self.subst(a)
return a
- nargs = map(subst_string, args)
+ nargs = list(map(subst_string, args))
nkw = self.subst_kw(kw)
- return apply(SCons.Action.Action, nargs, nkw)
+ return SCons.Action.Action(*nargs, **nkw)
def AddPreAction(self, files, action):
nodes = self.arg2nodes(files, self.fs.Entry)
action = SCons.Action.Action(action)
uniq = {}
- for executor in map(lambda n: n.get_executor(), nodes):
+ for executor in [n.get_executor() for n in nodes]:
uniq[executor] = 1
for executor in uniq.keys():
executor.add_pre_action(action)
@@ -1759,7 +1744,7 @@ class Base(SubstitutionEnvironment):
nodes = self.arg2nodes(files, self.fs.Entry)
action = SCons.Action.Action(action)
uniq = {}
- for executor in map(lambda n: n.get_executor(), nodes):
+ for executor in [n.get_executor() for n in nodes]:
uniq[executor] = 1
for executor in uniq.keys():
executor.add_post_action(action)
@@ -1769,7 +1754,7 @@ class Base(SubstitutionEnvironment):
tlist = self.arg2nodes(target, self.ans.Alias)
if not SCons.Util.is_List(source):
source = [source]
- source = filter(None, source)
+ source = [_f for _f in source if _f]
if not action:
if not source:
@@ -1796,7 +1781,7 @@ class Base(SubstitutionEnvironment):
'multi' : 1,
'is_explicit' : None,
})
- bld = apply(SCons.Builder.Builder, (), nkw)
+ bld = SCons.Builder.Builder(**nkw)
# Apply the Builder separately to each target so that the Aliases
# stay separate. If we did one "normal" Builder call with the
@@ -1813,7 +1798,7 @@ class Base(SubstitutionEnvironment):
b = bld
else:
nkw['action'] = b.action + action
- b = apply(SCons.Builder.Builder, (), nkw)
+ b = SCons.Builder.Builder(**nkw)
t.convert()
result.extend(b(self, t, t.sources + source))
return result
@@ -1827,14 +1812,16 @@ class Base(SubstitutionEnvironment):
return tlist
def BuildDir(self, *args, **kw):
- if kw.has_key('build_dir'):
+ msg = """BuildDir() and the build_dir keyword have been deprecated;\n\tuse VariantDir() and the variant_dir keyword instead."""
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg)
+ if 'build_dir' in kw:
kw['variant_dir'] = kw['build_dir']
del kw['build_dir']
- return apply(self.VariantDir, args, kw)
+ return self.VariantDir(*args, **kw)
def Builder(self, **kw):
nkw = self.subst_kw(kw)
- return apply(SCons.Builder.Builder, [], nkw)
+ return SCons.Builder.Builder(**nkw)
def CacheDir(self, path):
import SCons.CacheDir
@@ -1862,7 +1849,7 @@ class Base(SubstitutionEnvironment):
nkw['custom_tests'] = self.subst_kw(nkw['custom_tests'])
except KeyError:
pass
- return apply(SCons.SConf.SConf, nargs, nkw)
+ return SCons.SConf.SConf(*nargs, **nkw)
def Command(self, target, source, action, **kw):
"""Builds the supplied target files from the supplied
@@ -1877,8 +1864,8 @@ class Base(SubstitutionEnvironment):
try: bkw['source_scanner'] = kw['source_scanner']
except KeyError: pass
else: del kw['source_scanner']
- bld = apply(SCons.Builder.Builder, (), bkw)
- return apply(bld, (self, target, source), kw)
+ bld = SCons.Builder.Builder(**bkw)
+ return bld(self, target, source, **kw)
def Depends(self, target, dependency):
"""Explicity specify that 'target's depend on 'dependency'."""
@@ -1895,9 +1882,9 @@ class Base(SubstitutionEnvironment):
if SCons.Util.is_Sequence(s):
result=[]
for e in s:
- result.append(apply(self.fs.Dir, (e,) + args, kw))
+ result.append(self.fs.Dir(e, *args, **kw))
return result
- return apply(self.fs.Dir, (s,) + args, kw)
+ return self.fs.Dir(s, *args, **kw)
def NoClean(self, *targets):
"""Tags a target so that it will not be cleaned by -c"""
@@ -1924,17 +1911,17 @@ class Base(SubstitutionEnvironment):
if SCons.Util.is_Sequence(s):
result=[]
for e in s:
- result.append(apply(self.fs.Entry, (e,) + args, kw))
+ result.append(self.fs.Entry(e, *args, **kw))
return result
- return apply(self.fs.Entry, (s,) + args, kw)
+ return self.fs.Entry(s, *args, **kw)
def Environment(self, **kw):
- return apply(SCons.Environment.Environment, [], self.subst_kw(kw))
+ return SCons.Environment.Environment(**self.subst_kw(kw))
def Execute(self, action, *args, **kw):
"""Directly execute an action through an Environment
"""
- action = apply(self.Action, (action,) + args, kw)
+ action = self.Action(action, *args, **kw)
result = action([], [], self)
if isinstance(result, SCons.Errors.BuildError):
errstr = result.errstr
@@ -1952,9 +1939,9 @@ class Base(SubstitutionEnvironment):
if SCons.Util.is_Sequence(s):
result=[]
for e in s:
- result.append(apply(self.fs.File, (e,) + args, kw))
+ result.append(self.fs.File(e, *args, **kw))
return result
- return apply(self.fs.File, (s,) + args, kw)
+ return self.fs.File(s, *args, **kw)
def FindFile(self, file, dirs):
file = self.subst(file)
@@ -1965,7 +1952,7 @@ class Base(SubstitutionEnvironment):
return SCons.Util.flatten(sequence)
def GetBuildPath(self, files):
- result = map(str, self.arg2nodes(files, self.fs.Entry))
+ result = list(map(str, self.arg2nodes(files, self.fs.Entry)))
if SCons.Util.is_List(files):
return result
else:
@@ -2007,7 +1994,7 @@ class Base(SubstitutionEnvironment):
def Repository(self, *dirs, **kw):
dirs = self.arg2nodes(list(dirs), self.fs.Dir)
- apply(self.fs.Repository, dirs, kw)
+ self.fs.Repository(*dirs, **kw)
def Requires(self, target, prerequisite):
"""Specify that 'prerequisite' must be built before 'target',
@@ -2026,7 +2013,7 @@ class Base(SubstitutionEnvironment):
arg = self.subst(arg)
nargs.append(arg)
nkw = self.subst_kw(kw)
- return apply(SCons.Scanner.Base, nargs, nkw)
+ return SCons.Scanner.Base(*nargs, **nkw)
def SConsignFile(self, name=".sconsign", dbm_module=None):
if name is not None:
@@ -2048,7 +2035,7 @@ class Base(SubstitutionEnvironment):
for side_effect in side_effects:
if side_effect.multiple_side_effect_has_builder():
- raise SCons.Errors.UserError, "Multiple ways to build the same target were specified for: %s" % str(side_effect)
+ raise SCons.Errors.UserError("Multiple ways to build the same target were specified for: %s" % str(side_effect))
side_effect.add_source(targets)
side_effect.side_effect = 1
self.Precious(side_effect)
@@ -2058,6 +2045,9 @@ class Base(SubstitutionEnvironment):
def SourceCode(self, entry, builder):
"""Arrange for a source code builder for (part of) a tree."""
+ msg = """SourceCode() has been deprecated and there is no replacement.
+\tIf you need this function, please contact dev@scons.tigris.org."""
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedSourceCodeWarning, msg)
entries = self.arg2nodes(entry, self.fs.Entry)
for entry in entries:
entry.set_src_builder(builder)
@@ -2074,12 +2064,12 @@ class Base(SubstitutionEnvironment):
self.src_sig_type = type
if type == 'MD5':
if not SCons.Util.md5:
- raise UserError, "MD5 signatures are not available in this version of Python."
+ raise UserError("MD5 signatures are not available in this version of Python.")
self.decide_source = self._changed_content
elif type == 'timestamp':
self.decide_source = self._changed_timestamp_match
else:
- raise UserError, "Unknown source signature type '%s'" % type
+ raise UserError("Unknown source signature type '%s'" % type)
def Split(self, arg):
"""This function converts a string or list into a list of strings
@@ -2093,9 +2083,9 @@ class Base(SubstitutionEnvironment):
in the list are not split at spaces.
In all cases, the function returns a list of Nodes and strings."""
if SCons.Util.is_List(arg):
- return map(self.subst, arg)
+ return list(map(self.subst, arg))
elif SCons.Util.is_String(arg):
- return string.split(self.subst(arg))
+ return self.subst(arg).split()
else:
return [self.subst(arg)]
@@ -2110,7 +2100,7 @@ class Base(SubstitutionEnvironment):
self.tgt_sig_type = type
if type in ('MD5', 'content'):
if not SCons.Util.md5:
- raise UserError, "MD5 signatures are not available in this version of Python."
+ raise UserError("MD5 signatures are not available in this version of Python.")
self.decide_target = self._changed_content
elif type == 'timestamp':
self.decide_target = self._changed_timestamp_match
@@ -2119,7 +2109,7 @@ class Base(SubstitutionEnvironment):
elif type == 'source':
self.decide_target = self._changed_source
else:
- raise UserError, "Unknown target signature type '%s'"%type
+ raise UserError("Unknown target signature type '%s'"%type)
def Value(self, value, built_value=None):
"""
@@ -2137,17 +2127,15 @@ class Base(SubstitutionEnvironment):
node = self.arg2nodes(node, self.fs.Entry)[0]
sources = []
- # Uncomment this and get rid of the global definition when we
- # drop support for pre-2.2 Python versions.
- #def build_source(ss, result):
- # for s in ss:
- # if isinstance(s, SCons.Node.FS.Dir):
- # build_source(s.all_children(), result)
- # elif s.has_builder():
- # build_source(s.sources, result)
- # elif isinstance(s.disambiguate(), SCons.Node.FS.File):
- # result.append(s)
- build_source(node.all_children(), sources)
+ def build_source(ss):
+ for s in ss:
+ if isinstance(s, SCons.Node.FS.Dir):
+ build_source(s.all_children())
+ elif s.has_builder():
+ build_source(s.sources)
+ elif isinstance(s.disambiguate(), SCons.Node.FS.File):
+ sources.append(s)
+ build_source(node.all_children())
# THIS CODE APPEARS TO HAVE NO EFFECT
# # get the final srcnode for all nodes, this means stripping any
@@ -2208,7 +2196,7 @@ class OverrideEnvironment(Base):
return self.__dict__['__subject'].__getitem__(key)
def __setitem__(self, key, value):
if not is_valid_construction_var(key):
- raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
+ raise SCons.Errors.UserError("Illegal construction variable `%s'" % key)
self.__dict__['overrides'][key] = value
def __delitem__(self, key):
try:
@@ -2235,7 +2223,7 @@ class OverrideEnvironment(Base):
self.__dict__['overrides'][key]
return 1
except KeyError:
- return self.__dict__['__subject'].has_key(key)
+ return key in self.__dict__['__subject']
def __contains__(self, key):
if self.__dict__['overrides'].__contains__(key):
return 1
@@ -2247,7 +2235,7 @@ class OverrideEnvironment(Base):
return d
def items(self):
"""Emulates the items() method of dictionaries."""
- return self.Dictionary().items()
+ return list(self.Dictionary().items())
# Overridden private construction environment methods.
def _update(self, dict):
@@ -2314,13 +2302,13 @@ def NoSubstitutionProxy(subject):
nkw = kwargs.copy()
nkw['gvars'] = {}
self.raw_to_mode(nkw)
- return apply(SCons.Subst.scons_subst_list, nargs, nkw)
+ return SCons.Subst.scons_subst_list(*nargs, **nkw)
def subst_target_source(self, string, *args, **kwargs):
nargs = (string, self,) + args
nkw = kwargs.copy()
nkw['gvars'] = {}
self.raw_to_mode(nkw)
- return apply(SCons.Subst.scons_subst, nargs, nkw)
+ return SCons.Subst.scons_subst(*nargs, **nkw)
return _NoSubstitutionProxy(subject)
# Local Variables:
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index f3bb798..b466498 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -21,16 +21,17 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/EnvironmentTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/EnvironmentTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import copy
+import io
import os
-import string
-import StringIO
import sys
import TestCmd
import unittest
-import UserList
+from collections import UserDict as UD, UserList as UL
from SCons.Environment import *
import SCons.Warnings
@@ -39,19 +40,17 @@ def diff_env(env1, env2):
s1 = "env1 = {\n"
s2 = "env2 = {\n"
d = {}
- for k in env1._dict.keys() + env2._dict.keys():
+ for k in list(env1._dict.keys()) + list(env2._dict.keys()):
d[k] = None
- keys = d.keys()
- keys.sort()
- for k in keys:
- if env1.has_key(k):
- if env2.has_key(k):
+ for k in sorted(d.keys()):
+ if k in env1:
+ if k in env2:
if env1[k] != env2[k]:
s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
else:
s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n"
- elif env2.has_key(k):
+ elif k in env2:
s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n"
s1 = s1 + "}\n"
s2 = s2 + "}\n"
@@ -61,19 +60,17 @@ def diff_dict(d1, d2):
s1 = "d1 = {\n"
s2 = "d2 = {\n"
d = {}
- for k in d1.keys() + d2.keys():
+ for k in list(d1.keys()) + list(d2.keys()):
d[k] = None
- keys = d.keys()
- keys.sort()
- for k in keys:
- if d1.has_key(k):
- if d2.has_key(k):
+ for k in sorted(d.keys()):
+ if k in d1:
+ if k in d2:
if d1[k] != d2[k]:
s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
else:
s1 = s1 + " " + repr(k) + " : " + repr(d1[k]) + "\n"
- elif env2.has_key(k):
+ elif k in env2:
s2 = s2 + " " + repr(k) + " : " + repr(d2[k]) + "\n"
s1 = s1 + "}\n"
s2 = s2 + "}\n"
@@ -103,7 +100,7 @@ class Builder(SCons.Builder.BuilderBase):
scanned_it = {}
-class Scanner:
+class Scanner(object):
"""A dummy Scanner class for testing purposes. "Scanning"
a target is simply setting a value in the dictionary.
"""
@@ -129,21 +126,21 @@ class Scanner:
-class CLVar(UserList.UserList):
+class CLVar(UL):
def __init__(self, seq):
- if type(seq) == type(''):
- seq = string.split(seq)
- UserList.UserList.__init__(self, seq)
+ if isinstance(seq, str):
+ seq = seq.split()
+ UL.__init__(self, seq)
def __add__(self, other):
- return UserList.UserList.__add__(self, CLVar(other))
+ return UL.__add__(self, CLVar(other))
def __radd__(self, other):
- return UserList.UserList.__radd__(self, CLVar(other))
+ return UL.__radd__(self, CLVar(other))
def __coerce__(self, other):
return (self, CLVar(other))
-class DummyNode:
+class DummyNode(object):
def __init__(self, name):
self.name = name
def __str__(self):
@@ -156,17 +153,17 @@ class DummyNode:
def test_tool( env ):
env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
-class TestEnvironmentFixture:
+class TestEnvironmentFixture(object):
def TestEnvironment(self, *args, **kw):
- if not kw or not kw.has_key('tools'):
+ if not kw or 'tools' not in kw:
kw['tools'] = [test_tool]
default_keys = { 'CC' : 'cc',
'CCFLAGS' : '-DNDEBUG',
'ENV' : { 'TMP' : '/tmp' } }
for key, value in default_keys.items():
- if not kw.has_key(key):
+ if key not in kw:
kw[key] = value
- if not kw.has_key('BUILDERS'):
+ if 'BUILDERS' not in kw:
static_obj = SCons.Builder.Builder(action = {},
emitter = {},
suffix = '.o',
@@ -174,7 +171,7 @@ class TestEnvironmentFixture:
kw['BUILDERS'] = {'Object' : static_obj}
static_obj.add_action('.cpp', 'fake action')
- env = apply(Environment, args, kw)
+ env = Environment(*args, **kw)
return env
class SubstitutionTestCase(unittest.TestCase):
@@ -183,7 +180,7 @@ class SubstitutionTestCase(unittest.TestCase):
"""Test initializing a SubstitutionEnvironment
"""
env = SubstitutionEnvironment()
- assert not env.has_key('__env__')
+ assert '__env__' not in env
def test___cmp__(self):
"""Test comparing SubstitutionEnvironments
@@ -231,29 +228,21 @@ class SubstitutionTestCase(unittest.TestCase):
"""Test the SubstitutionEnvironment has_key() method
"""
env = SubstitutionEnvironment(XXX = 'x')
- assert env.has_key('XXX')
- assert not env.has_key('YYY')
+ assert 'XXX' in env
+ assert 'YYY' not in env
def test_contains(self):
"""Test the SubstitutionEnvironment __contains__() method
"""
- try:
- 'x' in {'x':1}
- except TypeError:
- # TODO(1.5)
- # An early version of Python that doesn't support "in"
- # on dictionaries. Just pass the test.
- pass
- else:
- env = SubstitutionEnvironment(XXX = 'x')
- assert 'XXX' in env
- assert not 'YYY' in env
+ env = SubstitutionEnvironment(XXX = 'x')
+ assert 'XXX' in env
+ assert not 'YYY' in env
def test_items(self):
"""Test the SubstitutionEnvironment items() method
"""
env = SubstitutionEnvironment(XXX = 'x', YYY = 'y')
- items = env.items()
+ items = list(env.items())
assert items == [('XXX','x'), ('YYY','y')], items
def test_arg2nodes(self):
@@ -264,7 +253,7 @@ class SubstitutionTestCase(unittest.TestCase):
class X(SCons.Node.Node):
pass
def Factory(name, directory = None, create = 1, dict=dict, X=X):
- if not dict.has_key(name):
+ if name not in dict:
dict[name] = X()
dict[name].name = name
return dict[name]
@@ -274,8 +263,9 @@ class SubstitutionTestCase(unittest.TestCase):
assert isinstance(nodes[0], X)
assert nodes[0].name == "Util.py UtilTests.py"
- import types
- if hasattr(types, 'UnicodeType'):
+ try: unicode
+ except NameError: pass
+ else:
code = """if 1:
nodes = env.arg2nodes(u"Util.py UtilTests.py", Factory)
assert len(nodes) == 1, nodes
@@ -305,7 +295,7 @@ class SubstitutionTestCase(unittest.TestCase):
assert len(nodes) == 1, nodes
assert isinstance(nodes[0], SConsNode), node
- class OtherNode:
+ class OtherNode(object):
pass
nodes = env.arg2nodes(OtherNode())
assert len(nodes) == 1, nodes
@@ -390,7 +380,7 @@ class SubstitutionTestCase(unittest.TestCase):
DummyNode,
target=targets,
source=sources)
- names = map(lambda n: n.name, nodes)
+ names = [n.name for n in nodes]
assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names
def test_gvars(self):
@@ -547,13 +537,13 @@ class SubstitutionTestCase(unittest.TestCase):
def test_subst_path(self):
"""Test substituting a path list
"""
- class MyProxy:
+ class MyProxy(object):
def __init__(self, val):
self.val = val
def get(self):
return self.val + '-proxy'
- class MyNode:
+ class MyNode(object):
def __init__(self, val):
self.val = val
def get_subst_proxy(self):
@@ -561,7 +551,7 @@ class SubstitutionTestCase(unittest.TestCase):
def __str__(self):
return self.val
- class MyObj:
+ class MyObj(object):
def get(self):
return self
@@ -577,23 +567,23 @@ class SubstitutionTestCase(unittest.TestCase):
assert r == ['foo', 'xxx', 'bar'], r
r = env.subst_path(['$FOO', '$LIST', '$BAR'])
- assert map(str, r) == ['foo', 'one two', 'bar'], r
+ assert list(map(str, r)) == ['foo', 'one two', 'bar'], r
r = env.subst_path(['$FOO', '$TARGET', '$SOURCE', '$BAR'])
assert r == ['foo', '', '', 'bar'], r
r = env.subst_path(['$FOO', '$TARGET', '$BAR'], target=MyNode('ttt'))
- assert map(str, r) == ['foo', 'ttt', 'bar'], r
+ assert list(map(str, r)) == ['foo', 'ttt', 'bar'], r
r = env.subst_path(['$FOO', '$SOURCE', '$BAR'], source=MyNode('sss'))
- assert map(str, r) == ['foo', 'sss', 'bar'], r
+ assert list(map(str, r)) == ['foo', 'sss', 'bar'], r
n = MyObj()
r = env.subst_path(['$PROXY', MyProxy('my2'), n])
assert r == ['my1-proxy', 'my2-proxy', n], r
- class StringableObj:
+ class StringableObj(object):
def __init__(self, s):
self.s = s
def __str__(self):
@@ -647,21 +637,21 @@ sys.exit(0)
python = '"' + sys.executable + '"'
try:
- sys.stderr = StringIO.StringIO()
+ sys.stderr = io.StringIO()
cmd = '%s %s' % (python, test.workpath('stdout.py'))
output = env.backtick(cmd)
errout = sys.stderr.getvalue()
assert output == 'this came from stdout.py\n', output
assert errout == '', errout
- sys.stderr = StringIO.StringIO()
+ sys.stderr = io.StringIO()
cmd = '%s %s' % (python, test.workpath('stderr.py'))
output = env.backtick(cmd)
errout = sys.stderr.getvalue()
assert output == '', output
assert errout == 'this came from stderr.py\n', errout
- sys.stderr = StringIO.StringIO()
+ sys.stderr = io.StringIO()
cmd = '%s %s' % (python, test.workpath('fail.py'))
try:
env.backtick(cmd)
@@ -670,7 +660,7 @@ sys.exit(0)
else:
self.fail("did not catch expected OSError")
- sys.stderr = StringIO.StringIO()
+ sys.stderr = io.StringIO()
cmd = '%s %s' % (python, test.workpath('echo.py'))
env['ENV'] = os.environ.copy()
env['ENV']['ECHO'] = 'this came from ECHO'
@@ -830,7 +820,7 @@ sys.exit(0)
assert d['LIBPATH'] == ['/usr/fax',
'foo',
'C:\\Program Files\\ASCEND'], d['LIBPATH']
- LIBS = map(str, d['LIBS'])
+ LIBS = list(map(str, d['LIBS']))
assert LIBS == ['xxx', 'yyy', 'ascend'], (d['LIBS'], LIBS)
assert d['LINKFLAGS'] == ['-Wl,-link', '-pthread',
'-mno-cygwin', '-mwindows',
@@ -845,7 +835,7 @@ sys.exit(0)
"""
env = SubstitutionEnvironment()
env.MergeFlags('')
- assert not env.has_key('CCFLAGS'), env['CCFLAGS']
+ assert 'CCFLAGS' not in env, env['CCFLAGS']
env.MergeFlags('-X')
assert env['CCFLAGS'] == ['-X'], env['CCFLAGS']
env.MergeFlags('-X')
@@ -909,12 +899,12 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture):
env2 = self.TestEnvironment(XXX = 'x', YYY = 'y')
assert env1 == env2, diff_env(env1, env2)
- assert not env1.has_key('__env__')
- assert not env2.has_key('__env__')
+ assert '__env__' not in env1
+ assert '__env__' not in env2
def test_variables(self):
"""Test that variables only get applied once."""
- class FakeOptions:
+ class FakeOptions(object):
def __init__(self, key, val):
self.calls = 0
self.key = key
@@ -1088,69 +1078,69 @@ env4.builder1.env, env3)
env = Environment()
try: del env['SCANNERS']
except KeyError: pass
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [None, None, None, None, None], s
env = self.TestEnvironment(SCANNERS = [])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [None, None, None, None, None], s
env.Replace(SCANNERS = [s1])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, None, None], s
env.Append(SCANNERS = [s2])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, s2, None], s
env.AppendUnique(SCANNERS = [s3])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, s2, s3], s
env = env.Clone(SCANNERS = [s2])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [None, None, None, s2, None], s
env['SCANNERS'] = [s1]
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, None, None], s
env.PrependUnique(SCANNERS = [s2, s1])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, s2, None], s
env.Prepend(SCANNERS = [s3])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, s3, s3], s
# Verify behavior of case-insensitive suffix matches on Windows.
- uc_suffixes = map(string.upper, suffixes)
+ uc_suffixes = [_.upper() for _ in suffixes]
env = Environment(SCANNERS = [s1, s2, s3],
PLATFORM = 'linux')
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [s1, s1, None, s2, s3], s
- s = map(env.get_scanner, uc_suffixes)
+ s = list(map(env.get_scanner, uc_suffixes))
assert s == [None, None, None, None, None], s
env['PLATFORM'] = 'win32'
- s = map(env.get_scanner, uc_suffixes)
+ s = list(map(env.get_scanner, uc_suffixes))
assert s == [s1, s1, None, s2, s3], s
# Verify behavior for a scanner returning None (on Windows
# where we might try to perform case manipulation on None).
env.Replace(SCANNERS = [s4])
- s = map(env.get_scanner, suffixes)
+ s = list(map(env.get_scanner, suffixes))
assert s == [None, None, None, None, None], s
def test_ENV(self):
"""Test setting the external ENV in Environments
"""
env = Environment()
- assert env.Dictionary().has_key('ENV')
+ assert 'ENV' in env.Dictionary()
env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' })
assert env.Dictionary('ENV')['PATH'] == '/foo:/bar'
@@ -1182,7 +1172,7 @@ env4.builder1.env, env3)
except warning:
exc_caught = 1
assert exc_caught, "Did not catch ReservedVariableWarning for `%s'" % kw
- assert not env4.has_key(kw), "`%s' variable was incorrectly set" % kw
+ assert kw not in env4, "`%s' variable was incorrectly set" % kw
finally:
SCons.Warnings.warningAsException(old)
@@ -1204,7 +1194,7 @@ env4.builder1.env, env3)
except warning:
exc_caught = 1
assert exc_caught, "Did not catch FutureReservedVariableWarning for `%s'" % kw
- assert env4.has_key(kw), "`%s' variable was not set" % kw
+ assert kw in env4, "`%s' variable was not set" % kw
finally:
SCons.Warnings.warningAsException(old)
@@ -1233,7 +1223,7 @@ env4.builder1.env, env3)
path = drive + path
path = os.path.normpath(path)
drive, path = os.path.splitdrive(path)
- return string.lower(drive) + path
+ return drive.lower() + path
env = dict.TestEnvironment(LIBS = [ 'foo', 'bar', 'baz' ],
LIBLINKPREFIX = 'foo',
@@ -1290,7 +1280,7 @@ env4.builder1.env, env3)
env.fs.Repository('/rep1')
env.fs.Repository('/rep2')
- env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
+ env.Replace(CPPPATH = [ 'foo', '/__a__/b', '$FOO/bar', blat],
INCPREFIX = '-I ',
INCSUFFIX = 'XXX',
FOO = 'baz')
@@ -1299,7 +1289,7 @@ env4.builder1.env, env3)
'-I', normalize_path('xx/fooXXX'),
'-I', normalize_path('/rep1/xx/fooXXX'),
'-I', normalize_path('/rep2/xx/fooXXX'),
- '-I', normalize_path('/a/bXXX'),
+ '-I', normalize_path('/__a__/bXXX'),
'-I', normalize_path('xx/baz/barXXX'),
'-I', normalize_path('/rep1/xx/baz/barXXX'),
'-I', normalize_path('/rep2/xx/baz/barXXX'),
@@ -1310,12 +1300,12 @@ env4.builder1.env, env3)
if arg not in ('$(','$)','-I'):
return np(str(arg))
return arg
- flags = map(normalize_if_path, flags)
+ flags = list(map(normalize_if_path, flags))
assert flags == expect, flags
def test_platform(self):
"""Test specifying a platform callable when instantiating."""
- class platform:
+ class platform(object):
def __str__(self): return "TestPlatform"
def __call__(self, env): env['XYZZY'] = 777
@@ -1330,7 +1320,7 @@ env4.builder1.env, env3)
def test_Default_PLATFORM(self):
"""Test overriding the default PLATFORM variable"""
- class platform:
+ class platform(object):
def __str__(self): return "DefaultTestPlatform"
def __call__(self, env): env['XYZZY'] = 888
@@ -1481,11 +1471,6 @@ def exists(env):
b2 = Environment()['BUILDERS']
assert b1 == b2, diff_dict(b1, b2)
- import UserDict
- UD = UserDict.UserDict
- import UserList
- UL = UserList.UserList
-
cases = [
'a1', 'A1', 'a1A1',
'a2', ['A2'], ['a2', 'A2'],
@@ -1606,13 +1591,13 @@ def exists(env):
assert isinstance(result, CLVar), repr(result)
assert result == ['foo', 'bar'], result
- class C:
+ class C(object):
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
def __cmp__(self, other):
- raise "should not compare"
+ raise Exception("should not compare")
ccc = C('ccc')
@@ -1713,17 +1698,8 @@ def exists(env):
env['CLVar'] = CLVar([])
env.AppendUnique(CLVar = 'bar')
result = env['CLVar']
- if sys.version[0] == '1' or sys.version[:3] == '2.0':
- # Python 2.0 and before have a quirky behavior where CLVar([])
- # actually matches '' and [] due to different __coerce__()
- # semantics in the UserList implementation. It isn't worth a
- # lot of effort to get this corner case to work identically
- # (support for Python 1.5 support will die soon anyway),
- # so just treat it separately for now.
- assert result == 'bar', result
- else:
- assert isinstance(result, CLVar), repr(result)
- assert result == ['bar'], result
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
env['CLVar'] = CLVar(['abc'])
env.AppendUnique(CLVar = 'bar')
@@ -1766,7 +1742,7 @@ def exists(env):
# Ensure that lists and dictionaries are
# deep copied, but not instances.
- class TestA:
+ class TestA(object):
pass
env1 = self.TestEnvironment(XXX=TestA(), YYY = [ 1, 2, 3 ],
ZZZ = { 1:2, 3:4 })
@@ -1776,8 +1752,8 @@ def exists(env):
assert env1.Dictionary('XXX') is env2.Dictionary('XXX')
assert 4 in env2.Dictionary('YYY')
assert not 4 in env1.Dictionary('YYY')
- assert env2.Dictionary('ZZZ').has_key(5)
- assert not env1.Dictionary('ZZZ').has_key(5)
+ assert 5 in env2.Dictionary('ZZZ')
+ assert 5 not in env1.Dictionary('ZZZ')
#
env1 = self.TestEnvironment(BUILDERS = {'b1' : Builder()})
@@ -1953,16 +1929,16 @@ def generate(env):
xxx, zzz = env.Dictionary('XXX', 'ZZZ')
assert xxx == 'x'
assert zzz == 'z'
- assert env.Dictionary().has_key('BUILDERS')
- assert env.Dictionary().has_key('CC')
- assert env.Dictionary().has_key('CCFLAGS')
- assert env.Dictionary().has_key('ENV')
+ assert 'BUILDERS' in env.Dictionary()
+ assert 'CC' in env.Dictionary()
+ assert 'CCFLAGS' in env.Dictionary()
+ assert 'ENV' in env.Dictionary()
assert env['XXX'] == 'x'
env['XXX'] = 'foo'
assert env.Dictionary('XXX') == 'foo'
del env['XXX']
- assert not env.Dictionary().has_key('XXX')
+ assert 'XXX' not in env.Dictionary()
def test_FindIxes(self):
"Test FindIxes()"
@@ -2002,7 +1978,7 @@ def generate(env):
RPATH=[])
orig_backtick = env.backtick
- class my_backtick:
+ class my_backtick(object):
def __init__(self, save_command, output):
self.save_command = save_command
self.output = output
@@ -2105,8 +2081,8 @@ f5: \
del dlist[:]
env.ParseDepends('$SINGLE', only_one=1)
- t = map(str, tlist)
- d = map(str, dlist)
+ t = list(map(str, tlist))
+ d = list(map(str, dlist))
assert t == ['f0'], t
assert d == ['d1', 'd2', 'd3'], d
@@ -2114,8 +2090,8 @@ f5: \
del dlist[:]
env.ParseDepends(test.workpath('multiple'))
- t = map(str, tlist)
- d = map(str, dlist)
+ t = list(map(str, tlist))
+ d = list(map(str, dlist))
assert t == ['f1', 'f2', 'f3', 'f4', 'f5'], t
assert d == ['foo', 'bar', 'abc', 'def', 'ghi', 'jkl', 'mno'], d
@@ -2153,11 +2129,6 @@ f5: \
def test_Prepend(self):
"""Test prepending to construction variables in an Environment
"""
- import UserDict
- UD = UserDict.UserDict
- import UserList
- UL = UserList.UserList
-
cases = [
'a1', 'A1', 'A1a1',
'a2', ['A2'], ['A2', 'a2'],
@@ -2368,17 +2339,8 @@ f5: \
env['CLVar'] = CLVar([])
env.PrependUnique(CLVar = 'bar')
result = env['CLVar']
- if sys.version[0] == '1' or sys.version[:3] == '2.0':
- # Python 2.0 and before have a quirky behavior where CLVar([])
- # actually matches '' and [] due to different __coerce__()
- # semantics in the UserList implementation. It isn't worth a
- # lot of effort to get this corner case to work identically
- # (support for Python 1.5 support will die soon anyway),
- # so just treat it separately for now.
- assert result == 'bar', result
- else:
- assert isinstance(result, CLVar), repr(result)
- assert result == ['bar'], result
+ assert isinstance(result, CLVar), repr(result)
+ assert result == ['bar'], result
env['CLVar'] = CLVar(['abc'])
env.PrependUnique(CLVar = 'bar')
@@ -2519,21 +2481,21 @@ def generate(env):
test.workpath('sub2'),
test.workpath('sub3'),
test.workpath('sub4'),
- ] + string.split(env_path, os.pathsep)
+ ] + env_path.split(os.pathsep)
pathdirs_1243 = [ test.workpath('sub1'),
test.workpath('sub2'),
test.workpath('sub4'),
test.workpath('sub3'),
- ] + string.split(env_path, os.pathsep)
+ ] + env_path.split(os.pathsep)
- path = string.join(pathdirs_1234, os.pathsep)
+ path = os.pathsep.join(pathdirs_1234)
env = self.TestEnvironment(ENV = {'PATH' : path})
wi = env.WhereIs('xxx.exe')
assert wi == test.workpath(sub3_xxx_exe), wi
wi = env.WhereIs('xxx.exe', pathdirs_1243)
assert wi == test.workpath(sub4_xxx_exe), wi
- wi = env.WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
+ wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
assert wi == test.workpath(sub4_xxx_exe), wi
wi = env.WhereIs('xxx.exe', reject = sub3_xxx_exe)
@@ -2541,13 +2503,13 @@ def generate(env):
wi = env.WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
assert wi == test.workpath(sub4_xxx_exe), wi
- path = string.join(pathdirs_1243, os.pathsep)
+ path = os.pathsep.join(pathdirs_1243)
env = self.TestEnvironment(ENV = {'PATH' : path})
wi = env.WhereIs('xxx.exe')
assert wi == test.workpath(sub4_xxx_exe), wi
wi = env.WhereIs('xxx.exe', pathdirs_1234)
assert wi == test.workpath(sub3_xxx_exe), wi
- wi = env.WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
+ wi = env.WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
assert wi == test.workpath(sub3_xxx_exe), wi
if sys.platform == 'win32':
@@ -2558,13 +2520,13 @@ def generate(env):
assert wi == test.workpath(sub4_xxx_exe), wi
wi = env.WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
- assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+ assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
# Test that we return a normalized path even when
# the path contains forward slashes.
forward_slash = test.workpath('') + '/sub3'
wi = env.WhereIs('xxx', path = forward_slash, pathext = '.EXE')
- assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+ assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
@@ -2637,37 +2599,37 @@ def generate(env):
tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
assert str(tgt) == 'export_alias', tgt
- assert len(tgt.sources) == 2, map(str, tgt.sources)
- assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
- assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
+ assert len(tgt.sources) == 2, list(map(str, tgt.sources))
+ assert str(tgt.sources[0]) == 'asrc1', list(map(str, tgt.sources))
+ assert str(tgt.sources[1]) == 'kkk', list(map(str, tgt.sources))
n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
assert n is tgt, n
- assert len(tgt.sources) == 4, map(str, tgt.sources)
- assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
- assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
+ assert len(tgt.sources) == 4, list(map(str, tgt.sources))
+ assert str(tgt.sources[2]) == 'lll', list(map(str, tgt.sources))
+ assert str(tgt.sources[3]) == 'asrc4', list(map(str, tgt.sources))
n = env.Alias('$EA', 'asrc5')[0]
assert n is tgt, n
- assert len(tgt.sources) == 5, map(str, tgt.sources)
- assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
+ assert len(tgt.sources) == 5, list(map(str, tgt.sources))
+ assert str(tgt.sources[4]) == 'asrc5', list(map(str, tgt.sources))
t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
assert str(t1) == 't1', t1
assert str(t2) == 't2', t2
- assert len(t1.sources) == 2, map(str, t1.sources)
- assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
- assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
- assert len(t2.sources) == 2, map(str, t2.sources)
- assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
- assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
+ assert len(t1.sources) == 2, list(map(str, t1.sources))
+ assert str(t1.sources[0]) == 'asrc6', list(map(str, t1.sources))
+ assert str(t1.sources[1]) == 'asrc7', list(map(str, t1.sources))
+ assert len(t2.sources) == 2, list(map(str, t2.sources))
+ assert str(t2.sources[0]) == 'asrc6', list(map(str, t2.sources))
+ assert str(t2.sources[1]) == 'asrc7', list(map(str, t2.sources))
tgt = env.Alias('add', 's1')
tgt = env.Alias('add', 's2')[0]
- s = map(str, tgt.sources)
+ s = list(map(str, tgt.sources))
assert s == ['s1', 's2'], s
tgt = env.Alias(tgt, 's3')[0]
- s = map(str, tgt.sources)
+ s = list(map(str, tgt.sources))
assert s == ['s1', 's2', 's3'], s
tgt = env.Alias('act', None, "action1")[0]
@@ -2709,7 +2671,7 @@ def generate(env):
def test_VariantDir(self):
"""Test the VariantDir() method"""
- class MyFS:
+ class MyFS(object):
def Dir(self, name):
return name
def VariantDir(self, variant_dir, src_dir, duplicate):
@@ -2770,20 +2732,20 @@ def generate(env):
fff = env.arg2nodes('fff')[0]
t = env.Clean('foo', 'aaa')
- l = map(str, CT[foo])
+ l = list(map(str, CT[foo]))
assert l == ['aaa'], l
t = env.Clean(foo, ['$BAR', 'ccc'])
- l = map(str, CT[foo])
+ l = list(map(str, CT[foo]))
assert l == ['aaa', 'bbb', 'ccc'], l
eee = env.arg2nodes('eee')[0]
t = env.Clean('$FOO', 'ddd')
- l = map(str, CT[fff])
+ l = list(map(str, CT[fff]))
assert l == ['ddd'], l
t = env.Clean(fff, [eee, 'fff'])
- l = map(str, CT[fff])
+ l = list(map(str, CT[fff]))
assert l == ['ddd', 'eee', 'fff'], l
def test_Command(self):
@@ -2794,25 +2756,25 @@ def generate(env):
assert t.builder is not None
assert t.builder.action.__class__.__name__ == 'CommandAction'
assert t.builder.action.cmd_list == 'buildfoo $target $source'
- assert 'foo1.in' in map(lambda x: x.path, t.sources)
- assert 'foo2.in' in map(lambda x: x.path, t.sources)
+ assert 'foo1.in' in [x.path for x in t.sources]
+ assert 'foo2.in' in [x.path for x in t.sources]
sub = env.fs.Dir('sub')
t = env.Command(target='bar.out', source='sub',
action='buildbar $target $source')[0]
- assert 'sub' in map(lambda x: x.path, t.sources)
+ assert 'sub' in [x.path for x in t.sources]
def testFunc(env, target, source):
assert str(target[0]) == 'foo.out'
- assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
+ assert 'foo1.in' in list(map(str, source)) and 'foo2.in' in list(map(str, source)), list(map(str, source))
return 0
t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
action=testFunc)[0]
assert t.builder is not None
assert t.builder.action.__class__.__name__ == 'FunctionAction'
t.build()
- assert 'foo1.in' in map(lambda x: x.path, t.sources)
- assert 'foo2.in' in map(lambda x: x.path, t.sources)
+ assert 'foo1.in' in [x.path for x in t.sources]
+ assert 'foo2.in' in [x.path for x in t.sources]
x = []
def test2(baz, x=x):
@@ -2829,7 +2791,7 @@ def generate(env):
action = 'foo',
X = 'xxx')[0]
assert str(t) == 'xxx.out', str(t)
- assert 'xxx.in' in map(lambda x: x.path, t.sources)
+ assert 'xxx.in' in [x.path for x in t.sources]
env = self.TestEnvironment(source_scanner = 'should_not_find_this')
t = env.Command(target='file.out', source='file.in',
@@ -2897,7 +2859,7 @@ def generate(env):
def test_Dir(self):
"""Test the Dir() method"""
- class MyFS:
+ class MyFS(object):
def Dir(self, name):
return 'Dir(%s)' % name
@@ -2960,7 +2922,7 @@ def generate(env):
def test_Execute(self):
"""Test the Execute() method"""
- class MyAction:
+ class MyAction(object):
def __init__(self, *args, **kw):
self.args = args
def __call__(self, target, source, env):
@@ -2974,7 +2936,7 @@ def generate(env):
def test_Entry(self):
"""Test the Entry() method"""
- class MyFS:
+ class MyFS(object):
def Entry(self, name):
return 'Entry(%s)' % name
@@ -2998,7 +2960,7 @@ def generate(env):
def test_File(self):
"""Test the File() method"""
- class MyFS:
+ class MyFS(object):
def File(self, name):
return 'File(%s)' % name
@@ -3123,7 +3085,7 @@ def generate(env):
def test_Repository(self):
"""Test the Repository() method."""
- class MyFS:
+ class MyFS(object):
def __init__(self):
self.list = []
def Repository(self, *dirs):
@@ -3161,7 +3123,7 @@ def generate(env):
"""Test the SConsignFile() method"""
import SCons.SConsign
- class MyFS:
+ class MyFS(object):
SConstruct_dir = os.sep + 'dir'
env = self.TestEnvironment(FOO = 'SConsign',
@@ -3422,9 +3384,9 @@ def generate(env):
bad_msg = '%s is not reserved, but got omitted; see Environment.construction_var_name_ok'
added.append('INIT')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
env.Append(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3437,9 +3399,9 @@ def generate(env):
APPEND = 'append')
added.append('APPEND')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
env.AppendUnique(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3452,9 +3414,9 @@ def generate(env):
APPENDUNIQUE = 'appendunique')
added.append('APPENDUNIQUE')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
env.Prepend(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3467,9 +3429,9 @@ def generate(env):
PREPEND = 'prepend')
added.append('PREPEND')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
env.Prepend(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3482,9 +3444,9 @@ def generate(env):
PREPENDUNIQUE = 'prependunique')
added.append('PREPENDUNIQUE')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
env.Replace(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3497,9 +3459,9 @@ def generate(env):
REPLACE = 'replace')
added.append('REPLACE')
for x in self.reserved_variables:
- assert not env.has_key(x), env[x]
+ assert x not in env, env[x]
for x in added:
- assert env.has_key(x), bad_msg % x
+ assert x in env, bad_msg % x
copy = env.Clone(TARGETS = 'targets',
SOURCES = 'sources',
@@ -3511,9 +3473,9 @@ def generate(env):
UNCHANGED_TARGETS = 'unchanged_targets',
COPY = 'copy')
for x in self.reserved_variables:
- assert not copy.has_key(x), env[x]
+ assert x not in copy, env[x]
for x in added + ['COPY']:
- assert copy.has_key(x), bad_msg % x
+ assert x in copy, bad_msg % x
over = env.Override({'TARGETS' : 'targets',
'SOURCES' : 'sources',
@@ -3525,9 +3487,9 @@ def generate(env):
'UNCHANGED_TARGETS' : 'unchanged_targets',
'OVERRIDE' : 'override'})
for x in self.reserved_variables:
- assert not over.has_key(x), over[x]
+ assert x not in over, over[x]
for x in added + ['OVERRIDE']:
- assert over.has_key(x), bad_msg % x
+ assert x in over, bad_msg % x
def test_parse_flags(self):
'''Test the Base class parse_flags argument'''
@@ -3548,7 +3510,7 @@ def generate(env):
# all we have to show is that it gets to MergeFlags internally
env = Environment(tools = [])
env2 = env.Clone(parse_flags = '-X')
- assert not env.has_key('CCFLAGS')
+ assert 'CCFLAGS' not in env
assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
env = Environment(tools = [], CCFLAGS=None)
@@ -3558,9 +3520,9 @@ def generate(env):
env = Environment(tools = [], CPPDEFINES = 'FOO')
env2 = env.Clone(parse_flags = '-std=c99 -X -DBAR')
- assert not env.has_key('CFLAGS')
+ assert 'CFLAGS' not in env
assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
- assert not env.has_key('CCFLAGS')
+ assert 'CCFLAGS' not in env
assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
@@ -3594,19 +3556,19 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
env, env2, env3 = self.envs
del env3['XXX']
- assert not env.has_key('XXX'), "env has XXX?"
- assert not env2.has_key('XXX'), "env2 has XXX?"
- assert not env3.has_key('XXX'), "env3 has XXX?"
+ assert 'XXX' not in env, "env has XXX?"
+ assert 'XXX' not in env2, "env2 has XXX?"
+ assert 'XXX' not in env3, "env3 has XXX?"
del env3['YYY']
- assert not env.has_key('YYY'), "env has YYY?"
- assert not env2.has_key('YYY'), "env2 has YYY?"
- assert not env3.has_key('YYY'), "env3 has YYY?"
+ assert 'YYY' not in env, "env has YYY?"
+ assert 'YYY' not in env2, "env2 has YYY?"
+ assert 'YYY' not in env3, "env3 has YYY?"
del env3['ZZZ']
- assert not env.has_key('ZZZ'), "env has ZZZ?"
- assert not env2.has_key('ZZZ'), "env2 has ZZZ?"
- assert not env3.has_key('ZZZ'), "env3 has ZZZ?"
+ assert 'ZZZ' not in env, "env has ZZZ?"
+ assert 'ZZZ' not in env2, "env2 has ZZZ?"
+ assert 'ZZZ' not in env3, "env3 has ZZZ?"
def test_get(self):
"""Test the OverrideEnvironment get() method"""
@@ -3624,36 +3586,28 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
def test_has_key(self):
"""Test the OverrideEnvironment has_key() method"""
env, env2, env3 = self.envs
- assert env.has_key('XXX'), env.has_key('XXX')
- assert env2.has_key('XXX'), env2.has_key('XXX')
- assert env3.has_key('XXX'), env3.has_key('XXX')
- assert env.has_key('YYY'), env.has_key('YYY')
- assert env2.has_key('YYY'), env2.has_key('YYY')
- assert env3.has_key('YYY'), env3.has_key('YYY')
- assert not env.has_key('ZZZ'), env.has_key('ZZZ')
- assert not env2.has_key('ZZZ'), env2.has_key('ZZZ')
- assert env3.has_key('ZZZ'), env3.has_key('ZZZ')
+ assert 'XXX' in env, 'XXX' in env
+ assert 'XXX' in env2, 'XXX' in env2
+ assert 'XXX' in env3, 'XXX' in env3
+ assert 'YYY' in env, 'YYY' in env
+ assert 'YYY' in env2, 'YYY' in env2
+ assert 'YYY' in env3, 'YYY' in env3
+ assert 'ZZZ' not in env, 'ZZZ' in env
+ assert 'ZZZ' not in env2, 'ZZZ' in env2
+ assert 'ZZZ' in env3, 'ZZZ' in env3
def test_contains(self):
"""Test the OverrideEnvironment __contains__() method"""
- try:
- 'x' in {'x':1}
- except TypeError:
- # TODO(1.5)
- # An early version of Python that doesn't support "in"
- # on dictionaries. Just pass the test.
- pass
- else:
- env, env2, env3 = self.envs
- assert 'XXX' in env
- assert 'XXX' in env2
- assert 'XXX' in env3
- assert 'YYY' in env
- assert 'YYY' in env2
- assert 'YYY' in env3
- assert not 'ZZZ' in env
- assert not 'ZZZ' in env2
- assert 'ZZZ' in env3
+ env, env2, env3 = self.envs
+ assert 'XXX' in env
+ assert 'XXX' in env2
+ assert 'XXX' in env3
+ assert 'YYY' in env
+ assert 'YYY' in env2
+ assert 'YYY' in env3
+ assert not 'ZZZ' in env
+ assert not 'ZZZ' in env2
+ assert 'ZZZ' in env3
def test_items(self):
"""Test the OverrideEnvironment Dictionary() method"""
@@ -3668,14 +3622,11 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
def test_items(self):
"""Test the OverrideEnvironment items() method"""
env, env2, env3 = self.envs
- items = env.items()
- items.sort()
+ items = sorted(env.items())
assert items == [('XXX', 'x'), ('YYY', 'y')], items
- items = env2.items()
- items.sort()
+ items = sorted(env2.items())
assert items == [('XXX', 'x2'), ('YYY', 'y')], items
- items = env3.items()
- items.sort()
+ items = sorted(env3.items())
assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items
def test_gvars(self):
@@ -3819,7 +3770,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
# all we have to show is that it gets to MergeFlags internally
env = SubstitutionEnvironment()
env2 = env.Override({'parse_flags' : '-X'})
- assert not env.has_key('CCFLAGS')
+ assert 'CCFLAGS' not in env
assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
env = SubstitutionEnvironment(CCFLAGS=None)
@@ -3829,9 +3780,9 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture):
env = SubstitutionEnvironment(CPPDEFINES = 'FOO')
env2 = env.Override({'parse_flags' : '-std=c99 -X -DBAR'})
- assert not env.has_key('CFLAGS')
+ assert 'CFLAGS' not in env
assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS']
- assert not env.has_key('CCFLAGS')
+ assert 'CCFLAGS' not in env
assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS']
assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES']
assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES']
@@ -3933,9 +3884,9 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture):
args = ('$XXX $TARGET $SOURCE $YYY',)
kw = {'target' : DummyNode('ttt'), 'source' : DummyNode('sss')}
- x = apply(env.subst_target_source, args, kw)
+ x = env.subst_target_source(*args, **kw)
assert x == 'x ttt sss y', x
- x = apply(proxy.subst_target_source, args, kw)
+ x = proxy.subst_target_source(*args, **kw)
assert x == ' ttt sss ', x
class EnvironmentVariableTestCase(unittest.TestCase):
@@ -3982,7 +3933,7 @@ if __name__ == "__main__":
EnvironmentVariableTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py
index 69b389a..542bc47 100644
--- a/src/engine/SCons/Errors.py
+++ b/src/engine/SCons/Errors.py
@@ -28,7 +28,7 @@ and user errors in SCons.
"""
-__revision__ = "src/engine/SCons/Errors.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Errors.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
@@ -133,7 +133,7 @@ class ExplicitExit(Exception):
self.node = node
self.status = status
self.exitstatus = status
- apply(Exception.__init__, (self,) + args)
+ Exception.__init__(self, *args)
def convert_to_BuildError(status, exc_info=None):
"""
@@ -157,9 +157,7 @@ def convert_to_BuildError(status, exc_info=None):
status=status, # might be 0, OK here
exitstatus=status, # might be 0, OK here
exc_info=exc_info)
- # TODO(1.5):
- #elif isinstance(status, (StopError, UserError)):
- elif isinstance(status, StopError) or isinstance(status, UserError):
+ elif isinstance(status, (StopError, UserError)):
buildError = BuildError(
errstr=str(status),
status=2,
diff --git a/src/engine/SCons/ErrorsTests.py b/src/engine/SCons/ErrorsTests.py
index 3bc852d..76d2c53 100644
--- a/src/engine/SCons/ErrorsTests.py
+++ b/src/engine/SCons/ErrorsTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/ErrorsTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/ErrorsTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -79,21 +79,21 @@ class ErrorsTestCase(unittest.TestCase):
def test_InternalError(self):
"""Test the InternalError exception."""
try:
- raise SCons.Errors.InternalError, "test internal error"
+ raise SCons.Errors.InternalError("test internal error")
except SCons.Errors.InternalError, e:
assert e.args == ("test internal error",)
def test_UserError(self):
"""Test the UserError exception."""
try:
- raise SCons.Errors.UserError, "test user error"
+ raise SCons.Errors.UserError("test user error")
except SCons.Errors.UserError, e:
assert e.args == ("test user error",)
def test_ExplicitExit(self):
"""Test the ExplicitExit exception."""
try:
- raise SCons.Errors.ExplicitExit, "node"
+ raise SCons.Errors.ExplicitExit("node")
except SCons.Errors.ExplicitExit, e:
assert e.node == "node"
diff --git a/src/engine/SCons/Executor.py b/src/engine/SCons/Executor.py
index 44a1b9e..7bb450a 100644
--- a/src/engine/SCons/Executor.py
+++ b/src/engine/SCons/Executor.py
@@ -26,19 +26,17 @@ Nodes.
# 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__ = "src/engine/SCons/Executor.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Executor.py 5023 2010/06/14 22:05:46 scons"
-import string
-import UserList
+import collections
from SCons.Debug import logInstanceCreation
import SCons.Errors
import SCons.Memoize
-class Batch:
+class Batch(object):
"""Remembers exact association between targets
and sources of executor."""
def __init__(self, targets=[], sources=[]):
@@ -47,15 +45,15 @@ class Batch:
-class TSList(UserList.UserList):
+class TSList(collections.UserList):
"""A class that implements $TARGETS or $SOURCES expansions by wrapping
an executor Method. This class is used in the Executor.lvars()
to delay creation of NodeList objects until they're needed.
- Note that we subclass UserList.UserList purely so that the
+ Note that we subclass collections.UserList purely so that the
is_Sequence() function will identify an object of this class as
a list during variable expansion. We're not really using any
- UserList.UserList methods in practice.
+ collections.UserList methods in practice.
"""
def __init__(self, func):
self.func = func
@@ -76,7 +74,7 @@ class TSList(UserList.UserList):
nl = self.func()
return repr(nl)
-class TSObject:
+class TSObject(object):
"""A class that implements $TARGET or $SOURCE expansions by wrapping
an Executor method.
"""
@@ -110,7 +108,7 @@ def rfile(node):
return rfile()
-class Executor:
+class Executor(object):
"""A class for controlling instances of executing an action.
This largely exists to hold a single association of an action,
@@ -161,10 +159,10 @@ class Executor:
ut = []
for b in self.batches:
if b.targets[0].is_up_to_date():
- us.extend(map(rfile, b.sources))
+ us.extend(list(map(rfile, b.sources)))
ut.extend(b.targets)
else:
- cs.extend(map(rfile, b.sources))
+ cs.extend(list(map(rfile, b.sources)))
ct.extend(b.targets)
self._changed_sources_list = SCons.Util.NodeList(cs)
self._changed_targets_list = SCons.Util.NodeList(ct)
@@ -190,14 +188,14 @@ class Executor:
return rfile(self.batches[0].sources[0]).get_subst_proxy()
def _get_sources(self, *args, **kw):
- return SCons.Util.NodeList(map(lambda n: rfile(n).get_subst_proxy(), self.get_all_sources()))
+ return SCons.Util.NodeList([rfile(n).get_subst_proxy() for n in self.get_all_sources()])
def _get_target(self, *args, **kw):
#return SCons.Util.NodeList([self.batches[0].targets[0].get_subst_proxy()])
return self.batches[0].targets[0].get_subst_proxy()
def _get_targets(self, *args, **kw):
- return SCons.Util.NodeList(map(lambda n: n.get_subst_proxy(), self.get_all_targets()))
+ return SCons.Util.NodeList([n.get_subst_proxy() for n in self.get_all_targets()])
def _get_unchanged_sources(self, *args, **kw):
try:
@@ -226,7 +224,7 @@ class Executor:
if not SCons.Util.is_List(action):
if not action:
import SCons.Errors
- raise SCons.Errors.UserError, "Executor must have an action."
+ raise SCons.Errors.UserError("Executor must have an action.")
action = [action]
self.action_list = action
@@ -237,16 +235,14 @@ class Executor:
"""Returns all targets for all batches of this Executor."""
result = []
for batch in self.batches:
- # TODO(1.5): remove the list() cast
- result.extend(list(batch.targets))
+ result.extend(batch.targets)
return result
def get_all_sources(self):
"""Returns all sources for all batches of this Executor."""
result = []
for batch in self.batches:
- # TODO(1.5): remove the list() cast
- result.extend(list(batch.sources))
+ result.extend(batch.sources)
return result
def get_all_children(self):
@@ -271,8 +267,7 @@ class Executor:
"""
result = SCons.Util.UniqueList([])
for target in self.get_all_targets():
- # TODO(1.5): remove the list() cast
- result.extend(list(target.prerequisites))
+ result.extend(target.prerequisites)
return result
def get_action_side_effects(self):
@@ -342,7 +337,7 @@ class Executor:
for act in self.get_action_list():
#args = (self.get_all_targets(), self.get_all_sources(), env)
args = ([], [], env)
- status = apply(act, args, kw)
+ status = act(*args, **kw)
if isinstance(status, SCons.Errors.BuildError):
status.executor = self
raise status
@@ -372,7 +367,7 @@ class Executor:
# TODO(batch): extend to multiple batches
assert (len(self.batches) == 1)
# TODO(batch): remove duplicates?
- sources = filter(lambda x, s=self.batches[0].sources: x not in s, sources)
+ sources = [x for x in sources if x not in self.batches[0].sources]
self.batches[0].sources.extend(sources)
def get_sources(self):
@@ -394,7 +389,7 @@ class Executor:
for s in self.get_all_sources():
if s.missing():
msg = "Source `%s' not found, needed by target `%s'."
- raise SCons.Errors.StopError, msg % (s, self.batches[0].targets[0])
+ raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0]))
def add_pre_action(self, action):
self.pre_actions.append(action)
@@ -406,9 +401,10 @@ class Executor:
def my_str(self):
env = self.get_build_env()
- get = lambda action, t=self.get_all_targets(), s=self.get_all_sources(), e=env: \
- action.genstring(t, s, e)
- return string.join(map(get, self.get_action_list()), "\n")
+ return "\n".join([action.genstring(self.get_all_targets(),
+ self.get_all_sources(),
+ env)
+ for action in self.get_action_list()])
def __str__(self):
@@ -417,7 +413,7 @@ class Executor:
def nullify(self):
self.cleanup()
self.do_execute = self.do_nothing
- self.my_str = lambda S=self: ''
+ self.my_str = lambda: ''
memoizer_counters.append(SCons.Memoize.CountValue('get_contents'))
@@ -431,9 +427,10 @@ class Executor:
except KeyError:
pass
env = self.get_build_env()
- get = lambda action, t=self.get_all_targets(), s=self.get_all_sources(), e=env: \
- action.get_contents(t, s, e)
- result = string.join(map(get, self.get_action_list()), "")
+ result = "".join([action.get_contents(self.get_all_targets(),
+ self.get_all_sources(),
+ env)
+ for action in self.get_action_list()])
self._memo['get_contents'] = result
return result
@@ -521,7 +518,7 @@ class Executor:
idict = {}
for i in ignore:
idict[i] = 1
- sourcelist = filter(lambda s, i=idict: not i.has_key(s), sourcelist)
+ sourcelist = [s for s in sourcelist if s not in idict]
memo_dict[key] = sourcelist
@@ -547,7 +544,7 @@ def GetBatchExecutor(key):
return _batch_executors[key]
def AddBatchExecutor(key, executor):
- assert not _batch_executors.has_key(key)
+ assert key not in _batch_executors
_batch_executors[key] = executor
nullenv = None
@@ -569,7 +566,7 @@ def get_NullEnvironment():
nullenv = NullEnvironment()
return nullenv
-class Null:
+class Null(object):
"""A null Executor, with a null build Environment, that does
nothing when the rest of the methods call it.
diff --git a/src/engine/SCons/ExecutorTests.py b/src/engine/SCons/ExecutorTests.py
index d69e31c..be5dab0 100644
--- a/src/engine/SCons/ExecutorTests.py
+++ b/src/engine/SCons/ExecutorTests.py
@@ -21,16 +21,15 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/ExecutorTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/ExecutorTests.py 5023 2010/06/14 22:05:46 scons"
-import string
import sys
import unittest
import SCons.Executor
-class MyEnvironment:
+class MyEnvironment(object):
def __init__(self, **kw):
self._dict = {}
self._dict.update(kw)
@@ -39,30 +38,30 @@ class MyEnvironment:
def Override(self, overrides):
d = self._dict.copy()
d.update(overrides)
- return apply(MyEnvironment, (), d)
+ return MyEnvironment(**d)
def _update(self, dict):
self._dict.update(dict)
-class MyAction:
+class MyAction(object):
def __init__(self, actions=['action1', 'action2']):
self.actions = actions
def __call__(self, target, source, env, **kw):
for action in self.actions:
- apply(action, (target, source, env), kw)
+ action(target, source, env, **kw)
def genstring(self, target, source, env):
- return string.join(['GENSTRING'] + map(str, self.actions) + target + source)
+ return ' '.join(['GENSTRING'] + list(map(str, self.actions)) + target + source)
def get_contents(self, target, source, env):
- return string.join(self.actions + target + source)
+ return ' '.join(self.actions + target + source)
def get_implicit_deps(self, target, source, env):
return []
-class MyBuilder:
+class MyBuilder(object):
def __init__(self, env, overrides):
self.env = env
self.overrides = overrides
self.action = MyAction()
-class MyNode:
+class MyNode(object):
def __init__(self, name=None, pre=[], post=[]):
self.name = name
self.implicit = []
@@ -79,7 +78,7 @@ class MyNode:
[],
[self],
['s1', 's2'])
- apply(executor, (self), {})
+ executor(self)
def get_env_scanner(self, env, kw):
return MyScanner('dep-')
def get_implicit_deps(self, env, scanner, path):
@@ -93,7 +92,7 @@ class MyNode:
def disambiguate(self):
return self
-class MyScanner:
+class MyScanner(object):
def __init__(self, prefix):
self.prefix = prefix
def path(self, env, cwd, target, source):
@@ -120,7 +119,7 @@ class ExecutorTestCase(unittest.TestCase):
except SCons.Errors.UserError:
pass
else:
- raise "Did not catch expected UserError"
+ raise Exception("Did not catch expected UserError")
def test__action_list(self):
"""Test the {get,set}_action_list() methods"""
@@ -182,10 +181,10 @@ class ExecutorTestCase(unittest.TestCase):
[t],
['s1', 's2'])
- class LocalScanner:
+ class LocalScanner(object):
def path(self, env, dir, target, source):
- target = map(str, target)
- source = map(str, source)
+ target = list(map(str, target))
+ source = list(map(str, source))
return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source)
s = LocalScanner()
@@ -243,7 +242,7 @@ class ExecutorTestCase(unittest.TestCase):
except SCons.Errors.BuildError:
pass
else:
- raise Exception, "Did not catch expected BuildError"
+ raise Exception("Did not catch expected BuildError")
assert result == ['pre_err'], result
del result[:]
@@ -311,7 +310,7 @@ class ExecutorTestCase(unittest.TestCase):
except SCons.Errors.StopError, e:
assert str(e) == "Source `s2' not found, needed by target `t1'.", e
else:
- raise AssertionError, "did not catch expected StopError: %s" % r
+ raise AssertionError("did not catch expected StopError: %s" % r)
def test_add_pre_action(self):
"""Test adding pre-actions to an Executor"""
@@ -440,13 +439,13 @@ class ExecutorTestCase(unittest.TestCase):
x = SCons.Executor.Executor('b', env, [{}], [], [s1, s2, s3])
r = x.get_unignored_sources(None, [])
- assert r == [s1, s2, s3], map(str, r)
+ assert r == [s1, s2, s3], list(map(str, r))
r = x.get_unignored_sources(None, [s2])
- assert r == [s1, s3], map(str, r)
+ assert r == [s1, s3], list(map(str, r))
r = x.get_unignored_sources(None, [s1, s3])
- assert r == [s2], map(str, r)
+ assert r == [s2], list(map(str, r))
@@ -455,7 +454,7 @@ if __name__ == "__main__":
tclasses = [ ExecutorTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Job.py b/src/engine/SCons/Job.py
index e3d7f0f..bbf1def 100644
--- a/src/engine/SCons/Job.py
+++ b/src/engine/SCons/Job.py
@@ -29,7 +29,9 @@ stop, and wait on jobs.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Job.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Job.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import os
import signal
@@ -50,7 +52,7 @@ default_stack_size = 256
interrupt_msg = 'Build interrupted.'
-class InterruptState:
+class InterruptState(object):
def __init__(self):
self.interrupted = False
@@ -61,7 +63,7 @@ class InterruptState:
return self.interrupted
-class Jobs:
+class Jobs(object):
"""An instance of this class initializes N jobs, and provides
methods for starting, stopping, and waiting on all N jobs.
"""
@@ -127,7 +129,7 @@ class Jobs:
turns out that it very difficult to stop the build process
by throwing asynchronously an exception such as
KeyboardInterrupt. For example, the python Condition
- variables (threading.Condition) and Queue's do not seem to
+ variables (threading.Condition) and queue's do not seem to
asynchronous-exception-safe. It would require adding a whole
bunch of try/finally block and except KeyboardInterrupt all
over the place.
@@ -161,7 +163,7 @@ class Jobs:
except AttributeError:
pass
-class Serial:
+class Serial(object):
"""This class is used to execute tasks in series, and is more efficient
than Parallel, but is only appropriate for non-parallel builds. Only
one instance of this class should be in existence at a time.
@@ -187,7 +189,7 @@ class Serial:
fails to execute (i.e. execute() raises an exception), then the job will
stop."""
- while 1:
+ while True:
task = self.taskmaster.next_task()
if task is None:
@@ -221,7 +223,7 @@ class Serial:
# Parallel class (and its dependent classes) will work if the interpreter
# doesn't support threads.
try:
- import Queue
+ import queue
import threading
except ImportError:
pass
@@ -240,7 +242,7 @@ else:
self.start()
def run(self):
- while 1:
+ while True:
task = self.requestQueue.get()
if task is None:
@@ -262,7 +264,7 @@ else:
self.resultsQueue.put((task, ok))
- class ThreadPool:
+ class ThreadPool(object):
"""This class is responsible for spawning and managing worker threads."""
def __init__(self, num, stack_size, interrupted):
@@ -271,8 +273,8 @@ else:
One must specify the stack size of the worker threads. The
stack size is specified in kilobytes.
"""
- self.requestQueue = Queue.Queue(0)
- self.resultsQueue = Queue.Queue(0)
+ self.requestQueue = queue.Queue(0)
+ self.resultsQueue = queue.Queue(0)
try:
prev_size = threading.stack_size(stack_size*1024)
@@ -293,9 +295,7 @@ else:
worker = Worker(self.requestQueue, self.resultsQueue, interrupted)
self.workers.append(worker)
- # Once we drop Python 1.5 we can change the following to:
- #if 'prev_size' in locals():
- if 'prev_size' in locals().keys():
+ if 'prev_size' in locals():
threading.stack_size(prev_size)
def put(self, task):
@@ -338,7 +338,7 @@ else:
worker.join(1.0)
self.workers = []
- class Parallel:
+ class Parallel(object):
"""This class is used to execute tasks in parallel, and is somewhat
less efficient than Serial, but is appropriate for parallel builds.
@@ -374,7 +374,7 @@ else:
jobs = 0
- while 1:
+ while True:
# Start up as many available tasks as we're
# allowed to.
while jobs < self.maxjobs:
@@ -402,7 +402,7 @@ else:
# Let any/all completed tasks finish up before we go
# back and put the next batch of tasks on the queue.
- while 1:
+ while True:
task, ok = self.tp.get()
jobs = jobs - 1
diff --git a/src/engine/SCons/JobTests.py b/src/engine/SCons/JobTests.py
index 4ac79ca..8cb12e7 100644
--- a/src/engine/SCons/JobTests.py
+++ b/src/engine/SCons/JobTests.py
@@ -19,9 +19,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.
-#
-__revision__ = "src/engine/SCons/JobTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/JobTests.py 5023 2010/06/14 22:05:46 scons"
import unittest
import random
@@ -39,7 +38,7 @@ num_jobs = 11
# how many tasks to perform for the test
num_tasks = num_jobs*5
-class DummyLock:
+class DummyLock(object):
"fake lock class to use if threads are not supported"
def acquire(self):
pass
@@ -47,13 +46,13 @@ class DummyLock:
def release(self):
pass
-class NoThreadsException:
+class NoThreadsException(object):
"raised by the ParallelTestCase if threads are not supported"
def __str__(self):
return "the interpreter doesn't support threads"
-class Task:
+class Task(object):
"""A dummy task class for testing purposes."""
def __init__(self, i, taskmaster):
@@ -113,7 +112,7 @@ class RandomTask(Task):
x = math.sin(i)
time.sleep(0.01)
-class ExceptionTask:
+class ExceptionTask(object):
"""A dummy task class for testing purposes."""
def __init__(self, i, taskmaster):
@@ -151,7 +150,7 @@ class ExceptionTask:
def exception_set(self):
self.taskmaster.exception_set()
-class Taskmaster:
+class Taskmaster(object):
"""A dummy taskmaster class for testing the job classes."""
def __init__(self, n, test_case, Task):
@@ -368,7 +367,7 @@ import SCons.Taskmaster
import SCons.Node
import time
-class DummyNodeInfo:
+class DummyNodeInfo(object):
def update(self, obj):
pass
@@ -397,7 +396,7 @@ class badnode (goodnode):
goodnode.__init__(self)
self.expect_to_be = SCons.Node.failed
def build(self, **kw):
- raise Exception, 'badnode exception'
+ raise Exception('badnode exception')
class slowbadnode (badnode):
def build(self, **kw):
@@ -406,11 +405,11 @@ class slowbadnode (badnode):
# it is faster than slowgoodnode then these could complete
# while the scheduler is sleeping.
time.sleep(0.05)
- raise Exception, 'slowbadnode exception'
+ raise Exception('slowbadnode exception')
class badpreparenode (badnode):
def prepare(self):
- raise Exception, 'badpreparenode exception'
+ raise Exception('badpreparenode exception')
class _SConsTaskTest(unittest.TestCase):
@@ -491,7 +490,7 @@ class _SConsTaskTest(unittest.TestCase):
self.failUnless(state in [SCons.Node.no_state, N.expect_to_be],
"Node %s got unexpected result: %s" % (N, state))
- self.failUnless(filter(lambda N: N.get_state(), testnodes),
+ self.failUnless([N for N in testnodes if N.get_state()],
"no nodes ran at all.")
@@ -526,8 +525,8 @@ if __name__ == "__main__":
result = runner.run(suite())
if (len(result.failures) == 0
and len(result.errors) == 1
- and type(result.errors[0][0]) == SerialTestCase
- and type(result.errors[0][1][0]) == NoThreadsException):
+ and isinstance(result.errors[0][0], SerialTestCase)
+ and isinstance(result.errors[0][1][0], NoThreadsException)):
sys.exit(2)
elif not result.wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Memoize.py b/src/engine/SCons/Memoize.py
index 5d9f01c..6be415b 100644
--- a/src/engine/SCons/Memoize.py
+++ b/src/engine/SCons/Memoize.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Memoize.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Memoize.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Memoizer
@@ -119,14 +119,14 @@ This collected caching logic nicely, but had two drawbacks:
to figure out how to optimize the underlying methods.
"""
-import new
+import types
# A flag controlling whether or not we actually use memoization.
use_memoizer = None
CounterList = []
-class Counter:
+class Counter(object):
"""
Base class for counting memoization hits and misses.
@@ -165,11 +165,11 @@ class CountValue(Counter):
"""
def __call__(self, *args, **kw):
obj = args[0]
- if obj._memo.has_key(self.method_name):
+ if self.method_name in obj._memo:
self.hit = self.hit + 1
else:
self.miss = self.miss + 1
- return apply(self.underlying_method, args, kw)
+ return self.underlying_method(*args, **kw)
class CountDict(Counter):
"""
@@ -199,91 +199,43 @@ class CountDict(Counter):
except KeyError:
self.miss = self.miss + 1
else:
- key = apply(self.keymaker, args, kw)
- if memo_dict.has_key(key):
+ key = self.keymaker(*args, **kw)
+ if key in memo_dict:
self.hit = self.hit + 1
else:
self.miss = self.miss + 1
- return apply(self.underlying_method, args, kw)
+ return self.underlying_method(*args, **kw)
-class Memoizer:
+class Memoizer(object):
"""Object which performs caching of method calls for its 'primary'
instance."""
def __init__(self):
pass
-# Find out if we support metaclasses (Python 2.2 and later).
+def Dump(title=None):
+ if title:
+ print title
+ CounterList.sort()
+ for counter in CounterList:
+ counter.display()
-class M:
+class Memoized_Metaclass(type):
def __init__(cls, name, bases, cls_dict):
- cls.use_metaclass = 1
- def fake_method(self):
- pass
- new.instancemethod(fake_method, None, cls)
-
-try:
- class A:
- __metaclass__ = M
-
- use_metaclass = A.use_metaclass
-except AttributeError:
- use_metaclass = None
- reason = 'no metaclasses'
-except TypeError:
- use_metaclass = None
- reason = 'new.instancemethod() bug'
-else:
- del A
-
-del M
-
-if not use_metaclass:
-
- def Dump(title):
- pass
+ super(Memoized_Metaclass, cls).__init__(name, bases, cls_dict)
+
+ for counter in cls_dict.get('memoizer_counters', []):
+ method_name = counter.method_name
+
+ counter.name = cls.__name__ + '.' + method_name
+ counter.underlying_method = cls_dict[method_name]
+
+ replacement_method = types.MethodType(counter, None, cls)
+ setattr(cls, method_name, replacement_method)
- try:
- class Memoized_Metaclass(type):
- # Just a place-holder so pre-metaclass Python versions don't
- # have to have special code for the Memoized classes.
- pass
- except TypeError:
- class Memoized_Metaclass:
- # A place-holder so pre-metaclass Python versions don't
- # have to have special code for the Memoized classes.
- pass
-
- def EnableMemoization():
- import SCons.Warnings
- msg = 'memoization is not supported in this version of Python (%s)'
- raise SCons.Warnings.NoMetaclassSupportWarning, msg % reason
-
-else:
-
- def Dump(title=None):
- if title:
- print title
- CounterList.sort()
- for counter in CounterList:
- counter.display()
-
- class Memoized_Metaclass(type):
- def __init__(cls, name, bases, cls_dict):
- super(Memoized_Metaclass, cls).__init__(name, bases, cls_dict)
-
- for counter in cls_dict.get('memoizer_counters', []):
- method_name = counter.method_name
-
- counter.name = cls.__name__ + '.' + method_name
- counter.underlying_method = cls_dict[method_name]
-
- replacement_method = new.instancemethod(counter, None, cls)
- setattr(cls, method_name, replacement_method)
-
- def EnableMemoization():
- global use_memoizer
- use_memoizer = 1
+def EnableMemoization():
+ global use_memoizer
+ use_memoizer = 1
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/MemoizeTests.py b/src/engine/SCons/MemoizeTests.py
index f51ed80..6b71e24 100644
--- a/src/engine/SCons/MemoizeTests.py
+++ b/src/engine/SCons/MemoizeTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/MemoizeTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/MemoizeTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -30,7 +30,7 @@ import SCons.Memoize
-class FakeObject:
+class FakeObject(object):
__metaclass__ = SCons.Memoize.Memoized_Metaclass
@@ -85,7 +85,7 @@ class FakeObject:
return mc
return None
-class Returner:
+class Returner(object):
def __init__(self, result):
self.result = result
self.calls = 0
@@ -132,12 +132,8 @@ class CountDictTestCase(unittest.TestCase):
c = obj.get_memoizer_counter('dict')
- if SCons.Memoize.use_metaclass:
- assert c.hit == 3, c.hit
- assert c.miss == 2, c.miss
- else:
- assert c.hit == 0, c.hit
- assert c.miss == 0, c.miss
+ assert c.hit == 3, c.hit
+ assert c.miss == 2, c.miss
class CountValueTestCase(unittest.TestCase):
@@ -171,12 +167,8 @@ class CountValueTestCase(unittest.TestCase):
c = obj.get_memoizer_counter('value')
- if SCons.Memoize.use_metaclass:
- assert c.hit == 3, c.hit
- assert c.miss == 1, c.miss
- else:
- assert c.hit == 0, c.hit
- assert c.miss == 0, c.miss
+ assert c.hit == 3, c.hit
+ assert c.miss == 1, c.miss
if __name__ == "__main__":
@@ -187,7 +179,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py
index ff4a47e..291ac4d 100644
--- a/src/engine/SCons/Node/Alias.py
+++ b/src/engine/SCons/Node/Alias.py
@@ -30,23 +30,22 @@ This creates a hash of global Aliases (dummy targets).
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Node/Alias.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/Alias.py 5023 2010/06/14 22:05:46 scons"
-import string
-import UserDict
+import collections
import SCons.Errors
import SCons.Node
import SCons.Util
-class AliasNameSpace(UserDict.UserDict):
+class AliasNameSpace(collections.UserDict):
def Alias(self, name, **kw):
if isinstance(name, SCons.Node.Alias.Alias):
return name
try:
a = self[name]
except KeyError:
- a = apply(SCons.Node.Alias.Alias, (name,), kw)
+ a = SCons.Node.Alias.Alias(name, **kw)
self[name] = a
return a
@@ -95,8 +94,8 @@ class Alias(SCons.Node.Node):
def get_contents(self):
"""The contents of an alias is the concatenation
of the content signatures of all its sources."""
- childsigs = map(lambda n: n.get_csig(), self.children())
- return string.join(childsigs, '')
+ childsigs = [n.get_csig() for n in self.children()]
+ return ''.join(childsigs)
def sconsign(self):
"""An Alias is not recorded in .sconsign files"""
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index e7a16b3..56a5564 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Node/AliasTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/AliasTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -51,7 +51,7 @@ class AliasTestCase(unittest.TestCase):
def test_get_contents(self):
"""Test the get_contents() method
"""
- class DummyNode:
+ class DummyNode(object):
def __init__(self, contents):
self.contents = contents
def get_csig(self):
@@ -119,7 +119,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 10641e9..9298d98 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -31,73 +31,17 @@ 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.
-#
-__revision__ = "src/engine/SCons/Node/FS.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/FS.py 5023 2010/06/14 22:05:46 scons"
-from itertools import izip
-import cStringIO
import fnmatch
import os
-import os.path
import re
import shutil
import stat
-import string
import sys
import time
-
-try:
- import codecs
-except ImportError:
- pass
-else:
- # TODO(2.2): Remove when 2.3 becomes the minimal supported version.
- try:
- codecs.BOM_UTF8
- except AttributeError:
- codecs.BOM_UTF8 = '\xef\xbb\xbf'
- try:
- codecs.BOM_UTF16_LE
- codecs.BOM_UTF16_BE
- except AttributeError:
- codecs.BOM_UTF16_LE = '\xff\xfe'
- codecs.BOM_UTF16_BE = '\xfe\xff'
-
- # Provide a wrapper function to handle decoding differences in
- # different versions of Python. Normally, we'd try to do this in the
- # compat layer (and maybe it still makes sense to move there?) but
- # that doesn't provide a way to supply the string class used in
- # pre-2.3 Python versions with a .decode() method that all strings
- # naturally have. Plus, the 2.[01] encodings behave differently
- # enough that we have to settle for a lowest-common-denominator
- # wrapper approach.
- #
- # Note that the 2.[012] implementations below may be inefficient
- # because they perform an explicit look up of the encoding for every
- # decode, but they're old enough (and we want to stop supporting
- # them soon enough) that it's not worth complicating the interface.
- # Think of it as additional incentive for people to upgrade...
- try:
- ''.decode
- except AttributeError:
- # 2.0 through 2.2: strings have no .decode() method
- try:
- codecs.lookup('ascii').decode
- except AttributeError:
- # 2.0 and 2.1: encodings are a tuple of functions, and the
- # decode() function returns a (result, length) tuple.
- def my_decode(contents, encoding):
- return codecs.lookup(encoding)[1](contents)[0]
- else:
- # 2.2: encodings are an object with methods, and the
- # .decode() method returns just the decoded bytes.
- def my_decode(contents, encoding):
- return codecs.lookup(encoding).decode(contents)
- else:
- # 2.3 or later: use the .decode() string method
- def my_decode(contents, encoding):
- return contents.decode(encoding)
+import codecs
import SCons.Action
from SCons.Debug import logInstanceCreation
@@ -256,11 +200,11 @@ def set_duplicate(duplicate):
}
if not duplicate in Valid_Duplicates:
- raise SCons.Errors.InternalError, ("The argument of set_duplicate "
+ raise SCons.Errors.InternalError("The argument of set_duplicate "
"should be in Valid_Duplicates")
global Link_Funcs
Link_Funcs = []
- for func in string.split(duplicate,'-'):
+ for func in duplicate.split('-'):
if link_dict[func]:
Link_Funcs.append(link_dict[func])
@@ -334,7 +278,7 @@ def get_MkdirBuilder():
name = "MkdirBuilder")
return MkdirBuilder
-class _Null:
+class _Null(object):
pass
_null = _Null()
@@ -373,25 +317,23 @@ if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin:
return x
else:
def _my_normcase(x):
- return string.upper(x)
+ return x.upper()
-class DiskChecker:
+class DiskChecker(object):
def __init__(self, type, do, ignore):
self.type = type
self.do = do
self.ignore = ignore
- self.set_do()
- def set_do(self):
- self.__call__ = self.do
- def set_ignore(self):
- self.__call__ = self.ignore
+ self.func = do
+ def __call__(self, *args, **kw):
+ return self.func(*args, **kw)
def set(self, list):
if self.type in list:
- self.set_do()
+ self.func = self.do
else:
- self.set_ignore()
+ self.func = self.ignore
def do_diskcheck_match(node, predicate, errorfmt):
result = predicate()
@@ -407,7 +349,7 @@ def do_diskcheck_match(node, predicate, errorfmt):
except (AttributeError, KeyError):
pass
if result:
- raise TypeError, errorfmt % node.abspath
+ raise TypeError(errorfmt % node.abspath)
def ignore_diskcheck_match(node, predicate, errorfmt):
pass
@@ -459,11 +401,14 @@ def set_diskcheck(list):
dc.set(list)
def diskcheck_types():
- return map(lambda dc: dc.type, diskcheckers)
+ return [dc.type for dc in diskcheckers]
class EntryProxy(SCons.Util.Proxy):
+
+ __str__ = SCons.Util.Delegate('__str__')
+
def __get_abspath(self):
entry = self.get()
return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(),
@@ -497,7 +442,7 @@ class EntryProxy(SCons.Util.Proxy):
return self
else:
entry = self.get()
- r = string.replace(entry.get_path(), os.sep, '/')
+ r = entry.get_path().replace(os.sep, '/')
return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_posix")
def __get_windows_path(self):
@@ -507,7 +452,7 @@ class EntryProxy(SCons.Util.Proxy):
return self
else:
entry = self.get()
- r = string.replace(entry.get_path(), os.sep, '\\')
+ r = entry.get_path().replace(os.sep, '\\')
return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_windows")
def __get_srcnode(self):
@@ -620,8 +565,8 @@ class Base(SCons.Node.Node):
"""
if isinstance(self, klass) or klass is Entry:
return
- raise TypeError, "Tried to lookup %s '%s' as a %s." %\
- (self.__class__.__name__, self.path, klass.__name__)
+ raise TypeError("Tried to lookup %s '%s' as a %s." %\
+ (self.__class__.__name__, self.path, klass.__name__))
def get_dir(self):
return self.dir
@@ -647,7 +592,7 @@ class Base(SCons.Node.Node):
return self._memo['_save_str']
except KeyError:
pass
- result = intern(self._get_str())
+ result = sys.intern(self._get_str())
self._memo['_save_str'] = result
return result
@@ -753,8 +698,8 @@ class Base(SCons.Node.Node):
try: i = path_elems.index(dir)
except ValueError: pass
else: path_elems = path_elems[i+1:]
- path_elems = map(lambda n: n.name, path_elems)
- return string.join(path_elems, os.sep)
+ path_elems = [n.name for n in path_elems]
+ return os.sep.join(path_elems)
def set_src_builder(self, builder):
"""Set the source code builder for this node."""
@@ -911,7 +856,7 @@ class Entry(Base):
self._morph()
elif must_exist:
msg = "No such file or directory: '%s'" % self.abspath
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
else:
self.__class__ = File
self._morph()
@@ -990,7 +935,7 @@ class Entry(Base):
def rel_path(self, other):
d = self.disambiguate()
if d.__class__ is Entry:
- raise "rel_path() could not disambiguate File/Dir"
+ raise Exception("rel_path() could not disambiguate File/Dir")
return d.rel_path(other)
def new_ninfo(self):
@@ -1010,7 +955,7 @@ class Entry(Base):
_classEntry = Entry
-class LocalFS:
+class LocalFS(object):
if SCons.Memoize.use_memoizer:
__metaclass__ = SCons.Memoize.Memoized_Metaclass
@@ -1249,7 +1194,7 @@ class FS(LocalFS):
root = directory.root
if os.sep != '/':
- p = string.replace(p, os.sep, '/')
+ p = p.replace(os.sep, '/')
return root._lookup_abs(p, fsclass, create)
def Entry(self, name, directory = None, create = 1):
@@ -1294,11 +1239,11 @@ class FS(LocalFS):
if not isinstance(variant_dir, SCons.Node.Node):
variant_dir = self.Dir(variant_dir)
if src_dir.is_under(variant_dir):
- raise SCons.Errors.UserError, "Source directory cannot be under variant directory."
+ raise SCons.Errors.UserError("Source directory cannot be under variant directory.")
if variant_dir.srcdir:
if variant_dir.srcdir == src_dir:
return # We already did this.
- raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir)
+ raise SCons.Errors.UserError("'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir))
variant_dir.link(src_dir, duplicate)
def Repository(self, *dirs):
@@ -1327,12 +1272,12 @@ class FS(LocalFS):
if start_dir.is_under(bd):
# If already in the build-dir location, don't reflect
return [orig], fmt % str(orig)
- p = apply(os.path.join, [bd.path] + tail)
+ p = os.path.join(bd.path, *tail)
targets.append(self.Entry(p))
tail = [dir.name] + tail
dir = dir.up()
if targets:
- message = fmt % string.join(map(str, targets))
+ message = fmt % ' '.join(map(str, targets))
return targets, message
def Glob(self, pathname, ondisk=True, source=True, strings=False, cwd=None):
@@ -1574,9 +1519,9 @@ class Dir(Base):
i = self.path_elements.index(other) + 1
path_elems = ['..'] * (len(self.path_elements) - i) \
- + map(lambda n: n.name, other.path_elements[i:])
+ + [n.name for n in other.path_elements[i:]]
- result = string.join(path_elems, os.sep)
+ result = os.sep.join(path_elems)
memo_dict[other] = result
@@ -1622,7 +1567,7 @@ class Dir(Base):
"""A null "builder" for directories."""
global MkdirBuilder
if self.builder is not MkdirBuilder:
- apply(SCons.Node.Node.build, [self,], kw)
+ SCons.Node.Node.build(self, **kw)
#
#
@@ -1641,7 +1586,7 @@ class Dir(Base):
if p is None:
# Don't use while: - else: for this condition because
# if so, then parent is None and has no .path attribute.
- raise SCons.Errors.StopError, parent.path
+ raise SCons.Errors.StopError(parent.path)
parent = p
listDirs.reverse()
for dirnode in listDirs:
@@ -1682,12 +1627,9 @@ class Dir(Base):
"""Return content signatures and names of all our children
separated by new-lines. Ensure that the nodes are sorted."""
contents = []
- name_cmp = lambda a, b: cmp(a.name, b.name)
- sorted_children = self.children()[:]
- sorted_children.sort(name_cmp)
- for node in sorted_children:
+ for node in sorted(self.children(), key=lambda t: t.name):
contents.append('%s %s\n' % (node.get_csig(), node.name))
- return string.join(contents, '')
+ return ''.join(contents)
def get_csig(self):
"""Compute the content signature for Directory nodes. In
@@ -1783,7 +1725,7 @@ class Dir(Base):
d[name] = result
return result
else:
- return d.has_key(name)
+ return name in d
memoizer_counters.append(SCons.Memoize.CountValue('srcdir_list'))
@@ -1911,12 +1853,11 @@ class Dir(Base):
in any way (or ignored, passing None is common).
"""
entries = self.entries
- names = entries.keys()
+ names = list(entries.keys())
names.remove('.')
names.remove('..')
func(arg, self, names)
- select_dirs = lambda n, e=entries: isinstance(e[n], Dir)
- for dirname in filter(select_dirs, names):
+ for dirname in [n for n in names if isinstance(entries[n], Dir)]:
entries[dirname].walk(func, arg)
def glob(self, pathname, ondisk=True, source=False, strings=False):
@@ -1953,9 +1894,8 @@ class Dir(Base):
"""
dirname, basename = os.path.split(pathname)
if not dirname:
- result = self._glob1(basename, ondisk, source, strings)
- result.sort(lambda a, b: cmp(str(a), str(b)))
- return result
+ return sorted(self._glob1(basename, ondisk, source, strings),
+ key=lambda t: str(t))
if has_glob_magic(dirname):
list = self.glob(dirname, ondisk, source, strings=False)
else:
@@ -1964,10 +1904,9 @@ class Dir(Base):
for dir in list:
r = dir._glob1(basename, ondisk, source, strings)
if strings:
- r = map(lambda x, d=str(dir): os.path.join(d, x), r)
+ r = [os.path.join(str(dir), x) for x in r]
result.extend(r)
- result.sort(lambda a, b: cmp(str(a), str(b)))
- return result
+ return sorted(result, key=lambda a: str(a))
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
"""
@@ -1990,9 +1929,8 @@ class Dir(Base):
# We use the .name attribute from the Node because the keys of
# the dir.entries dictionary are normalized (that is, all upper
# case) on case-insensitive systems like Windows.
- #node_names = [ v.name for k, v in dir.entries.items() if k not in ('.', '..') ]
- entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys())
- node_names = map(lambda n, e=dir.entries: e[n].name, entry_names)
+ node_names = [ v.name for k, v in dir.entries.items()
+ if k not in ('.', '..') ]
names.extend(node_names)
if not strings:
# Make sure the working directory (self) actually has
@@ -2015,7 +1953,7 @@ class Dir(Base):
# after we exit this loop.
if pattern[0] != '.':
#disk_names = [ d for d in disk_names if d[0] != '.' ]
- disk_names = filter(lambda x: x[0] != '.', disk_names)
+ disk_names = [x for x in disk_names if x[0] != '.']
disk_names = fnmatch.filter(disk_names, pattern)
dirEntry = dir.Entry
for name in disk_names:
@@ -2031,14 +1969,14 @@ class Dir(Base):
names = set(names)
if pattern[0] != '.':
#names = [ n for n in names if n[0] != '.' ]
- names = filter(lambda x: x[0] != '.', names)
+ names = [x for x in names if x[0] != '.']
names = fnmatch.filter(names, pattern)
if strings:
return names
#return [ self.entries[_my_normcase(n)] for n in names ]
- return map(lambda n, e=self.entries: e[_my_normcase(n)], names)
+ return [self.entries[_my_normcase(n)] for n in names]
class RootDir(Dir):
"""A class for the root directory of a file system.
@@ -2111,7 +2049,7 @@ class RootDir(Dir):
except KeyError:
if not create:
msg = "No such file or directory: '%s' in '%s' (and create is False)" % (p, str(self))
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
# There is no Node for this path name, and we're allowed
# to create it.
dir_name, file_name = os.path.split(p)
@@ -2200,7 +2138,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
except AttributeError:
s = str(n)
else:
- s = string.replace(s, os.sep, '/')
+ s = s.replace(os.sep, '/')
return s
for attr in ['bsources', 'bdepends', 'bimplicit']:
try:
@@ -2208,7 +2146,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
except AttributeError:
pass
else:
- setattr(self, attr, map(node_to_str, val))
+ setattr(self, attr, list(map(node_to_str, val)))
def convert_from_sconsign(self, dir, name):
"""
Converts a newly-read FileBuildInfo object for in-SCons use
@@ -2238,7 +2176,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
except AttributeError:
continue
nodes = []
- for s, ni in izip(strings, nodeinfos):
+ for s, ni in zip(strings, nodeinfos):
if not isinstance(s, SCons.Node.Node):
s = ni.str_to_node(s)
nodes.append(s)
@@ -2247,11 +2185,11 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
result = []
bkids = self.bsources + self.bdepends + self.bimplicit
bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs
- for bkid, bkidsig in izip(bkids, bkidsigs):
+ for bkid, bkidsig in zip(bkids, bkidsigs):
result.append(str(bkid) + ': ' +
- string.join(bkidsig.format(names=names), ' '))
+ ' '.join(bkidsig.format(names=names)))
result.append('%s [%s]' % (self.bactsig, self.bact))
- return string.join(result, '\n')
+ return '\n'.join(result)
class File(Base):
"""A class for files in a file system.
@@ -2286,9 +2224,7 @@ class File(Base):
def Dirs(self, pathlist):
"""Create a list of directories relative to the SConscript
directory of this file."""
- # TODO(1.5)
- # return [self.Dir(p) for p in pathlist]
- return map(lambda p, s=self: s.Dir(p), pathlist)
+ return [self.Dir(p) for p in pathlist]
def File(self, name):
"""Create a file node named 'name' relative to
@@ -2336,38 +2272,24 @@ class File(Base):
raise
return contents
- try:
- import codecs
- except ImportError:
- get_text_contents = get_contents
- else:
- # This attempts to figure out what the encoding of the text is
- # based upon the BOM bytes, and then decodes the contents so that
- # it's a valid python string.
- def get_text_contents(self):
- contents = self.get_contents()
- # The behavior of various decode() methods and functions
- # w.r.t. the initial BOM bytes is different for different
- # encodings and/or Python versions. ('utf-8' does not strip
- # them, but has a 'utf-8-sig' which does; 'utf-16' seems to
- # strip them; etc.) Just side step all the complication by
- # explicitly stripping the BOM before we decode().
- if contents.startswith(codecs.BOM_UTF8):
- contents = contents[len(codecs.BOM_UTF8):]
- # TODO(2.2): Remove when 2.3 becomes floor.
- #contents = contents.decode('utf-8')
- contents = my_decode(contents, 'utf-8')
- elif contents.startswith(codecs.BOM_UTF16_LE):
- contents = contents[len(codecs.BOM_UTF16_LE):]
- # TODO(2.2): Remove when 2.3 becomes floor.
- #contents = contents.decode('utf-16-le')
- contents = my_decode(contents, 'utf-16-le')
- elif contents.startswith(codecs.BOM_UTF16_BE):
- contents = contents[len(codecs.BOM_UTF16_BE):]
- # TODO(2.2): Remove when 2.3 becomes floor.
- #contents = contents.decode('utf-16-be')
- contents = my_decode(contents, 'utf-16-be')
- return contents
+ # This attempts to figure out what the encoding of the text is
+ # based upon the BOM bytes, and then decodes the contents so that
+ # it's a valid python string.
+ def get_text_contents(self):
+ contents = self.get_contents()
+ # The behavior of various decode() methods and functions
+ # w.r.t. the initial BOM bytes is different for different
+ # encodings and/or Python versions. ('utf-8' does not strip
+ # them, but has a 'utf-8-sig' which does; 'utf-16' seems to
+ # strip them; etc.) Just sidestep all the complication by
+ # explicitly stripping the BOM before we decode().
+ if contents.startswith(codecs.BOM_UTF8):
+ return contents[len(codecs.BOM_UTF8):].decode('utf-8')
+ if contents.startswith(codecs.BOM_UTF16_LE):
+ return contents[len(codecs.BOM_UTF16_LE):].decode('utf-16-le')
+ if contents.startswith(codecs.BOM_UTF16_BE):
+ return contents[len(codecs.BOM_UTF16_BE):].decode('utf-16-be')
+ return contents
def get_content_hash(self):
"""
@@ -2603,7 +2525,7 @@ class File(Base):
if scanner:
# result = [n.disambiguate() for n in scanner(self, env, path)]
result = scanner(self, env, path)
- result = map(lambda N: N.disambiguate(), result)
+ result = [N.disambiguate() for N in result]
else:
result = []
@@ -2741,7 +2663,7 @@ class File(Base):
self._createDir()
except SCons.Errors.StopError, drive:
desc = "No drive `%s' for target `%s'." % (drive, self)
- raise SCons.Errors.StopError, desc
+ raise SCons.Errors.StopError(desc)
#
#
@@ -2760,7 +2682,7 @@ class File(Base):
e = Link(self, src, None)
if isinstance(e, SCons.Errors.BuildError):
desc = "Cannot duplicate `%s' in `%s': %s." % (src.path, self.dir.path, e.errstr)
- raise SCons.Errors.StopError, desc
+ raise SCons.Errors.StopError(desc)
self.linked = 1
# The Link() action may or may not have actually
# created the file, depending on whether the -n
@@ -3019,7 +2941,7 @@ class File(Base):
children = self.children()
executor = self.get_executor()
# sigs = [n.get_cachedir_csig() for n in children]
- sigs = map(lambda n: n.get_cachedir_csig(), children)
+ sigs = [n.get_cachedir_csig() for n in children]
sigs.append(SCons.Util.MD5signature(executor.get_contents()))
sigs.append(self.path)
result = self.cachesig = SCons.Util.MD5collect(sigs)
@@ -3034,7 +2956,7 @@ def get_default_fs():
default_fs = FS()
return default_fs
-class FileFinder:
+class FileFinder(object):
"""
"""
if SCons.Memoize.use_memoizer:
@@ -3117,8 +3039,8 @@ class FileFinder:
if verbose and not callable(verbose):
if not SCons.Util.is_String(verbose):
verbose = "find_file"
- verbose = ' %s: ' % verbose
- verbose = lambda s, v=verbose: sys.stdout.write(v + s)
+ _verbose = u' %s: ' % verbose
+ verbose = lambda s: sys.stdout.write(_verbose + s)
filedir, filename = os.path.split(filename)
if filedir:
@@ -3150,10 +3072,10 @@ class FileFinder:
# if isinstance(node, Dir) or isinstance(node, Entry):
# return node
# return None
- #paths = filter(None, map(filedir_lookup, paths))
+ #paths = [_f for _f in map(filedir_lookup, paths) if _f]
self.default_filedir = filedir
- paths = filter(None, map(self.filedir_lookup, paths))
+ paths = [_f for _f in map(self.filedir_lookup, paths) if _f]
result = None
for dir in paths:
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index c059925..ee6a2f5 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -20,12 +20,14 @@
# 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__ = "src/engine/SCons/Node/FSTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/FSTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import os
import os.path
-import string
import sys
import time
import unittest
@@ -40,16 +42,9 @@ import SCons.Warnings
built_it = None
-# This will be built-in in 2.3. For now fake it.
-try :
- True , False
-except NameError :
- True = 1 ; False = 0
-
-
scanner_count = 0
-class Scanner:
+class Scanner(object):
def __init__(self, node=None):
global scanner_count
scanner_count = scanner_count + 1
@@ -66,7 +61,7 @@ class Scanner:
def recurse_nodes(self, nodes):
return nodes
-class Environment:
+class Environment(object):
def __init__(self):
self.scanner = Scanner()
def Dictionary(self, *args):
@@ -80,7 +75,7 @@ class Environment:
def _update(self, dict):
pass
-class Action:
+class Action(object):
def __call__(self, targets, sources, env, **kw):
global built_it
if kw.get('execute', 1):
@@ -97,7 +92,7 @@ class Action:
def get_implicit_deps(self, target, source, env):
return []
-class Builder:
+class Builder(object):
def __init__(self, factory, action=Action()):
self.factory = factory
self.env = Environment()
@@ -341,7 +336,7 @@ class VariantDirTestCase(unittest.TestCase):
f11 = fs.File('src/file11')
t, m = f11.alter_targets()
- bdt = map(lambda n: n.path, t)
+ bdt = [n.path for n in t]
var1_file11 = os.path.normpath('build/var1/file11')
var2_file11 = os.path.normpath('build/var2/file11')
assert bdt == [var1_file11, var2_file11], bdt
@@ -349,11 +344,11 @@ class VariantDirTestCase(unittest.TestCase):
f12 = fs.File('src/file12')
f12.builder = 1
bdt, m = f12.alter_targets()
- assert bdt == [], map(lambda n: n.path, bdt)
+ assert bdt == [], [n.path for n in bdt]
d13 = fs.Dir('src/new_dir')
t, m = d13.alter_targets()
- bdt = map(lambda n: n.path, t)
+ bdt = [n.path for n in t]
var1_new_dir = os.path.normpath('build/var1/new_dir')
var2_new_dir = os.path.normpath('build/var2/new_dir')
assert bdt == [var1_new_dir, var2_new_dir], bdt
@@ -364,7 +359,7 @@ class VariantDirTestCase(unittest.TestCase):
save_Link = SCons.Node.FS.Link
def Link_IOError(target, source, env):
- raise IOError, (17, "Link_IOError")
+ raise IOError(17, "Link_IOError")
SCons.Node.FS.Link = SCons.Action.Action(Link_IOError, None)
test.write(['work', 'src', 'IOError'], "work/src/IOError\n")
@@ -434,7 +429,7 @@ class VariantDirTestCase(unittest.TestCase):
assert r == d1, "%s != %s" % (r, d1)
# verify the link creation attempts in file_link()
- class LinkSimulator :
+ class LinkSimulator (object):
"""A class to intercept os.[sym]link() calls and track them."""
def __init__( self, duplicate, link, symlink, copy ) :
@@ -445,7 +440,7 @@ class VariantDirTestCase(unittest.TestCase):
self.have['copy'] = copy
self.links_to_be_called = []
- for link in string.split(self.duplicate, '-'):
+ for link in self.duplicate.split('-'):
if self.have[link]:
self.links_to_be_called.append(link)
@@ -817,7 +812,7 @@ class FileBuildInfoTestCase(_tempdirTestCase):
'actionsig [action]',
]
- expect = string.join(expect_lines, '\n')
+ expect = '\n'.join(expect_lines)
format = bi1.format()
assert format == expect, (repr(expect), repr(format))
@@ -898,7 +893,7 @@ class FSTestCase(_tempdirTestCase):
except TypeError:
pass
else:
- raise Exception, "did not catch expected TypeError"
+ raise Exception("did not catch expected TypeError")
assert x1.Entry(x4) == x4
try:
@@ -906,7 +901,7 @@ class FSTestCase(_tempdirTestCase):
except TypeError:
pass
else:
- raise Exception, "did not catch expected TypeError"
+ raise Exception("did not catch expected TypeError")
x6 = x1.File(x6)
assert isinstance(x6, SCons.Node.FS.File)
@@ -921,12 +916,12 @@ class FSTestCase(_tempdirTestCase):
drive, path = os.path.splitdrive(os.getcwd())
def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive):
- dir = fileSys.Dir(string.replace(lpath, '/', sep))
+ dir = fileSys.Dir(lpath.replace('/', sep))
if os.sep != '/':
- path_ = string.replace(path_, '/', os.sep)
- abspath_ = string.replace(abspath_, '/', os.sep)
- up_path_ = string.replace(up_path_, '/', os.sep)
+ path_ = path_.replace('/', os.sep)
+ abspath_ = abspath_.replace('/', os.sep)
+ up_path_ = up_path_.replace('/', os.sep)
def strip_slash(p, drive=drive):
if p[-1] == os.sep and len(p) > 1:
@@ -937,7 +932,7 @@ class FSTestCase(_tempdirTestCase):
path = strip_slash(path_)
abspath = strip_slash(abspath_)
up_path = strip_slash(up_path_)
- name = string.split(abspath, os.sep)[-1]
+ name = abspath.split(os.sep)[-1]
assert dir.name == name, \
"dir.name %s != expected name %s" % \
@@ -978,7 +973,7 @@ class FSTestCase(_tempdirTestCase):
Dir_test('#', './', sub_dir, sub)
try:
- f2 = fs.File(string.join(['f1', 'f2'], sep), directory = d1)
+ f2 = fs.File(sep.join(['f1', 'f2']), directory = d1)
except TypeError, x:
assert str(x) == ("Tried to lookup File '%s' as a Dir." %
d1_f1), x
@@ -986,7 +981,7 @@ class FSTestCase(_tempdirTestCase):
raise
try:
- dir = fs.Dir(string.join(['d1', 'f1'], sep))
+ dir = fs.Dir(sep.join(['d1', 'f1']))
except TypeError, x:
assert str(x) == ("Tried to lookup File '%s' as a Dir." %
d1_f1), x
@@ -1051,7 +1046,7 @@ class FSTestCase(_tempdirTestCase):
assert built_it
def match(path, expect):
- expect = string.replace(expect, '/', os.sep)
+ expect = expect.replace('/', os.sep)
assert path == expect, "path %s != expected %s" % (path, expect)
e1 = fs.Entry("d1")
@@ -1152,7 +1147,7 @@ class FSTestCase(_tempdirTestCase):
# Make sure we can scan this file even if the target isn't
# a file that has a scanner (it might be an Alias, e.g.).
- class DummyNode:
+ class DummyNode(object):
pass
deps = f12.get_found_includes(env, s, DummyNode())
@@ -1195,17 +1190,12 @@ class FSTestCase(_tempdirTestCase):
f1 = fs.File(test.workpath("binary_file"))
assert f1.get_contents() == "Foo\x1aBar", f1.get_contents()
- try:
- # TODO(1.5)
- eval('test_string = u"Foo\x1aBar"')
- except SyntaxError:
- pass
- else:
- # This tests to make sure we can decode UTF-8 text files.
- 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"'), \
- f1.get_text_contents()
+ # This tests to make sure we can decode UTF-8 text files.
+ 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"'), \
+ f1.get_text_contents()
def nonexistent(method, s):
try:
@@ -1213,7 +1203,7 @@ class FSTestCase(_tempdirTestCase):
except SCons.Errors.UserError:
pass
else:
- raise Exception, "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
nonexistent(fs.Entry, 'nonexistent')
nonexistent(fs.Entry, 'nonexistent/foo')
@@ -1318,7 +1308,7 @@ class FSTestCase(_tempdirTestCase):
# We round down the current time to the nearest even integer
# value, subtract two to make sure the timestamp is not "now,"
# and then convert it back to a float.
- tstamp = float(int(time.time() / 2) * 2) - 2
+ tstamp = float(int(time.time() // 2) * 2) - 2.0
os.utime(test.workpath("tstamp"), (tstamp - 2.0, tstamp))
f = fs.File("tstamp")
t = f.get_timestamp()
@@ -1336,7 +1326,7 @@ class FSTestCase(_tempdirTestCase):
f2 = test.workpath('tdir2', 'file2')
test.write(f1, 'file1\n')
test.write(f2, 'file2\n')
- current_time = float(int(time.time() / 2) * 2)
+ current_time = float(int(time.time() // 2) * 2)
t1 = current_time - 4.0
t2 = current_time - 2.0
os.utime(f1, (t1 - 2.0, t1))
@@ -1434,7 +1424,7 @@ class FSTestCase(_tempdirTestCase):
test.subdir('sub', ['sub', 'dir'])
def drive_workpath(drive, dirs, test=test):
- x = apply(test.workpath, dirs)
+ x = test.workpath(*dirs)
drive, path = os.path.splitdrive(x)
return 'X:' + path
@@ -1466,11 +1456,11 @@ class FSTestCase(_tempdirTestCase):
seps = seps + ['/']
def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs):
- dir = fileSys.Dir(string.replace(lpath, '/', sep))
+ dir = fileSys.Dir(lpath.replace('/', sep))
if os.sep != '/':
- path_ = string.replace(path_, '/', os.sep)
- up_path_ = string.replace(up_path_, '/', os.sep)
+ path_ = path_.replace('/', os.sep)
+ up_path_ = up_path_.replace('/', os.sep)
def strip_slash(p):
if p[-1] == os.sep and len(p) > 3:
@@ -1478,7 +1468,7 @@ class FSTestCase(_tempdirTestCase):
return p
path = strip_slash(path_)
up_path = strip_slash(up_path_)
- name = string.split(path, os.sep)[-1]
+ name = path.split(os.sep)[-1]
assert dir.name == name, \
"dir.name %s != expected name %s" % \
@@ -1577,8 +1567,8 @@ class FSTestCase(_tempdirTestCase):
d1 = fs.Dir('d1')
d2 = d1.Dir('d2')
- dirs = string.split(os.path.normpath(d2.abspath), os.sep)
- above_path = apply(os.path.join, ['..']*len(dirs) + ['above'])
+ dirs = os.path.normpath(d2.abspath).split(os.sep)
+ above_path = os.path.join(*['..']*len(dirs) + ['above'])
above = d2.Dir(above_path)
def test_rel_path(self):
@@ -1667,16 +1657,11 @@ class FSTestCase(_tempdirTestCase):
def test_proxy(self):
"""Test a Node.FS object wrapped in a proxy instance"""
f1 = self.fs.File('fff')
- class Proxy:
- # Simplest possibly Proxy class that works for our test,
- # this is stripped down from SCons.Util.Proxy.
- def __init__(self, subject):
- self.__subject = subject
- def __getattr__(self, name):
- return getattr(self.__subject, name)
- p = Proxy(f1)
+ class MyProxy(SCons.Util.Proxy):
+ __str__ = SCons.Util.Delegate('__str__')
+ p = MyProxy(f1)
f2 = self.fs.Entry(p)
- assert f1 is f2, (f1, f2)
+ assert f1 is f2, (f1, str(f1), f2, str(f2))
@@ -1730,8 +1715,7 @@ class DirTestCase(_tempdirTestCase):
fs.Dir(os.path.join('ddd', 'd1', 'f4'))
fs.Dir(os.path.join('ddd', 'd1', 'f5'))
dir.scan()
- kids = map(lambda x: x.path, dir.children(None))
- kids.sort()
+ kids = sorted([x.path for x in dir.children(None)])
assert kids == [os.path.join('ddd', 'd1'),
os.path.join('ddd', 'f1'),
os.path.join('ddd', 'f2'),
@@ -1756,8 +1740,7 @@ class DirTestCase(_tempdirTestCase):
e = self.fs.Dir(os.path.join('d', 'empty'))
s = self.fs.Dir(os.path.join('d', 'sub'))
- #TODO(1.5) files = d.get_contents().split('\n')
- files = string.split(d.get_contents(), '\n')
+ files = d.get_contents().split('\n')
assert e.get_contents() == '', e.get_contents()
assert e.get_text_contents() == '', e.get_text_contents()
@@ -1776,14 +1759,12 @@ class DirTestCase(_tempdirTestCase):
fs.File(os.path.join('ddd', 'f1'))
dir.scan()
- kids = map(lambda x: x.path, dir.children())
- kids.sort()
+ kids = sorted([x.path for x in dir.children()])
assert kids == [os.path.join('ddd', 'f1')], kids
fs.File(os.path.join('ddd', 'f2'))
dir.scan()
- kids = map(lambda x: x.path, dir.children())
- kids.sort()
+ kids = sorted([x.path for x in dir.children()])
assert kids == [os.path.join('ddd', 'f1'),
os.path.join('ddd', 'f2')], kids
@@ -1818,8 +1799,8 @@ class DirTestCase(_tempdirTestCase):
self.fs.VariantDir(sub2, src, duplicate=0)
def check(result, expect):
- result = map(str, result)
- expect = map(os.path.normpath, expect)
+ result = list(map(str, result))
+ expect = list(map(os.path.normpath, expect))
assert result == expect, result
s = src.srcdir_list()
@@ -1922,8 +1903,8 @@ class DirTestCase(_tempdirTestCase):
exists_e.exists = return_true
def check(result, expect):
- result = map(str, result)
- expect = map(os.path.normpath, expect)
+ result = list(map(str, result))
+ expect = list(map(os.path.normpath, expect))
assert result == expect, result
# First check from the source directory.
@@ -2095,14 +2076,17 @@ class EntryTestCase(_tempdirTestCase):
assert e4n.__class__ is SCons.Node.FS.File, e4n.__class__
assert not exists, "e4n exists?"
- class MyCalc:
+ class MyCalc(object):
def __init__(self, val):
self.max_drift = 0
- class M:
+ class M(object):
def __init__(self, val):
self.val = val
def collect(self, args):
- return reduce(lambda x, y: x+y, args)
+ result = 0
+ for a in args:
+ result += a
+ return result
def signature(self, executor):
return self.val + 222
self.module = M(val)
@@ -2135,7 +2119,7 @@ class FileTestCase(_tempdirTestCase):
d1 = self.fs.Dir('subdir/d1')
d2 = self.fs.Dir('subdir/d2')
dirs = fff.Dirs(['d1', 'd2'])
- assert dirs == [d1, d2], map(str, dirs)
+ assert dirs == [d1, d2], list(map(str, dirs))
def test_exists(self):
"""Test the File.exists() method"""
@@ -2248,8 +2232,7 @@ class GlobTestCase(_tempdirTestCase):
strings_kwargs = copy.copy(kwargs)
strings_kwargs['strings'] = True
for input, string_expect, node_expect in cases:
- r = apply(self.fs.Glob, (input,), strings_kwargs)
- r.sort()
+ r = sorted(self.fs.Glob(input, **strings_kwargs))
assert r == string_expect, "Glob(%s, strings=True) expected %s, got %s" % (input, string_expect, r)
# Now execute all of the cases without string=True and look for
@@ -2259,26 +2242,25 @@ class GlobTestCase(_tempdirTestCase):
# Verify those by running the list through str() before comparing
# them with the expected list of strings.
for input, string_expect, node_expect in cases:
- r = apply(self.fs.Glob, (input,), kwargs)
+ r = self.fs.Glob(input, **kwargs)
if node_expect:
- r.sort(lambda a,b: cmp(a.path, b.path))
+ r = sorted(r, key=lambda a: a.path)
result = []
for n in node_expect:
- if type(n) == type(''):
+ if isinstance(n, str):
n = self.fs.Entry(n)
result.append(n)
fmt = lambda n: "%s %s" % (repr(n), repr(str(n)))
else:
- r = map(str, r)
- r.sort()
+ r = sorted(map(str, r))
result = string_expect
fmt = lambda n: n
if r != result:
import pprint
print "Glob(%s) expected:" % repr(input)
- pprint.pprint(map(fmt, result))
+ pprint.pprint(list(map(fmt, result)))
print "Glob(%s) got:" % repr(input)
- pprint.pprint(map(fmt, r))
+ pprint.pprint(list(map(fmt, r)))
self.fail()
def test_exact_match(self):
@@ -2538,7 +2520,7 @@ class RepositoryTestCase(_tempdirTestCase):
]
rep = self.fs.Dir('#').getRepositories()
- r = map(lambda x, np=os.path.normpath: np(str(x)), rep)
+ r = [os.path.normpath(str(x)) for x in rep]
assert r == expect, r
def test_get_all_rdirs(self):
@@ -2560,7 +2542,7 @@ class RepositoryTestCase(_tempdirTestCase):
]
rep = self.fs.Dir('#').get_all_rdirs()
- r = map(lambda x, np=os.path.normpath: np(str(x)), rep)
+ r = [os.path.normpath(str(x)) for x in rep]
assert r == expect, r
def test_rentry(self):
@@ -2742,25 +2724,25 @@ class RepositoryTestCase(_tempdirTestCase):
rep3_sub_d1 = fs.Dir(test.workpath('rep3', 'sub', 'd1'))
r = fs.Top.Rfindalldirs((d1,))
- assert r == [d1], map(str, r)
+ assert r == [d1], list(map(str, r))
r = fs.Top.Rfindalldirs((d1, d2))
- assert r == [d1, d2], map(str, r)
+ assert r == [d1, d2], list(map(str, r))
r = fs.Top.Rfindalldirs(('d1',))
- assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+ assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
r = fs.Top.Rfindalldirs(('#d1',))
- assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+ assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
r = sub.Rfindalldirs(('d1',))
- assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], map(str, r)
+ assert r == [sub_d1, rep1_sub_d1, rep2_sub_d1, rep3_sub_d1], list(map(str, r))
r = sub.Rfindalldirs(('#d1',))
- assert r == [d1, rep1_d1, rep2_d1, rep3_d1], map(str, r)
+ assert r == [d1, rep1_d1, rep2_d1, rep3_d1], list(map(str, r))
r = fs.Top.Rfindalldirs(('d1', d2))
- assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], map(str, r)
+ assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], list(map(str, r))
def test_rexists(self):
"""Test the Entry.rexists() method"""
@@ -2800,7 +2782,7 @@ class RepositoryTestCase(_tempdirTestCase):
# We round down the current time to the nearest even integer
# value, subtract two to make sure the timestamp is not "now,"
# and then convert it back to a float.
- tstamp = float(int(time.time() / 2) * 2) - 2
+ tstamp = float(int(time.time() // 2) * 2) - 2.0
os.utime(test.workpath("rep2", "tstamp"), (tstamp - 2.0, tstamp))
f = fs.File("tstamp")
t = f.get_timestamp()
@@ -2831,8 +2813,8 @@ class RepositoryTestCase(_tempdirTestCase):
try:
eval('test_string = u"Con\x1aTents\n"')
except SyntaxError:
- import UserString
- class FakeUnicodeString(UserString.UserString):
+ import collections
+ class FakeUnicodeString(collections.UserString):
def encode(self, encoding):
return str(self)
test_string = FakeUnicodeString("Con\x1aTents\n")
@@ -2892,10 +2874,10 @@ class find_fileTestCase(unittest.TestCase):
nodes.append(SCons.Node.FS.find_file('pseudo', paths))
nodes.append(SCons.Node.FS.find_file('same', paths))
- file_names = map(str, nodes)
- file_names = map(os.path.normpath, file_names)
+ file_names = list(map(str, nodes))
+ file_names = list(map(os.path.normpath, file_names))
expect = ['./foo', './bar/baz', './pseudo', './bar/same']
- expect = map(os.path.normpath, expect)
+ expect = list(map(os.path.normpath, expect))
assert file_names == expect, file_names
# Make sure we don't blow up if there's already a File in place
@@ -2904,11 +2886,11 @@ class find_fileTestCase(unittest.TestCase):
# 'bar/baz' as a Dir.
SCons.Node.FS.find_file('baz/no_file_here', paths)
- import StringIO
+ import io
save_sys_stdout = sys.stdout
try:
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
SCons.Node.FS.find_file('foo2', paths, verbose="xyz")
expect = " xyz: looking for 'foo2' in '.' ...\n" + \
@@ -2916,7 +2898,7 @@ class find_fileTestCase(unittest.TestCase):
c = sio.getvalue()
assert c == expect, c
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
SCons.Node.FS.find_file('baz2', paths, verbose=1)
expect = " find_file: looking for 'baz2' in '.' ...\n" + \
@@ -2925,7 +2907,7 @@ class find_fileTestCase(unittest.TestCase):
c = sio.getvalue()
assert c == expect, c
- sio = StringIO.StringIO()
+ sio = io.StringIO()
sys.stdout = sio
SCons.Node.FS.find_file('on_disk', paths, verbose=1)
expect = " find_file: looking for 'on_disk' in '.' ...\n" + \
@@ -2965,8 +2947,8 @@ class stored_infoTestCase(unittest.TestCase):
bi = f.get_stored_info()
assert hasattr(bi, 'ninfo')
- class MySConsign:
- class Null:
+ class MySConsign(object):
+ class Null(object):
def __init__(self):
self.xyzzy = 7
def get_entry(self, name):
@@ -3433,14 +3415,14 @@ class SaveStringsTestCase(unittest.TestCase):
fs1.VariantDir('d0', 'src', duplicate=0)
fs1.VariantDir('d1', 'src', duplicate=1)
- s = map(str, nodes)
- expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+ s = list(map(str, nodes))
+ expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
assert s == expect, s
modify(nodes)
- s = map(str, nodes)
- expect = map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b'])
+ s = list(map(str, nodes))
+ expect = list(map(os.path.normpath, ['src/f', 'src/f', 'd0/b', 'd1/b']))
assert s == expect, s
SCons.Node.FS.save_strings(1)
@@ -3449,14 +3431,14 @@ class SaveStringsTestCase(unittest.TestCase):
fs2.VariantDir('d0', 'src', duplicate=0)
fs2.VariantDir('d1', 'src', duplicate=1)
- s = map(str, nodes)
- expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+ s = list(map(str, nodes))
+ expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
assert s == expect, s
modify(nodes)
- s = map(str, nodes)
- expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b'])
+ s = list(map(str, nodes))
+ expect = list(map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']))
assert s == expect, 'node str() not cached: %s'%s
@@ -3509,7 +3491,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index c8e5d96..2a09187 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -19,17 +19,16 @@
# 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__ = "src/engine/SCons/Node/NodeTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/NodeTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
+import collections
import os
import re
-import string
import sys
-import types
import unittest
-import UserList
import SCons.Errors
import SCons.Node
@@ -50,13 +49,13 @@ def _actionAppend(a1, a2):
all.append(curr_a)
elif isinstance(curr_a, MyListAction):
all.extend(curr_a.list)
- elif type(curr_a) == type([1,2]):
+ elif isinstance(curr_a, list):
all.extend(curr_a)
else:
- raise 'Cannot Combine Actions'
+ raise Exception('Cannot Combine Actions')
return MyListAction(all)
-class MyActionBase:
+class MyActionBase(object):
def __add__(self, other):
return _actionAppend(self, other)
@@ -83,7 +82,7 @@ class MyAction(MyActionBase):
def get_implicit_deps(self, target, source, env):
return []
-class MyExecutor:
+class MyExecutor(object):
def __init__(self, env=None, targets=[], sources=[]):
self.env = env
self.targets = targets
@@ -114,7 +113,7 @@ class MyListAction(MyActionBase):
for A in self.list:
A(target, source, env)
-class Environment:
+class Environment(object):
def __init__(self, **kw):
self._dict = {}
self._dict.update(kw)
@@ -125,7 +124,7 @@ class Environment:
def Override(self, overrides):
d = self._dict.copy()
d.update(overrides)
- return apply(Environment, (), d)
+ return Environment(**d)
def _update(self, dict):
self._dict.update(dict)
def get_factory(self, factory):
@@ -133,7 +132,7 @@ class Environment:
def get_scanner(self, scanner_key):
return self._dict['SCANNERS'][0]
-class Builder:
+class Builder(object):
def __init__(self, env=None, is_explicit=1):
if env is None: env = Environment()
self.env = env
@@ -167,19 +166,19 @@ class ListBuilder(Builder):
target = self.nodes[0]
self.status = Builder.execute(self, target, source, env)
-class FailBuilder:
+class FailBuilder(object):
def execute(self, target, source, env):
return 1
-class ExceptBuilder:
+class ExceptBuilder(object):
def execute(self, target, source, env):
raise SCons.Errors.BuildError
-class ExceptBuilder2:
+class ExceptBuilder2(object):
def execute(self, target, source, env):
- raise "foo"
+ raise Exception("foo")
-class Scanner:
+class Scanner(object):
called = None
def __call__(self, node):
self.called = 1
@@ -205,16 +204,19 @@ class MyNode(SCons.Node.Node):
def get_found_includes(self, env, scanner, target):
return scanner(self)
-class Calculator:
+class Calculator(object):
def __init__(self, val):
self.max_drift = 0
- class M:
+ class M(object):
def __init__(self, val):
self.val = val
def signature(self, args):
return self.val
def collect(self, args):
- return reduce(lambda x, y: x+y, args, self.val)
+ result = self.val
+ for a in args:
+ result += a
+ return result
self.module = M(val)
@@ -382,7 +384,7 @@ class NodeTestCase(unittest.TestCase):
else:
self.fail("did not catch expected AttributeError")
- class Builder:
+ class Builder(object):
action = 'act'
env = 'env1'
overrides = {}
@@ -616,7 +618,7 @@ class NodeTestCase(unittest.TestCase):
class testNode2(SCons.Node.Node):
def __str__(self): return 'null_binfo'
- class FS:
+ class FS(object):
pass
node = testNode2()
node.fs = FS()
@@ -625,8 +627,8 @@ class NodeTestCase(unittest.TestCase):
assert result is None, result
def get_null_info():
- class Null_SConsignEntry:
- class Null_BuildInfo:
+ class Null_SConsignEntry(object):
+ class Null_BuildInfo(object):
def prepare_dependencies(self):
pass
binfo = Null_BuildInfo()
@@ -786,7 +788,7 @@ class NodeTestCase(unittest.TestCase):
except:
pass
else:
- raise "did not catch expected exception"
+ raise Exception("did not catch expected exception")
assert node.depends == [zero, one, two, three, four]
@@ -818,7 +820,7 @@ class NodeTestCase(unittest.TestCase):
except:
pass
else:
- raise "did not catch expected exception"
+ raise Exception("did not catch expected exception")
assert node.sources == [zero, one, two, three, four], node.sources
def test_add_ignore(self):
@@ -849,7 +851,7 @@ class NodeTestCase(unittest.TestCase):
except:
pass
else:
- raise "did not catch expected exception"
+ raise Exception("did not catch expected exception")
assert node.ignore == [zero, one, two, three, four]
def test_get_found_includes(self):
@@ -889,24 +891,24 @@ class NodeTestCase(unittest.TestCase):
d2.found_includes = [e, f]
f.found_includes = [g]
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f, g], map(str, deps)
+ assert deps == [d1, d2, e, f, g], list(map(str, deps))
# Recursive scanning eliminates duplicates
e.found_includes = [f]
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f, g], map(str, deps)
+ assert deps == [d1, d2, e, f, g], list(map(str, deps))
# Scanner method can select specific nodes to recurse
def no_fff(nodes):
- return filter(lambda n: str(n)[0] != 'f', nodes)
+ return [n for n in nodes if str(n)[0] != 'f']
s.recurse_nodes = no_fff
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2, e, f], map(str, deps)
+ assert deps == [d1, d2, e, f], list(map(str, deps))
# Scanner method can short-circuit recursing entirely
s.recurse_nodes = lambda nodes: []
deps = node.get_implicit_deps(env, s, target)
- assert deps == [d1, d2], map(str, deps)
+ assert deps == [d1, d2], list(map(str, deps))
def test_get_env_scanner(self):
"""Test fetching the environment scanner for a Node
@@ -1102,22 +1104,22 @@ class NodeTestCase(unittest.TestCase):
nw = SCons.Node.Walker(n1)
assert not nw.is_done()
- assert nw.next().name == "n1"
+ assert nw.get_next().name == "n1"
assert nw.is_done()
- assert nw.next() is None
+ assert nw.get_next() is None
n2 = MyNode("n2")
n3 = MyNode("n3")
n1.add_source([n2, n3])
nw = SCons.Node.Walker(n1)
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n2", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n3", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n1", n.name
- n = nw.next()
+ n = nw.get_next()
assert n is None, n
n4 = MyNode("n4")
@@ -1128,17 +1130,17 @@ class NodeTestCase(unittest.TestCase):
n3.add_dependency([n6, n7])
nw = SCons.Node.Walker(n1)
- assert nw.next().name == "n4"
- assert nw.next().name == "n5"
- assert nw.history.has_key(n2)
- assert nw.next().name == "n2"
- assert nw.next().name == "n6"
- assert nw.next().name == "n7"
- assert nw.history.has_key(n3)
- assert nw.next().name == "n3"
- assert nw.history.has_key(n1)
- assert nw.next().name == "n1"
- assert nw.next() is None
+ assert nw.get_next().name == "n4"
+ assert nw.get_next().name == "n5"
+ assert n2 in nw.history
+ assert nw.get_next().name == "n2"
+ assert nw.get_next().name == "n6"
+ assert nw.get_next().name == "n7"
+ assert n3 in nw.history
+ assert nw.get_next().name == "n3"
+ assert n1 in nw.history
+ assert nw.get_next().name == "n1"
+ assert nw.get_next() is None
n8 = MyNode("n8")
n8.add_dependency([n3])
@@ -1151,16 +1153,16 @@ class NodeTestCase(unittest.TestCase):
global cycle_detected
nw = SCons.Node.Walker(n3, cycle_func = cycle)
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n6", n.name
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n8", n.name
assert cycle_detected
cycle_detected = None
- n = nw.next()
+ n = nw.get_next()
assert n.name == "n7", n.name
- n = nw.next()
- assert nw.next() is None
+ n = nw.get_next()
+ assert nw.get_next() is None
def test_abspath(self):
"""Test the get_abspath() method."""
@@ -1275,16 +1277,9 @@ class NodeListTestCase(unittest.TestCase):
nl = SCons.Node.NodeList([n3, n2, n1])
l = [1]
- ul = UserList.UserList([2])
- try:
- l.extend(ul)
- except TypeError:
- # An older version of Python (*cough* 1.5.2 *cough*)
- # that doesn't allow UserList objects to extend lists.
- pass
- else:
- s = str(nl)
- assert s == "['n3', 'n2', 'n1']", s
+ ul = collections.UserList([2])
+ s = str(nl)
+ assert s == "['n3', 'n2', 'n1']", s
r = repr(nl)
r = re.sub('at (0[xX])?[0-9a-fA-F]+', 'at 0x', r)
@@ -1293,7 +1288,7 @@ class NodeListTestCase(unittest.TestCase):
# New-style classes report as "object"; classic classes report
# as "instance"...
r = re.sub("object", "instance", r)
- l = string.join(["<MyNode instance at 0x>"]*3, ", ")
+ l = ", ".join(["<MyNode instance at 0x>"]*3)
assert r == '[%s]' % l, r
@@ -1306,7 +1301,7 @@ if __name__ == "__main__":
NodeListTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py
index 53c2c80..be99d28 100644
--- a/src/engine/SCons/Node/Python.py
+++ b/src/engine/SCons/Node/Python.py
@@ -27,7 +27,7 @@ Python nodes.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Node/Python.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/Python.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node
@@ -67,7 +67,7 @@ class Value(SCons.Node.Node):
def build(self, **kw):
if not hasattr(self, 'built_value'):
- apply (SCons.Node.Node.build, (self,), kw)
+ SCons.Node.Node.build(self, **kw)
is_up_to_date = SCons.Node.Node.children_are_up_to_date
diff --git a/src/engine/SCons/Node/PythonTests.py b/src/engine/SCons/Node/PythonTests.py
index dcf39ec..314b940 100644
--- a/src/engine/SCons/Node/PythonTests.py
+++ b/src/engine/SCons/Node/PythonTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Node/PythonTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/PythonTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -51,7 +51,7 @@ class ValueTestCase(unittest.TestCase):
def test_build(self):
"""Test "building" a Value Node
"""
- class fake_executor:
+ class fake_executor(object):
def __call__(self, node):
node.write('faked')
@@ -119,7 +119,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index b0570b0..8d15b58 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -40,14 +40,12 @@ be able to depend on any other type of "thing."
# 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__ = "src/engine/SCons/Node/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Node/__init__.py 5023 2010/06/14 22:05:46 scons"
+import collections
import copy
-from itertools import chain, izip
-import string
-import UserList
+from itertools import chain
from SCons.Debug import logInstanceCreation
import SCons.Executor
@@ -57,7 +55,7 @@ import SCons.Util
from SCons.Debug import Trace
def classname(obj):
- return string.split(str(obj.__class__), '.')[-1]
+ return str(obj.__class__).split('.')[-1]
# Node states
#
@@ -99,7 +97,7 @@ Annotate = do_nothing
# Classes for signature info for Nodes.
-class NodeInfoBase:
+class NodeInfoBase(object):
"""
The generic base class for signature information for a Node.
@@ -107,7 +105,7 @@ class NodeInfoBase:
logic for dealing with their own Node-specific signature information.
"""
current_version_id = 1
- def __init__(self, node):
+ def __init__(self, node=None):
# Create an object attribute from the class attribute so it ends up
# in the pickled data in the .sconsign file.
self._version_id = self.current_version_id
@@ -136,8 +134,7 @@ class NodeInfoBase:
try:
field_list = self.field_list
except AttributeError:
- field_list = self.__dict__.keys()
- field_list.sort()
+ field_list = sorted(self.__dict__.keys())
fields = []
for field in field_list:
try:
@@ -150,7 +147,7 @@ class NodeInfoBase:
fields.append(f)
return fields
-class BuildInfoBase:
+class BuildInfoBase(object):
"""
The generic base class for build information for a Node.
@@ -161,7 +158,7 @@ class BuildInfoBase:
implicit dependencies, and action information.
"""
current_version_id = 1
- def __init__(self, node):
+ def __init__(self, node=None):
# Create an object attribute from the class attribute so it ends up
# in the pickled data in the .sconsign file.
self._version_id = self.current_version_id
@@ -172,7 +169,7 @@ class BuildInfoBase:
def merge(self, other):
self.__dict__.update(other.__dict__)
-class Node:
+class Node(object):
"""The base Node class, for entities that we know how to
build, or use to build other Nodes.
"""
@@ -182,7 +179,7 @@ class Node:
memoizer_counters = []
- class Attrs:
+ class Attrs(object):
pass
def __init__(self):
@@ -351,12 +348,12 @@ class Node:
for d in self.depends:
if d.missing():
msg = "Explicit dependency `%s' not found, needed by target `%s'."
- raise SCons.Errors.StopError, msg % (d, self)
+ raise SCons.Errors.StopError(msg % (d, self))
if self.implicit is not None:
for i in self.implicit:
if i.missing():
msg = "Implicit dependency `%s' not found, needed by target `%s'."
- raise SCons.Errors.StopError, msg % (i, self)
+ raise SCons.Errors.StopError(msg % (i, self))
self.binfo = self.get_binfo()
def build(self, **kw):
@@ -372,7 +369,7 @@ class Node:
"""
try:
- apply(self.get_executor(), (self,), kw)
+ self.get_executor()(self, **kw)
except SCons.Errors.BuildError, e:
e.node = self
raise
@@ -548,8 +545,7 @@ class Node:
deps = []
while nodes:
n = nodes.pop(0)
- d = filter(lambda x, seen=seen: not seen.has_key(x),
- n.get_found_includes(env, scanner, path))
+ d = [x for x in n.get_found_includes(env, scanner, path) if x not in seen]
if d:
deps.extend(d)
for n in d:
@@ -832,7 +828,7 @@ class Node:
except TypeError, e:
e = e.args[0]
if SCons.Util.is_List(e):
- s = map(str, e)
+ s = list(map(str, e))
else:
s = str(e)
raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -849,7 +845,7 @@ class Node:
except TypeError, e:
e = e.args[0]
if SCons.Util.is_List(e):
- s = map(str, e)
+ s = list(map(str, e))
else:
s = str(e)
raise SCons.Errors.UserError("attempted to ignore a non-Node dependency of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -863,7 +859,7 @@ class Node:
except TypeError, e:
e = e.args[0]
if SCons.Util.is_List(e):
- s = map(str, e)
+ s = list(map(str, e))
else:
s = str(e)
raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
@@ -1053,7 +1049,7 @@ class Node:
if t: Trace(': old %s new %s' % (len(then), len(children)))
result = True
- for child, prev_ni in izip(children, then):
+ for child, prev_ni in zip(children, then):
if child.changed_since_last_build(self, prev_ni):
if t: Trace(': %s changed' % child)
result = True
@@ -1199,8 +1195,8 @@ class Node:
new_bkids = new.bsources + new.bdepends + new.bimplicit
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
- osig = dict(izip(old_bkids, old_bkidsigs))
- nsig = dict(izip(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
@@ -1215,11 +1211,11 @@ class Node:
lines = []
- removed = filter(lambda x, nk=new_bkids: not x in nk, old_bkids)
+ removed = [x for x in old_bkids if not x in new_bkids]
if removed:
- removed = map(stringify, removed)
+ removed = list(map(stringify, removed))
fmt = "`%s' is no longer a dependency\n"
- lines.extend(map(lambda s, fmt=fmt: fmt % s, removed))
+ lines.extend([fmt % s for s in removed])
for k in new_bkids:
if not k in old_bkids:
@@ -1229,14 +1225,14 @@ class Node:
if len(lines) == 0 and old_bkids != new_bkids:
lines.append("the dependency order changed:\n" +
- "%sold: %s\n" % (' '*15, map(stringify, old_bkids)) +
- "%snew: %s\n" % (' '*15, map(stringify, new_bkids)))
+ "%sold: %s\n" % (' '*15, list(map(stringify, old_bkids))) +
+ "%snew: %s\n" % (' '*15, list(map(stringify, new_bkids))))
if len(lines) == 0:
def fmt_with_title(title, strlines):
- lines = string.split(strlines, '\n')
+ lines = strlines.split('\n')
sep = '\n' + ' '*(15 + len(title))
- return ' '*15 + title + string.join(lines, sep) + '\n'
+ return ' '*15 + title + sep.join(lines) + '\n'
if old.bactsig != new.bactsig:
if old.bact == new.bact:
lines.append("the contents of the build action changed\n" +
@@ -1254,31 +1250,22 @@ class Node:
return "%s %s" % (preamble, lines[0])
else:
lines = ["%s:\n" % preamble] + lines
- return string.join(lines, ' '*11)
-
-try:
- [].extend(UserList.UserList([]))
-except TypeError:
- # Python 1.5.2 doesn't allow a list to be extended by list-like
- # objects (such as UserList instances), so just punt and use
- # real lists.
- def NodeList(l):
- return l
-else:
- class NodeList(UserList.UserList):
- def __str__(self):
- return str(map(str, self.data))
+ return ( ' '*11).join(lines)
+
+class NodeList(collections.UserList):
+ def __str__(self):
+ return str(list(map(str, self.data)))
def get_children(node, parent): return node.children()
def ignore_cycle(node, stack): pass
def do_nothing(node, parent): pass
-class Walker:
+class Walker(object):
"""An iterator for walking a Node tree.
This is depth-first, children are visited before the parent.
The Walker object can be initialized with any node, and
- returns the next node on the descent with each next() call.
+ returns the next node on the descent with each get_next() call.
'kids_func' is an optional function that will be called to
get the children of a node instead of calling 'children'.
'cycle_func' is an optional function that will be called
@@ -1298,7 +1285,7 @@ class Walker:
self.history = {} # used to efficiently detect and avoid cycles
self.history[node] = None
- def next(self):
+ def get_next(self):
"""Return the next node for this walk of the tree.
This function is intentionally iterative, not recursive,
@@ -1310,7 +1297,7 @@ class Walker:
node = self.stack[-1].wkids.pop(0)
if not self.stack[-1].wkids:
self.stack[-1].wkids = None
- if self.history.has_key(node):
+ if node in self.history:
self.cycle_func(node, self.stack)
else:
node.wkids = copy.copy(self.kids_func(node, self.stack[-1]))
diff --git a/src/engine/SCons/Options/BoolOption.py b/src/engine/SCons/Options/BoolOption.py
index f0db8c9..f066a49 100644
--- a/src/engine/SCons/Options/BoolOption.py
+++ b/src/engine/SCons/Options/BoolOption.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/BoolOption.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/BoolOption.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -41,7 +41,7 @@ def BoolOption(*args, **kw):
msg = "The BoolOption() function is deprecated; use the BoolVariable() function instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
warned = True
- return apply(SCons.Variables.BoolVariable, args, kw)
+ return SCons.Variables.BoolVariable(*args, **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Options/EnumOption.py b/src/engine/SCons/Options/EnumOption.py
index 985cff9..b541108 100644
--- a/src/engine/SCons/Options/EnumOption.py
+++ b/src/engine/SCons/Options/EnumOption.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/EnumOption.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/EnumOption.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -41,7 +41,7 @@ def EnumOption(*args, **kw):
msg = "The EnumOption() function is deprecated; use the EnumVariable() function instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
warned = True
- return apply(SCons.Variables.EnumVariable, args, kw)
+ return SCons.Variables.EnumVariable(*args, **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Options/ListOption.py b/src/engine/SCons/Options/ListOption.py
index 56c3196..abc98a4 100644
--- a/src/engine/SCons/Options/ListOption.py
+++ b/src/engine/SCons/Options/ListOption.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/ListOption.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/ListOption.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -41,7 +41,7 @@ def ListOption(*args, **kw):
msg = "The ListOption() function is deprecated; use the ListVariable() function instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
warned = True
- return apply(SCons.Variables.ListVariable, args, kw)
+ return SCons.Variables.ListVariable(*args, **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Options/PackageOption.py b/src/engine/SCons/Options/PackageOption.py
index 597865b..db6cac9 100644
--- a/src/engine/SCons/Options/PackageOption.py
+++ b/src/engine/SCons/Options/PackageOption.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/PackageOption.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/PackageOption.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -41,7 +41,7 @@ def PackageOption(*args, **kw):
msg = "The PackageOption() function is deprecated; use the PackageVariable() function instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
warned = True
- return apply(SCons.Variables.PackageVariable, args, kw)
+ return SCons.Variables.PackageVariable(*args, **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Options/PathOption.py b/src/engine/SCons/Options/PathOption.py
index 04d56c2..e31960d 100644
--- a/src/engine/SCons/Options/PathOption.py
+++ b/src/engine/SCons/Options/PathOption.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/PathOption.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/PathOption.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -35,7 +35,7 @@ import SCons.Warnings
warned = False
-class _PathOptionClass:
+class _PathOptionClass(object):
def warn(self):
global warned
if not warned:
@@ -45,27 +45,27 @@ class _PathOptionClass:
def __call__(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable, args, kw)
+ return SCons.Variables.PathVariable(*args, **kw)
def PathAccept(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable.PathAccept, args, kw)
+ return SCons.Variables.PathVariable.PathAccept(*args, **kw)
def PathIsDir(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable.PathIsDir, args, kw)
+ return SCons.Variables.PathVariable.PathIsDir(*args, **kw)
def PathIsDirCreate(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable.PathIsDirCreate, args, kw)
+ return SCons.Variables.PathVariable.PathIsDirCreate(*args, **kw)
def PathIsFile(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable.PathIsFile, args, kw)
+ return SCons.Variables.PathVariable.PathIsFile(*args, **kw)
def PathExists(self, *args, **kw):
self.warn()
- return apply(SCons.Variables.PathVariable.PathExists, args, kw)
+ return SCons.Variables.PathVariable.PathExists(*args, **kw)
PathOption = _PathOptionClass()
diff --git a/src/engine/SCons/Options/__init__.py b/src/engine/SCons/Options/__init__.py
index b4960b1..63de8ed 100644
--- a/src/engine/SCons/Options/__init__.py
+++ b/src/engine/SCons/Options/__init__.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Options/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Options/__init__.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Options module hierarchy
@@ -48,24 +48,17 @@ class Options(SCons.Variables.Variables):
msg = "The Options class is deprecated; use the Variables class instead."
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
warned = True
- apply(SCons.Variables.Variables.__init__,
- (self,) + args,
- kw)
+ SCons.Variables.Variables.__init__(self, *args, **kw)
def AddOptions(self, *args, **kw):
- return apply(SCons.Variables.Variables.AddVariables,
- (self,) + args,
- kw)
+ return SCons.Variables.Variables.AddVariables(self, *args, **kw)
def UnknownOptions(self, *args, **kw):
- return apply(SCons.Variables.Variables.UnknownVariables,
- (self,) + args,
- kw)
+ return SCons.Variables.Variables.UnknownVariables(self, *args, **kw)
def FormatOptionHelpText(self, *args, **kw):
- return apply(SCons.Variables.Variables.FormatVariableHelpText,
- (self,) + args,
- kw)
+ return SCons.Variables.Variables.FormatVariableHelpText(self, *args,
+ **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/PathList.py b/src/engine/SCons/PathList.py
index 307edd8..764b0b8 100644
--- a/src/engine/SCons/PathList.py
+++ b/src/engine/SCons/PathList.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/PathList.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/PathList.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """SCons.PathList
@@ -33,7 +33,6 @@ Do the Right Thing (almost) regardless of how the variable is specified.
"""
import os
-import string
import SCons.Memoize
import SCons.Node
@@ -67,7 +66,7 @@ def node_conv(obj):
result = get()
return result
-class _PathList:
+class _PathList(object):
"""
An actual PathList object.
"""
@@ -98,14 +97,14 @@ class _PathList:
over and over for each target.
"""
if SCons.Util.is_String(pathlist):
- pathlist = string.split(pathlist, os.pathsep)
+ pathlist = pathlist.split(os.pathsep)
elif not SCons.Util.is_Sequence(pathlist):
pathlist = [pathlist]
pl = []
for p in pathlist:
try:
- index = string.find(p, '$')
+ index = p.find('$')
except (AttributeError, TypeError):
type = TYPE_OBJECT
else:
@@ -142,7 +141,7 @@ class _PathList:
return tuple(result)
-class PathListCache:
+class PathListCache(object):
"""
A class to handle caching of PathList lookups.
diff --git a/src/engine/SCons/PathListTests.py b/src/engine/SCons/PathListTests.py
index 87ad0d9..141a4f5 100644
--- a/src/engine/SCons/PathListTests.py
+++ b/src/engine/SCons/PathListTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/PathListTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/PathListTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -33,7 +33,7 @@ class subst_pathTestCase(unittest.TestCase):
def setUp(self):
- class FakeEnvironment:
+ class FakeEnvironment(object):
def __init__(self, **kw):
self.kw = kw
def subst(self, s, target=None, source=None, conv=lambda x: x):
@@ -55,7 +55,7 @@ class subst_pathTestCase(unittest.TestCase):
import SCons.Node
- class A:
+ class A(object):
pass
n = SCons.Node.Node()
@@ -70,7 +70,7 @@ class subst_pathTestCase(unittest.TestCase):
"""Test the subst_path() method on a non-Node object
"""
- class A:
+ class A(object):
def __str__(self):
return '<object A>'
@@ -86,7 +86,7 @@ class subst_pathTestCase(unittest.TestCase):
"""Test the subst_path() method on an object with a get() method
"""
- class B:
+ class B(object):
def get(self):
return 'b'
@@ -159,7 +159,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py
index f5b0458..48fe3ca 100644
--- a/src/engine/SCons/Platform/PlatformTests.py
+++ b/src/engine/SCons/Platform/PlatformTests.py
@@ -21,16 +21,18 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/PlatformTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/PlatformTests.py 5023 2010/06/14 22:05:46 scons"
+import SCons.compat
+
+import collections
import sys
import unittest
import SCons.Errors
import SCons.Platform
-import UserDict
-class Environment(UserDict.UserDict):
+class Environment(collections.UserDict):
def Detect(self, cmd):
return cmd
def AppendENVPath(self, key, value):
diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py
index 33cad25..7e6288d 100644
--- a/src/engine/SCons/Platform/__init__.py
+++ b/src/engine/SCons/Platform/__init__.py
@@ -42,13 +42,12 @@ their own platform definition.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/__init__.py 5023 2010/06/14 22:05:46 scons"
import SCons.compat
import imp
import os
-import string
import sys
import tempfile
@@ -69,15 +68,15 @@ def platform_default():
if osname == 'posix':
if sys.platform == 'cygwin':
return 'cygwin'
- elif string.find(sys.platform, 'irix') != -1:
+ elif sys.platform.find('irix') != -1:
return 'irix'
- elif string.find(sys.platform, 'sunos') != -1:
+ elif sys.platform.find('sunos') != -1:
return 'sunos'
- elif string.find(sys.platform, 'hp-ux') != -1:
+ elif sys.platform.find('hp-ux') != -1:
return 'hpux'
- elif string.find(sys.platform, 'aix') != -1:
+ elif sys.platform.find('aix') != -1:
return 'aix'
- elif string.find(sys.platform, 'darwin') != -1:
+ elif sys.platform.find('darwin') != -1:
return 'darwin'
else:
return 'posix'
@@ -94,7 +93,7 @@ def platform_module(name = platform_default()):
our execution environment.
"""
full_name = 'SCons.Platform.' + name
- if not sys.modules.has_key(full_name):
+ if full_name not in sys.modules:
if os.name == 'java':
eval(full_name)
else:
@@ -112,7 +111,7 @@ def platform_module(name = platform_default()):
importer = zipimport.zipimporter( sys.modules['SCons.Platform'].__path__[0] )
mod = importer.load_module(full_name)
except ImportError:
- raise SCons.Errors.UserError, "No platform named '%s'" % name
+ raise SCons.Errors.UserError("No platform named '%s'" % name)
setattr(SCons.Platform, name, mod)
return sys.modules[full_name]
@@ -121,14 +120,18 @@ def DefaultToolList(platform, env):
"""
return SCons.Tool.tool_list(platform, env)
-class PlatformSpec:
- def __init__(self, name):
+class PlatformSpec(object):
+ def __init__(self, name, generate):
self.name = name
+ self.generate = generate
+
+ def __call__(self, *args, **kw):
+ return self.generate(*args, **kw)
def __str__(self):
return self.name
-class TempFileMunge:
+class TempFileMunge(object):
"""A callable class. You can set an Environment variable to this,
then call it with a string argument, then it will perform temporary
file substitution on it. This is used to circumvent the long command
@@ -167,7 +170,10 @@ class TempFileMunge:
except ValueError:
maxline = 2048
- if (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= maxline:
+ length = 0
+ for c in cmd:
+ length += len(c)
+ if length <= maxline:
return self.cmd
# We do a normpath because mktemp() has what appears to be
@@ -184,7 +190,7 @@ class TempFileMunge:
if env['SHELL'] and env['SHELL'] == 'sh':
# The sh shell will try to escape the backslashes in the
# path, so unescape them.
- native_tmp = string.replace(native_tmp, '\\', r'\\\\')
+ native_tmp = native_tmp.replace('\\', r'\\\\')
# In Cygwin, we want to use rm to delete the temporary
# file, because del does not exist in the sh shell.
rm = env.Detect('rm') or 'del'
@@ -198,8 +204,8 @@ class TempFileMunge:
if not prefix:
prefix = '@'
- args = map(SCons.Subst.quote_spaces, cmd[1:])
- os.write(fd, string.join(args, " ") + "\n")
+ args = list(map(SCons.Subst.quote_spaces, cmd[1:]))
+ os.write(fd, " ".join(args) + "\n")
os.close(fd)
# XXX Using the SCons.Action.print_actions value directly
# like this is bogus, but expedient. This class should
@@ -218,15 +224,14 @@ class TempFileMunge:
# reach into SCons.Action directly.
if SCons.Action.print_actions:
print("Using tempfile "+native_tmp+" for command line:\n"+
- str(cmd[0]) + " " + string.join(args," "))
+ str(cmd[0]) + " " + " ".join(args))
return [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
def Platform(name = platform_default()):
"""Select a canned Platform specification.
"""
module = platform_module(name)
- spec = PlatformSpec(name)
- spec.__call__ = module.generate
+ spec = PlatformSpec(name, module.generate)
return spec
# Local Variables:
diff --git a/src/engine/SCons/Platform/aix.py b/src/engine/SCons/Platform/aix.py
index 039d3d4..e729bcb 100644
--- a/src/engine/SCons/Platform/aix.py
+++ b/src/engine/SCons/Platform/aix.py
@@ -30,10 +30,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/aix.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/aix.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import posix
@@ -51,9 +50,9 @@ def get_xlc(env, xlc=None, xlc_r=None, packages=[]):
cmd = "lslpp -fc " + package + " 2>/dev/null | egrep '" + xlc + "([^-_a-zA-Z0-9].*)?$'"
line = os.popen(cmd).readline()
if line:
- v, p = string.split(line, ':')[1:3]
- xlcVersion = string.split(v)[1]
- xlcPath = string.split(p)[0]
+ v, p = line.split(':')[1:3]
+ xlcVersion = v.split()[1]
+ xlcPath = p.split()[0]
xlcPath = xlcPath[:xlcPath.rindex('/')]
break
return (xlcPath, xlc, xlc_r, xlcVersion)
diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py
index 0105ae9..854a2c5 100644
--- a/src/engine/SCons/Platform/cygwin.py
+++ b/src/engine/SCons/Platform/cygwin.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/cygwin.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/cygwin.py 5023 2010/06/14 22:05:46 scons"
import posix
from SCons.Platform import TempFileMunge
diff --git a/src/engine/SCons/Platform/darwin.py b/src/engine/SCons/Platform/darwin.py
index 18c58f2..4d62517 100644
--- a/src/engine/SCons/Platform/darwin.py
+++ b/src/engine/SCons/Platform/darwin.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/darwin.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/darwin.py 5023 2010/06/14 22:05:46 scons"
import posix
diff --git a/src/engine/SCons/Platform/hpux.py b/src/engine/SCons/Platform/hpux.py
index d5ce3bb..4544dfb 100644
--- a/src/engine/SCons/Platform/hpux.py
+++ b/src/engine/SCons/Platform/hpux.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/hpux.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/hpux.py 5023 2010/06/14 22:05:46 scons"
import posix
diff --git a/src/engine/SCons/Platform/irix.py b/src/engine/SCons/Platform/irix.py
index 95df7eb..3daebf5 100644
--- a/src/engine/SCons/Platform/irix.py
+++ b/src/engine/SCons/Platform/irix.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/irix.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/irix.py 5023 2010/06/14 22:05:46 scons"
import posix
diff --git a/src/engine/SCons/Platform/os2.py b/src/engine/SCons/Platform/os2.py
index 973ac6b..e74a22c 100644
--- a/src/engine/SCons/Platform/os2.py
+++ b/src/engine/SCons/Platform/os2.py
@@ -30,11 +30,11 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/os2.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/os2.py 5023 2010/06/14 22:05:46 scons"
import win32
def generate(env):
- if not env.has_key('ENV'):
+ if 'ENV' not in env:
env['ENV'] = {}
env['OBJPREFIX'] = ''
env['OBJSUFFIX'] = '.obj'
diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py
index 67aef3e..1f19277 100644
--- a/src/engine/SCons/Platform/posix.py
+++ b/src/engine/SCons/Platform/posix.py
@@ -30,12 +30,11 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/posix.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/posix.py 5023 2010/06/14 22:05:46 scons"
import errno
import os
import os.path
-import string
import subprocess
import sys
import select
@@ -53,14 +52,14 @@ def escape(arg):
slash = '\\'
special = '"$()'
- arg = string.replace(arg, slash, slash+slash)
+ arg = arg.replace(slash, slash+slash)
for c in special:
- arg = string.replace(arg, c, slash+c)
+ arg = arg.replace(c, slash+c)
return '"' + arg + '"'
def exec_system(l, env):
- stat = os.system(string.join(l))
+ stat = os.system(' '.join(l))
if stat & 0xff:
return stat | 0x80
return stat >> 8
@@ -90,22 +89,22 @@ def exec_fork(l, env):
return stat >> 8
def _get_env_command(sh, escape, cmd, args, env):
- s = string.join(args)
+ s = ' '.join(args)
if env:
l = ['env', '-'] + \
- map(lambda t, e=escape: e(t[0])+'='+e(t[1]), env.items()) + \
+ [escape(t[0])+'='+escape(t[1]) for t in env.items()] + \
[sh, '-c', escape(s)]
- s = string.join(l)
+ s = ' '.join(l)
return s
def env_spawn(sh, escape, cmd, args, env):
return exec_system([_get_env_command( sh, escape, cmd, args, env)], env)
def spawnvpe_spawn(sh, escape, cmd, args, env):
- return exec_spawnvpe([sh, '-c', string.join(args)], env)
+ return exec_spawnvpe([sh, '-c', ' '.join(args)], env)
def fork_spawn(sh, escape, cmd, args, env):
- return exec_fork([sh, '-c', string.join(args)], env)
+ return exec_fork([sh, '-c', ' '.join(args)], env)
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
stdout_eof = stderr_eof = 0
@@ -131,7 +130,7 @@ def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
raise
def exec_popen3(l, env, stdout, stderr):
- proc = subprocess.Popen(string.join(l),
+ proc = subprocess.Popen(' '.join(l),
stdout=stdout,
stderr=stderr,
shell=True)
@@ -198,7 +197,7 @@ def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr):
def piped_fork_spawn(sh, escape, cmd, args, env, stdout, stderr):
# spawn using fork / exec and providing a pipe for the command's
# stdout / stderr stream
- return exec_piped_fork([sh, '-c', string.join(args)],
+ return exec_piped_fork([sh, '-c', ' '.join(args)],
env, stdout, stderr)
@@ -217,7 +216,7 @@ def generate(env):
# os.fork()/os.exec() works better than os.system(). There may just
# not be a default that works best for all users.
- if os.__dict__.has_key('spawnvpe'):
+ if 'spawnvpe' in os.__dict__:
spawn = spawnvpe_spawn
elif env.Detect('env'):
spawn = env_spawn
@@ -229,7 +228,7 @@ def generate(env):
else:
pspawn = piped_fork_spawn
- if not env.has_key('ENV'):
+ if 'ENV' not in env:
env['ENV'] = {}
env['ENV']['PATH'] = '/usr/local/bin:/opt/bin:/bin:/usr/bin'
env['OBJPREFIX'] = ''
diff --git a/src/engine/SCons/Platform/sunos.py b/src/engine/SCons/Platform/sunos.py
index 0a816db..f855aa8 100644
--- a/src/engine/SCons/Platform/sunos.py
+++ b/src/engine/SCons/Platform/sunos.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/sunos.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/sunos.py 5023 2010/06/14 22:05:46 scons"
import posix
diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py
index 1443099..57d9bdc 100644
--- a/src/engine/SCons/Platform/win32.py
+++ b/src/engine/SCons/Platform/win32.py
@@ -30,11 +30,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Platform/win32.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Platform/win32.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
-import string
import sys
import tempfile
@@ -61,27 +60,27 @@ except AttributeError:
else:
parallel_msg = None
- import __builtin__
+ import builtins
- _builtin_file = __builtin__.file
- _builtin_open = __builtin__.open
+ _builtin_file = builtins.file
+ _builtin_open = builtins.open
def _scons_file(*args, **kw):
- fp = apply(_builtin_file, args, kw)
+ fp = _builtin_file(*args, **kw)
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
win32con.HANDLE_FLAG_INHERIT,
0)
return fp
def _scons_open(*args, **kw):
- fp = apply(_builtin_open, args, kw)
+ fp = _builtin_open(*args, **kw)
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
win32con.HANDLE_FLAG_INHERIT,
0)
return fp
- __builtin__.file = _scons_file
- __builtin__.open = _scons_open
+ builtins.file = _scons_file
+ builtins.open = _scons_open
@@ -109,11 +108,11 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
stderrRedirected = 0
for arg in args:
# are there more possibilities to redirect stdout ?
- if (string.find( arg, ">", 0, 1 ) != -1 or
- string.find( arg, "1>", 0, 2 ) != -1):
+ if (arg.find( ">", 0, 1 ) != -1 or
+ arg.find( "1>", 0, 2 ) != -1):
stdoutRedirected = 1
# are there more possibilities to redirect stderr ?
- if string.find( arg, "2>", 0, 2 ) != -1:
+ if arg.find( "2>", 0, 2 ) != -1:
stderrRedirected = 1
# redirect output of non-redirected streams to our tempfiles
@@ -124,7 +123,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
# actually do the spawn
try:
- args = [sh, '/C', escape(string.join(args)) ]
+ args = [sh, '/C', escape(' '.join(args)) ]
ret = os.spawnve(os.P_WAIT, sh, args, env)
except OSError, e:
# catch any error
@@ -162,7 +161,7 @@ def exec_spawn(l, env):
result = 127
if len(l) > 2:
if len(l[2]) < 1000:
- command = string.join(l[0:3])
+ command = ' '.join(l[0:3])
else:
command = l[0]
else:
@@ -174,7 +173,7 @@ def spawn(sh, escape, cmd, args, env):
if not sh:
sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
return 127
- return exec_spawn([sh, '/C', escape(string.join(args))], env)
+ return exec_spawn([sh, '/C', escape(' '.join(args))], env)
# Windows does not allow special characters in file names anyway, so no
# need for a complex escape function, we will just quote the arg, except
@@ -240,7 +239,7 @@ def get_program_files_dir():
# Determine which windows CPU were running on.
-class ArchDefinition:
+class ArchDefinition(object):
"""
A class for defining architecture-specific settings and logic.
"""
@@ -318,7 +317,7 @@ def generate(env):
tmp_path = systemroot + os.pathsep + \
os.path.join(systemroot,'System32')
tmp_pathext = '.com;.exe;.bat;.cmd'
- if os.environ.has_key('PATHEXT'):
+ if 'PATHEXT' in os.environ:
tmp_pathext = os.environ['PATHEXT']
cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
if not cmd_interp:
@@ -330,7 +329,7 @@ def generate(env):
cmd_interp = env.Detect('command')
- if not env.has_key('ENV'):
+ if 'ENV' not in env:
env['ENV'] = {}
# Import things from the external environment to the construction
@@ -347,7 +346,7 @@ def generate(env):
if v:
env['ENV'][var] = v
- if not env['ENV'].has_key('COMSPEC'):
+ if 'COMSPEC' not in env['ENV']:
v = os.environ.get("COMSPEC")
if v:
env['ENV']['COMSPEC'] = v
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 57ec0ca..bce935e 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -26,15 +26,15 @@ Autoconf-like configuration support.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/SConf.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/SConf.py 5023 2010/06/14 22:05:46 scons"
+import SCons.compat
+
+import io
import os
import re
-import string
-import StringIO
import sys
import traceback
-import types
import SCons.Action
import SCons.Builder
@@ -79,7 +79,7 @@ def SetCacheMode(mode):
elif mode == "cache":
cache_mode = CACHE
else:
- raise ValueError, "SCons.SConf.SetCacheMode: Unknown mode " + mode
+ raise ValueError("SCons.SConf.SetCacheMode: Unknown mode " + mode)
progress_display = SCons.Util.display # will be overwritten by SCons.Script
def SetProgressDisplay(display):
@@ -96,7 +96,7 @@ sconf_global = None # current sconf object
def _createConfigH(target, source, env):
t = open(str(target[0]), "w")
- defname = re.sub('[^A-Za-z0-9_]', '_', string.upper(str(target[0])))
+ defname = re.sub('[^A-Za-z0-9_]', '_', str(target[0]).upper())
t.write("""#ifndef %(DEFNAME)s_SEEN
#define %(DEFNAME)s_SEEN
@@ -153,12 +153,7 @@ def _createSource( target, source, env ):
fd.close()
def _stringSource( target, source, env ):
return (str(target[0]) + ' <-\n |' +
- string.replace( source[0].get_contents(),
- '\n', "\n |" ) )
-
-# python 2.2 introduces types.BooleanType
-BooleanTypes = [types.IntType]
-if hasattr(types, 'BooleanType'): BooleanTypes.append(types.BooleanType)
+ source[0].get_contents().replace( '\n', "\n |" ) )
class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
"""
@@ -174,13 +169,13 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
self.string = string
-class Streamer:
+class Streamer(object):
"""
'Sniffer' for a file-like writable object. Similar to the unix tool tee.
"""
def __init__(self, orig):
self.orig = orig
- self.s = StringIO.StringIO()
+ self.s = io.StringIO()
def write(self, str):
if self.orig:
@@ -222,8 +217,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
"The stored build information has an unexpected class: %s" % bi.__class__)
else:
self.display("The original builder output was:\n" +
- string.replace(" |" + str(bi.string),
- "\n", "\n |"))
+ (" |" + str(bi.string)).replace("\n", "\n |"))
def failed(self):
# check, if the reason was a ConfigureDryRunError or a
@@ -246,7 +240,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
def excepthook(type, value, tb):
traceback.print_tb(tb)
print type, value
- apply(excepthook, self.exc_info())
+ excepthook(*self.exc_info())
return SCons.Taskmaster.Task.failed(self)
def collect_node_states(self):
@@ -374,7 +368,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
sconsign.set_entry(t.name, sconsign_entry)
sconsign.merge()
-class SConfBase:
+class SConfBase(object):
"""This is simply a class to represent a configure context. After
creating a SConf object, you can call any tests. After finished with your
tests, be sure to call the Finish() method, which returns the modified
@@ -400,8 +394,7 @@ class SConfBase:
SConfFS = SCons.Node.FS.default_fs or \
SCons.Node.FS.FS(env.fs.pathTop)
if sconf_global is not None:
- raise (SCons.Errors.UserError,
- "Only one SConf object may be active at one time")
+ raise SCons.Errors.UserError
self.env = env
if log_file is not None:
log_file = SConfFS.File(env.subst(log_file))
@@ -465,7 +458,7 @@ class SConfBase:
lines.append(define_str)
lines.append('')
- self.config_h_text = self.config_h_text + string.join(lines, '\n')
+ self.config_h_text = self.config_h_text + '\n'.join(lines)
def BuildNodes(self, nodes):
"""
@@ -635,17 +628,16 @@ class SConfBase:
return( 1, outputStr)
return (0, "")
- class TestWrapper:
+ class TestWrapper(object):
"""A wrapper around Tests (to ensure sanity)"""
def __init__(self, test, sconf):
self.test = test
self.sconf = sconf
def __call__(self, *args, **kw):
if not self.sconf.active:
- raise (SCons.Errors.UserError,
- "Test called after sconf.Finish()")
+ raise SCons.Errors.UserError
context = CheckContext(self.sconf)
- ret = apply(self.test, (context,) + args, kw)
+ ret = self.test(context, *args, **kw)
if self.sconf.config_h is not None:
self.sconf.config_h_text = self.sconf.config_h_text + context.config_h
context.Result("error: no result")
@@ -689,7 +681,7 @@ class SConfBase:
if self.logfile is not None and not dryrun:
# truncate logfile, if SConf.Configure is called for the first time
# in a build
- if _ac_config_logs.has_key(self.logfile):
+ if self.logfile in _ac_config_logs:
log_mode = "a"
else:
_ac_config_logs[self.logfile] = None
@@ -724,7 +716,7 @@ class SConfBase:
global sconf_global, _ac_config_hs
if not self.active:
- raise SCons.Errors.UserError, "Finish may be called only once!"
+ raise SCons.Errors.UserError("Finish may be called only once!")
if self.logstream is not None and not dryrun:
self.logstream.write("\n")
self.logstream.close()
@@ -739,7 +731,7 @@ class SConfBase:
_ac_config_hs[self.config_h] = self.config_h_text
self.env.fs = self.lastEnvFs
-class CheckContext:
+class CheckContext(object):
"""Provides a context for configure tests. Defines how a test writes to the
screen and log file.
@@ -788,15 +780,15 @@ class CheckContext:
string. In case of an integer, the written text will be 'yes' or 'no'.
The result is only displayed when self.did_show_result is not set.
"""
- if type(res) in BooleanTypes:
+ if isinstance(res, (int, bool)):
if res:
text = "yes"
else:
text = "no"
- elif type(res) == types.StringType:
+ elif isinstance(res, str):
text = res
else:
- raise TypeError, "Expected string, int or bool, got " + str(type(res))
+ raise TypeError("Expected string, int or bool, got " + str(type(res)))
if self.did_show_result == 0:
# Didn't show result yet, do it now.
@@ -804,19 +796,19 @@ class CheckContext:
self.did_show_result = 1
def TryBuild(self, *args, **kw):
- return apply(self.sconf.TryBuild, args, kw)
+ return self.sconf.TryBuild(*args, **kw)
def TryAction(self, *args, **kw):
- return apply(self.sconf.TryAction, args, kw)
+ return self.sconf.TryAction(*args, **kw)
def TryCompile(self, *args, **kw):
- return apply(self.sconf.TryCompile, args, kw)
+ return self.sconf.TryCompile(*args, **kw)
def TryLink(self, *args, **kw):
- return apply(self.sconf.TryLink, args, kw)
+ return self.sconf.TryLink(*args, **kw)
def TryRun(self, *args, **kw):
- return apply(self.sconf.TryRun, args, kw)
+ return self.sconf.TryRun(*args, **kw)
def __getattr__( self, attr ):
if( attr == 'env' ):
@@ -824,7 +816,7 @@ class CheckContext:
elif( attr == 'lastTarget' ):
return self.sconf.lastTarget
else:
- raise AttributeError, "CheckContext instance has no attribute '%s'" % attr
+ raise AttributeError("CheckContext instance has no attribute '%s'" % attr)
#### Stuff used by Conftest.py (look there for explanations).
@@ -889,7 +881,7 @@ def SConf(*args, **kw):
del kw[bt]
except KeyError:
pass
- return apply(SConfBase, args, kw)
+ return SConfBase(*args, **kw)
else:
return SCons.Util.Null()
@@ -901,7 +893,7 @@ def CheckFunc(context, function_name, header = None, language = None):
def CheckType(context, type_name, includes = "", language = None):
res = SCons.Conftest.CheckType(context, type_name,
- header = includes, language = language)
+ header = includes, language = language)
context.did_show_result = 1
return not res
@@ -933,7 +925,7 @@ def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
for s in headers:
l.append("#include %s%s%s\n"
% (include_quotes[0], s, include_quotes[1]))
- return string.join(l, ''), lastHeader
+ return ''.join(l), lastHeader
def CheckHeader(context, header, include_quotes = '<>', language = None):
"""
diff --git a/src/engine/SCons/SConfTests.py b/src/engine/SCons/SConfTests.py
index 9ba82f2..91c57d2 100644
--- a/src/engine/SCons/SConfTests.py
+++ b/src/engine/SCons/SConfTests.py
@@ -21,19 +21,20 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/SConfTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/SConfTests.py 5023 2010/06/14 22:05:46 scons"
+import SCons.compat
+
+import io
import os
import re
-import string
-import StringIO
import sys
from types import *
import unittest
import TestCmd
-sys.stdout = StringIO.StringIO()
+sys.stdout = io.StringIO()
if sys.platform == 'win32':
existing_lib = "msvcrt"
@@ -60,9 +61,9 @@ class SConfTestCase(unittest.TestCase):
import SCons.SConsign
SCons.SConsign.write() # simulate normal scons-finish
for n in sys.modules.keys():
- if string.split(n, '.')[0] == 'SCons' and n[:12] != 'SCons.compat':
+ if n.split('.')[0] == 'SCons' and n[:12] != 'SCons.compat':
m = sys.modules[n]
- if type(m) is ModuleType:
+ if isinstance(m, ModuleType):
# if this is really a scons module, clear its namespace
del sys.modules[n]
m.__dict__.clear()
@@ -84,7 +85,7 @@ class SConfTestCase(unittest.TestCase):
if (not self.scons_env.Detect( self.scons_env.subst('$CXX') ) or
not self.scons_env.Detect( self.scons_env.subst('$CC') ) or
not self.scons_env.Detect( self.scons_env.subst('$LINK') )):
- raise Exception, "This test needs an installed compiler!"
+ raise Exception("This test needs an installed compiler!")
if self.scons_env['CXX'] == 'g++':
global existing_lib
existing_lib = 'm'
@@ -97,11 +98,11 @@ class SConfTestCase(unittest.TestCase):
# original builtin functions whenever we have to reset
# all of our global state.
- import __builtin__
+ import builtins
import SCons.Platform.win32
- __builtin__.file = SCons.Platform.win32._builtin_file
- __builtin__.open = SCons.Platform.win32._builtin_open
+ builtins.file = SCons.Platform.win32._builtin_file
+ builtins.open = SCons.Platform.win32._builtin_open
def _baseTryXXX(self, TryFunc):
# TryCompile and TryLink are much the same, so we can test them
@@ -174,7 +175,7 @@ class SConfTestCase(unittest.TestCase):
self.prefix = ''
self.suffix = ''
def __call__(self, env, target, source):
- class MyNode:
+ class MyNode(object):
def __init__(self, name):
self.name = name
self.state = None
@@ -221,7 +222,7 @@ class SConfTestCase(unittest.TestCase):
def do_not_store_info(self):
pass
def get_executor(self):
- class Executor:
+ class Executor(object):
def __init__(self, targets):
self.targets = targets
def get_all_targets(self):
diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py
index 8865c3d..25f8486 100644
--- a/src/engine/SCons/SConsign.py
+++ b/src/engine/SCons/SConsign.py
@@ -27,11 +27,13 @@ Writing and reading information to the .sconsign file or files.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/SConsign.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/SConsign.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
-import cPickle
import os
-import os.path
+# compat layer imports "cPickle" for us if it's available.
+import pickle
import SCons.dblite
import SCons.Warnings
@@ -106,7 +108,7 @@ def write():
else:
syncmethod()
-class SConsignEntry:
+class SConsignEntry(object):
"""
Wrapper class for the generic entry in a .sconsign file.
The Node subclass populates it with attributes as it pleases.
@@ -124,7 +126,7 @@ class SConsignEntry:
def convert_from_sconsign(self, dir, name):
self.binfo.convert_from_sconsign(dir, name)
-class Base:
+class Base(object):
"""
This is the controlling class for the signatures for the collection of
entries associated with a specific directory. The actual directory
@@ -201,8 +203,8 @@ class DB(Base):
pass
else:
try:
- self.entries = cPickle.loads(rawentries)
- if type(self.entries) is not type({}):
+ self.entries = pickle.loads(rawentries)
+ if not isinstance(self.entries, dict):
self.entries = {}
raise TypeError
except KeyboardInterrupt:
@@ -239,7 +241,7 @@ class DB(Base):
path = normcase(self.dir.path)
for key, entry in self.entries.items():
entry.convert_to_sconsign()
- db[path] = cPickle.dumps(self.entries, 1)
+ db[path] = pickle.dumps(self.entries, 1)
if sync:
try:
@@ -260,8 +262,8 @@ class Dir(Base):
if not fp:
return
- self.entries = cPickle.load(fp)
- if type(self.entries) is not type({}):
+ self.entries = pickle.load(fp)
+ if not isinstance(self.entries, dict):
self.entries = {}
raise TypeError
@@ -327,7 +329,7 @@ class DirFile(Dir):
return
for key, entry in self.entries.items():
entry.convert_to_sconsign()
- cPickle.dump(self.entries, file, 1)
+ pickle.dump(self.entries, file, 1)
file.close()
if fname != self.sconsign:
try:
diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py
index 8d883c5..38c953b 100644
--- a/src/engine/SCons/SConsignTests.py
+++ b/src/engine/SCons/SConsignTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/SConsignTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/SConsignTests.py 5023 2010/06/14 22:05:46 scons"
import os
import sys
@@ -32,11 +32,11 @@ import SCons.dblite
import SCons.SConsign
-class BuildInfo:
+class BuildInfo(object):
def merge(self, object):
pass
-class DummySConsignEntry:
+class DummySConsignEntry(object):
def __init__(self, name):
self.name = name
self.binfo = BuildInfo()
@@ -45,12 +45,12 @@ class DummySConsignEntry:
def convert_from_sconsign(self, dir, name):
self.c_from_s = 1
-class FS:
+class FS(object):
def __init__(self, top):
self.Top = top
self.Top.repositories = []
-class DummyNode:
+class DummyNode(object):
def __init__(self, path='not_a_valid_path', binfo=None):
self.path = path
self.tpath = path
@@ -143,14 +143,14 @@ class BaseTestCase(SConsignTestCase):
except KeyError:
pass
else:
- raise "unexpected entry %s" % e
+ raise Exception("unexpected entry %s" % e)
try:
e = f.get_entry('bbb')
except KeyError:
pass
else:
- raise "unexpected entry %s" % e
+ raise Exception("unexpected entry %s" % e)
f.merge()
@@ -309,7 +309,7 @@ class SConsignFileTestCase(SConsignTestCase):
assert SCons.SConsign.DB_Name is file, SCons.SConsign.DB_Name
assert SCons.SConsign.DB_Module is None, SCons.SConsign.DB_Module
- class Fake_DBM:
+ class Fake_DBM(object):
def open(self, name, mode):
self.name = name
self.mode = mode
@@ -343,7 +343,7 @@ class writeTestCase(SConsignTestCase):
test = self.test
file = test.workpath('sconsign_file')
- class Fake_DBM:
+ class Fake_DBM(object):
def __getitem__(self, key):
return None
def __setitem__(self, key, value):
@@ -386,7 +386,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py
index a8f4be9..598d3b1 100644
--- a/src/engine/SCons/Scanner/C.py
+++ b/src/engine/SCons/Scanner/C.py
@@ -27,7 +27,7 @@ This module implements the depenency scanner for C/C++ code.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/C.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/C.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node.FS
import SCons.Scanner
@@ -44,7 +44,7 @@ class SConsCPPScanner(SCons.cpp.PreProcessor):
missing.
"""
def __init__(self, *args, **kw):
- apply(SCons.cpp.PreProcessor.__init__, (self,)+args, kw)
+ SCons.cpp.PreProcessor.__init__(self, *args, **kw)
self.missing = []
def initialize_result(self, fname):
self.result = SCons.Util.UniqueList([fname])
@@ -81,7 +81,7 @@ def dictify_CPPDEFINES(env):
return {cppdefines : None}
return cppdefines
-class SConsCPPScannerWrapper:
+class SConsCPPScannerWrapper(object):
"""
The SCons wrapper around a cpp.py scanner.
diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py
index 86f5d57..f09333b 100644
--- a/src/engine/SCons/Scanner/CTests.py
+++ b/src/engine/SCons/Scanner/CTests.py
@@ -21,14 +21,15 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/CTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/CTests.py 5023 2010/06/14 22:05:46 scons"
+import SCons.compat
+
+import collections
import os
-import os.path
import sys
import TestCmd
import unittest
-import UserDict
import SCons.Node.FS
import SCons.Warnings
@@ -170,9 +171,9 @@ test.write("f5b.h", "\n")
# define some helpers:
-class DummyEnvironment(UserDict.UserDict):
+class DummyEnvironment(collections.UserDict):
def __init__(self, **kw):
- UserDict.UserDict.__init__(self)
+ collections.UserDict.__init__(self)
self.data.update(kw)
self.fs = SCons.Node.FS.FS(test.workpath(''))
@@ -190,9 +191,9 @@ class DummyEnvironment(UserDict.UserDict):
return [[strSubst]]
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def get_calculator(self):
return None
@@ -213,8 +214,8 @@ else:
def deps_match(self, deps, headers):
global my_normpath
- scanned = map(my_normpath, map(str, deps))
- expect = map(my_normpath, headers)
+ scanned = list(map(my_normpath, list(map(str, deps))))
+ expect = list(map(my_normpath, headers))
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
@@ -310,7 +311,7 @@ class CScannerTestCase8(unittest.TestCase):
env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
deps2 = s(env.File('#fa.cpp'), env, path)
- headers1 = map(test.workpath, ['include/fa.h', 'include/fb.h'])
+ headers1 = list(map(test.workpath, ['include/fa.h', 'include/fb.h']))
headers2 = ['include/fa.h', 'include/fb.h']
deps_match(self, deps1, headers1)
deps_match(self, deps2, headers2)
@@ -319,7 +320,7 @@ class CScannerTestCase9(unittest.TestCase):
def runTest(self):
"""Generate a warning when we can't find a #included file"""
SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning)
- class TestOut:
+ class TestOut(object):
def __call__(self, x):
self.out = x
diff --git a/src/engine/SCons/Scanner/D.py b/src/engine/SCons/Scanner/D.py
index f657eeb..04bb5a7 100644
--- a/src/engine/SCons/Scanner/D.py
+++ b/src/engine/SCons/Scanner/D.py
@@ -30,10 +30,9 @@ Coded by Andy Friesen
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/D.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/D.py 5023 2010/06/14 22:05:46 scons"
import re
-import string
import SCons.Scanner
@@ -54,7 +53,7 @@ class D(SCons.Scanner.Classic):
def find_include(self, include, source_dir, path):
# translate dots (package separators) to slashes
- inc = string.replace(include, '.', '/')
+ inc = include.replace('.', '/')
i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path)
if i is None:
diff --git a/src/engine/SCons/Scanner/Dir.py b/src/engine/SCons/Scanner/Dir.py
index bb25324..172aa62 100644
--- a/src/engine/SCons/Scanner/Dir.py
+++ b/src/engine/SCons/Scanner/Dir.py
@@ -19,30 +19,29 @@
# 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__ = "src/engine/SCons/Scanner/Dir.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/Dir.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node.FS
import SCons.Scanner
def only_dirs(nodes):
is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
- return filter(is_Dir, nodes)
+ return list(filter(is_Dir, nodes))
def DirScanner(**kw):
"""Return a prototype Scanner instance for scanning
directories for on-disk files"""
kw['node_factory'] = SCons.Node.FS.Entry
kw['recursive'] = only_dirs
- return apply(SCons.Scanner.Base, (scan_on_disk, "DirScanner"), kw)
+ return SCons.Scanner.Base(scan_on_disk, "DirScanner", **kw)
def DirEntryScanner(**kw):
"""Return a prototype Scanner instance for "scanning"
directory Nodes for their in-memory entries"""
kw['node_factory'] = SCons.Node.FS.Entry
kw['recursive'] = None
- return apply(SCons.Scanner.Base, (scan_in_memory, "DirEntryScanner"), kw)
+ return SCons.Scanner.Base(scan_in_memory, "DirEntryScanner", **kw)
skip_entry = {}
@@ -67,7 +66,7 @@ for skip in skip_entry_list:
skip_entry[skip] = 1
skip_entry[SCons.Node.FS._my_normcase(skip)] = 1
-do_not_scan = lambda k: not skip_entry.has_key(k)
+do_not_scan = lambda k: k not in skip_entry
def scan_on_disk(node, env, path=()):
"""
@@ -100,9 +99,8 @@ def scan_in_memory(node, env, path=()):
# mixed Node types (Dirs and Files, for example) has a Dir as
# the first entry.
return []
- entry_list = filter(do_not_scan, entries.keys())
- entry_list.sort()
- return map(lambda n, e=entries: e[n], entry_list)
+ entry_list = sorted(filter(do_not_scan, list(entries.keys())))
+ return [entries[n] for n in entry_list]
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/DirTests.py b/src/engine/SCons/Scanner/DirTests.py
index c18a829..debf213 100644
--- a/src/engine/SCons/Scanner/DirTests.py
+++ b/src/engine/SCons/Scanner/DirTests.py
@@ -21,12 +21,10 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/DirTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/DirTests.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import sys
-import types
import unittest
import TestCmd
@@ -43,7 +41,7 @@ import SCons.Scanner.Dir
# def Entry(self, name):
# return self.fs.Entry(name)
-class DummyEnvironment:
+class DummyEnvironment(object):
def __init__(self, root):
self.fs = SCons.Node.FS.FS(root)
def Dir(self, name):
@@ -91,7 +89,7 @@ class DirScannerTestCase(DirScannerTestBase):
os.path.join('dir', 'sub'),
]
deps = s(env.Dir('dir'), env, ())
- sss = map(str, deps)
+ sss = list(map(str, deps))
assert sss == expect, sss
expect = [
@@ -99,7 +97,7 @@ class DirScannerTestCase(DirScannerTestBase):
os.path.join('dir', 'sub', 'f4'),
]
deps = s(env.Dir('dir/sub'), env, ())
- sss = map(str, deps)
+ sss = list(map(str, deps))
assert sss == expect, sss
class DirEntryScannerTestCase(DirScannerTestBase):
@@ -109,16 +107,16 @@ class DirEntryScannerTestCase(DirScannerTestBase):
s = SCons.Scanner.Dir.DirEntryScanner()
deps = s(env.Dir('dir'), env, ())
- sss = map(str, deps)
+ sss = list(map(str, deps))
assert sss == [], sss
deps = s(env.Dir('dir/sub'), env, ())
- sss = map(str, deps)
+ sss = list(map(str, deps))
assert sss == [], sss
# Make sure we don't blow up if handed a non-Dir node.
deps = s(env.File('dir/f1'), env, ())
- sss = map(str, deps)
+ sss = list(map(str, deps))
assert sss == [], sss
def suite():
diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py
index 1587368..8d023e7 100644
--- a/src/engine/SCons/Scanner/Fortran.py
+++ b/src/engine/SCons/Scanner/Fortran.py
@@ -25,12 +25,10 @@ This module implements the dependency scanner for Fortran code.
# 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__ = "src/engine/SCons/Scanner/Fortran.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/Fortran.py 5023 2010/06/14 22:05:46 scons"
import re
-import string
import SCons.Node
import SCons.Node.FS
@@ -75,7 +73,7 @@ class F90Scanner(SCons.Scanner.Classic):
kw['skeys'] = suffixes
kw['name'] = name
- apply(SCons.Scanner.Current.__init__, (self,) + args, kw)
+ SCons.Scanner.Current.__init__(self, *args, **kw)
def scan(self, node, env, path=()):
@@ -94,12 +92,12 @@ class F90Scanner(SCons.Scanner.Classic):
d = {}
for m in defmodules:
d[m] = 1
- modules = filter(lambda m, d=d: not d.has_key(m), modules)
+ modules = [m for m in modules if m not in d]
#modules = self.undefinedModules(modules, defmodules)
# Convert module name to a .mod filename
suffix = env.subst('$FORTRANMODSUFFIX')
- modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+ modules = [x.lower() + suffix for x in modules]
# Remove unique items from the list
mods_and_includes = SCons.Util.unique(includes+modules)
node.includes = mods_and_includes
@@ -123,9 +121,7 @@ class F90Scanner(SCons.Scanner.Classic):
sortkey = self.sort_key(dep)
nodes.append((sortkey, n))
- nodes.sort()
- nodes = map(lambda pair: pair[1], nodes)
- return nodes
+ return [pair[1] for pair in sorted(nodes)]
def FortranScan(path_variable="FORTRANPATH"):
"""Return a prototype Scanner instance for scanning source files
diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py
index 3ebb9a2..66eb057 100644
--- a/src/engine/SCons/Scanner/FortranTests.py
+++ b/src/engine/SCons/Scanner/FortranTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/FortranTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/FortranTests.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
@@ -207,7 +207,7 @@ test.write(['modules', 'use.mod'], "\n")
# define some helpers:
-class DummyEnvironment:
+class DummyEnvironment(object):
def __init__(self, listCppPath):
self.path = listCppPath
self.fs = SCons.Node.FS.FS(test.workpath(''))
@@ -218,10 +218,10 @@ class DummyEnvironment:
elif len(args) == 1 and args[0] == 'FORTRANPATH':
return self.path
else:
- raise KeyError, "Dummy environment only has FORTRANPATH attribute."
+ raise KeyError("Dummy environment only has FORTRANPATH attribute.")
def has_key(self, key):
- return self.Dictionary().has_key(key)
+ return key in self.Dictionary()
def __getitem__(self,key):
return self.Dictionary()[key]
@@ -238,9 +238,9 @@ class DummyEnvironment:
return arg
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def get_calculator(self):
return None
@@ -255,8 +255,8 @@ class DummyEnvironment:
return self.fs.File(filename)
def deps_match(self, deps, headers):
- scanned = map(os.path.normpath, map(str, deps))
- expect = map(os.path.normpath, headers)
+ scanned = list(map(os.path.normpath, list(map(str, deps))))
+ expect = list(map(os.path.normpath, headers))
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
@@ -382,7 +382,7 @@ class FortranScannerTestCase10(unittest.TestCase):
env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
deps2 = s(env.File('#fff4.f'), env, path)
- headers1 = map(test.workpath, ['include/f4.f'])
+ headers1 = list(map(test.workpath, ['include/f4.f']))
headers2 = ['include/f4.f']
deps_match(self, deps1, headers1)
deps_match(self, deps2, headers2)
@@ -390,7 +390,7 @@ class FortranScannerTestCase10(unittest.TestCase):
class FortranScannerTestCase11(unittest.TestCase):
def runTest(self):
SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning)
- class TestOut:
+ class TestOut(object):
def __call__(self, x):
self.out = x
diff --git a/src/engine/SCons/Scanner/IDL.py b/src/engine/SCons/Scanner/IDL.py
index f2169f8..507b9e1 100644
--- a/src/engine/SCons/Scanner/IDL.py
+++ b/src/engine/SCons/Scanner/IDL.py
@@ -28,7 +28,7 @@ Definition Language) files.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/IDL.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/IDL.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node.FS
import SCons.Scanner
diff --git a/src/engine/SCons/Scanner/IDLTests.py b/src/engine/SCons/Scanner/IDLTests.py
index 1dca8c8..d434971 100644
--- a/src/engine/SCons/Scanner/IDLTests.py
+++ b/src/engine/SCons/Scanner/IDLTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/IDLTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/IDLTests.py 5023 2010/06/14 22:05:46 scons"
import TestCmd
import SCons.Scanner.IDL
@@ -186,7 +186,7 @@ test.write([ 'repository', 'src', 'ddd.idl'], "\n")
# define some helpers:
-class DummyEnvironment:
+class DummyEnvironment(object):
def __init__(self, listCppPath):
self.path = listCppPath
self.fs = SCons.Node.FS.FS(test.workpath(''))
@@ -197,18 +197,18 @@ class DummyEnvironment:
elif len(args) == 1 and args[0] == 'CPPPATH':
return self.path
else:
- raise KeyError, "Dummy environment only has CPPPATH attribute."
+ raise KeyError("Dummy environment only has CPPPATH attribute.")
def subst(self, arg, target=None, source=None, conv=None):
return arg
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def has_key(self, key):
- return self.Dictionary().has_key(key)
+ return key in self.Dictionary()
def __getitem__(self,key):
return self.Dictionary()[key]
@@ -238,8 +238,8 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
my_normpath = os.path.normcase
def deps_match(self, deps, headers):
- scanned = map(my_normpath, map(str, deps))
- expect = map(my_normpath, headers)
+ scanned = list(map(my_normpath, list(map(str, deps))))
+ expect = list(map(my_normpath, headers))
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
@@ -329,7 +329,7 @@ class IDLScannerTestCase7(unittest.TestCase):
env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
deps2 = s(env.File('#t4.idl'), env, path)
- headers1 = map(test.workpath, ['include/fa.idl', 'include/fb.idl'])
+ headers1 = list(map(test.workpath, ['include/fa.idl', 'include/fb.idl']))
headers2 = ['include/fa.idl', 'include/fb.idl']
deps_match(self, deps1, headers1)
deps_match(self, deps2, headers2)
@@ -337,7 +337,7 @@ class IDLScannerTestCase7(unittest.TestCase):
class IDLScannerTestCase8(unittest.TestCase):
def runTest(self):
SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning)
- class TestOut:
+ class TestOut(object):
def __call__(self, x):
self.out = x
diff --git a/src/engine/SCons/Scanner/LaTeX.py b/src/engine/SCons/Scanner/LaTeX.py
index 01755f4..77be34c 100644
--- a/src/engine/SCons/Scanner/LaTeX.py
+++ b/src/engine/SCons/Scanner/LaTeX.py
@@ -27,10 +27,9 @@ This module implements the dependency scanner for LaTeX code.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/LaTeX.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/LaTeX.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import re
import SCons.Scanner
@@ -41,7 +40,7 @@ TexGraphics = ['.eps', '.ps']
LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif']
# Used as a return value of modify_env_var if the variable is not set.
-class _Null:
+class _Null(object):
pass
_null = _Null
@@ -58,13 +57,10 @@ def modify_env_var(env, var, abspath):
env.PrependENVPath(var, abspath)
try:
if SCons.Util.is_List(env[var]):
- #TODO(1.5)
- #env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
- env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var]))
+ env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
else:
# Split at os.pathsep to convert into absolute path
- #TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
- env.PrependENVPath(var, map(lambda p: os.path.abspath(p), string.split(str(env[var]), os.pathsep)))
+ env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
except KeyError:
pass
@@ -73,15 +69,13 @@ def modify_env_var(env, var, abspath):
# does not work, refuses to append ":" (os.pathsep).
if SCons.Util.is_List(env['ENV'][var]):
- # TODO(1.5)
- #env['ENV'][var] = os.pathsep.join(env['ENV'][var])
- env['ENV'][var] = string.join(env['ENV'][var], os.pathsep)
+ env['ENV'][var] = os.pathsep.join(env['ENV'][var])
# Append the trailing os.pathsep character here to catch the case with no env[var]
env['ENV'][var] = env['ENV'][var] + os.pathsep
return save
-class FindENVPathDirs:
+class FindENVPathDirs(object):
"""A class to bind a specific *PATH variable name to a function that
will return all of the *path directories."""
def __init__(self, variable):
@@ -165,7 +159,7 @@ class LaTeX(SCons.Scanner.Base):
'bibliographystyle': 'BSTINPUTS',
'usepackage': 'TEXINPUTS',
'lstinputlisting': 'TEXINPUTS'}
- env_variables = SCons.Util.unique(keyword_paths.values())
+ env_variables = SCons.Util.unique(list(keyword_paths.values()))
def __init__(self, name, suffixes, graphics_extensions, *args, **kw):
@@ -184,7 +178,7 @@ class LaTeX(SCons.Scanner.Base):
return []
return self.scan_recurse(node, path)
- class FindMultiPathDirs:
+ class FindMultiPathDirs(object):
"""The stock FindPathDirs function has the wrong granularity:
it is called once per target, while we need the path that depends
on what kind of included files is being searched. This wrapper
@@ -212,7 +206,7 @@ class LaTeX(SCons.Scanner.Base):
# To prevent "dict is not hashable error"
return tuple(di.items())
- class LaTeXScanCheck:
+ class LaTeXScanCheck(object):
"""Skip all but LaTeX source files, i.e., do not scan *.eps,
*.pdf, *.jpg, etc.
"""
@@ -231,7 +225,7 @@ class LaTeX(SCons.Scanner.Base):
kw['scan_check'] = LaTeXScanCheck(suffixes)
kw['name'] = name
- apply(SCons.Scanner.Base.__init__, (self,) + args, kw)
+ SCons.Scanner.Base.__init__(self, *args, **kw)
def _latex_names(self, include):
filename = include[1]
@@ -252,11 +246,12 @@ class LaTeX(SCons.Scanner.Base):
if include[0] == 'includegraphics':
base, ext = os.path.splitext( filename )
if ext == "":
- #TODO(1.5) return [filename + e for e in self.graphics_extensions]
- #return map(lambda e, f=filename: f+e, self.graphics_extensions + TexGraphics)
- # use the line above to find dependency for PDF builder when only .eps figure is present
- # Since it will be found if the user tell scons how to make the pdf figure leave it out for now.
- return map(lambda e, f=filename: f+e, self.graphics_extensions)
+ #return [filename+e for e in self.graphics_extensions + TexGraphics]
+ # use the line above to find dependencies for the PDF builder
+ # when only an .eps figure is present. Since it will be found
+ # if the user tells scons how to make the pdf figure, leave
+ # it out for now.
+ return [filename+e for e in self.graphics_extensions]
return [filename]
def sort_key(self, include):
@@ -303,7 +298,7 @@ class LaTeX(SCons.Scanner.Base):
split_includes = []
for include in includes:
inc_type = noopt_cre.sub('', include[0])
- inc_list = string.split(include[1],',')
+ inc_list = include[1].split(',')
for j in range(len(inc_list)):
split_includes.append( (inc_type, inc_list[j]) )
#
@@ -336,19 +331,11 @@ class LaTeX(SCons.Scanner.Base):
while queue:
include = queue.pop()
- # TODO(1.5): more compact:
- #try:
- # if seen[include[1]] == 1:
- # continue
- #except KeyError:
- # seen[include[1]] = 1
try:
- already_seen = seen[include[1]]
+ if seen[include[1]] == 1:
+ continue
except KeyError:
seen[include[1]] = 1
- already_seen = False
- if already_seen:
- continue
#
# Handle multiple filenames in include[1]
@@ -366,10 +353,7 @@ class LaTeX(SCons.Scanner.Base):
# recurse down
queue.extend( self.scan(n) )
- #
- nodes.sort()
- nodes = map(lambda pair: pair[1], nodes)
- return nodes
+ return [pair[1] for pair in sorted(nodes)]
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Scanner/LaTeXTests.py b/src/engine/SCons/Scanner/LaTeXTests.py
index d503a86..38c837f 100644
--- a/src/engine/SCons/Scanner/LaTeXTests.py
+++ b/src/engine/SCons/Scanner/LaTeXTests.py
@@ -21,14 +21,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/LaTeXTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/LaTeXTests.py 5023 2010/06/14 22:05:46 scons"
-import os.path
-import string
+import SCons.compat
+
+import collections
+import os
import sys
-import types
import unittest
-import UserDict
import TestCmd
import SCons.Node.FS
@@ -66,9 +66,9 @@ test.write('incNO.tex', "\n")
# define some helpers:
# copied from CTest.py
-class DummyEnvironment(UserDict.UserDict):
+class DummyEnvironment(collections.UserDict):
def __init__(self, **kw):
- UserDict.UserDict.__init__(self)
+ collections.UserDict.__init__(self)
self.data.update(kw)
self.fs = SCons.Node.FS.FS(test.workpath(''))
@@ -86,9 +86,9 @@ class DummyEnvironment(UserDict.UserDict):
return [[strSubst]]
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def get_calculator(self):
return None
@@ -109,8 +109,8 @@ else:
def deps_match(self, deps, headers):
global my_normpath
- scanned = map(my_normpath, map(str, deps))
- expect = map(my_normpath, headers)
+ scanned = list(map(my_normpath, list(map(str, deps))))
+ expect = list(map(my_normpath, headers))
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py
index 395d39f..97f25b3 100644
--- a/src/engine/SCons/Scanner/Prog.py
+++ b/src/engine/SCons/Scanner/Prog.py
@@ -21,9 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/Prog.py 4720 2010/03/24 03:14:11 jars"
-
-import string
+__revision__ = "src/engine/SCons/Scanner/Prog.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node
import SCons.Node.FS
@@ -37,7 +35,7 @@ def ProgramScanner(**kw):
"""Return a prototype Scanner instance for scanning executable
files for static-lib dependencies"""
kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH')
- ps = apply(SCons.Scanner.Base, [scan, "ProgramScanner"], kw)
+ ps = SCons.Scanner.Base(scan, "ProgramScanner", **kw)
return ps
def scan(node, env, libpath = ()):
@@ -53,7 +51,7 @@ def scan(node, env, libpath = ()):
# There are no LIBS in this environment, so just return a null list:
return []
if SCons.Util.is_String(libs):
- libs = string.split(libs)
+ libs = libs.split()
else:
libs = SCons.Util.flatten(libs)
diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py
index d3162cb..6e124e6 100644
--- a/src/engine/SCons/Scanner/ProgTests.py
+++ b/src/engine/SCons/Scanner/ProgTests.py
@@ -21,12 +21,10 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/ProgTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/ProgTests.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import sys
-import types
import unittest
import TestCmd
@@ -45,7 +43,7 @@ for h in libs:
# define some helpers:
-class DummyEnvironment:
+class DummyEnvironment(object):
def __init__(self, **kw):
self._dict = {'LIBSUFFIXES' : '.lib'}
self._dict.update(kw)
@@ -57,10 +55,10 @@ class DummyEnvironment:
elif len(args) == 1:
return self._dict[args[0]]
else:
- return map(lambda x, s=self: s._dict[x], args)
+ return [self._dict[x] for x in args]
def has_key(self, key):
- return self.Dictionary().has_key(key)
+ return key in self.Dictionary()
def __getitem__(self,key):
return self.Dictionary()[key]
@@ -80,9 +78,9 @@ class DummyEnvironment:
return s
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def get_factory(self, factory):
return factory or self.fs.File
@@ -93,7 +91,7 @@ class DummyEnvironment:
def File(self, filename):
return self.fs.File(test.workpath(filename))
-class DummyNode:
+class DummyNode(object):
def __init__(self, name):
self.name = name
def rexists(self):
@@ -102,10 +100,9 @@ class DummyNode:
return self.name
def deps_match(deps, libs):
- deps=map(str, deps)
- deps.sort()
+ deps=sorted(map(str, deps))
libs.sort()
- return map(os.path.normpath, deps) == map(os.path.normpath, libs)
+ return list(map(os.path.normpath, deps)) == list(map(os.path.normpath, libs))
# define some tests:
@@ -116,14 +113,14 @@ class ProgramScannerTestCase1(unittest.TestCase):
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['l1.lib']), map(str, deps)
+ assert deps_match(deps, ['l1.lib']), list(map(str, deps))
env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
LIBS='l1')
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['l1.lib']), map(str, deps)
+ assert deps_match(deps, ['l1.lib']), list(map(str, deps))
f1 = env.fs.File(test.workpath('f1'))
env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
@@ -144,23 +141,23 @@ class ProgramScannerTestCase1(unittest.TestCase):
class ProgramScannerTestCase2(unittest.TestCase):
def runTest(self):
- env = DummyEnvironment(LIBPATH=map(test.workpath,
- ["", "d1", "d1/d2" ]),
+ env = DummyEnvironment(LIBPATH=list(map(test.workpath,
+ ["", "d1", "d1/d2" ])),
LIBS=[ 'l1', 'l2', 'l3' ])
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), map(str, deps)
+ assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), list(map(str, deps))
class ProgramScannerTestCase3(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"),
test.workpath("d1")],
- LIBS=string.split('l2 l3'))
+ LIBS='l2 l3'.split())
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
+ assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), list(map(str, deps))
class ProgramScannerTestCase5(unittest.TestCase):
def runTest(self):
@@ -171,11 +168,11 @@ class ProgramScannerTestCase5(unittest.TestCase):
else:
return arg
env = SubstEnvironment(LIBPATH=[ "$blah" ],
- LIBS=string.split('l2 l3'))
+ LIBS='l2 l3'.split())
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, [ 'd1/l2.lib' ]), map(str, deps)
+ assert deps_match(deps, [ 'd1/l2.lib' ]), list(map(str, deps))
class ProgramScannerTestCase6(unittest.TestCase):
def runTest(self):
@@ -186,7 +183,7 @@ class ProgramScannerTestCase6(unittest.TestCase):
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), map(str, deps)
+ assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps))
class ProgramScannerTestCase7(unittest.TestCase):
def runTest(self):
@@ -199,7 +196,7 @@ class ProgramScannerTestCase7(unittest.TestCase):
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
- assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), map(str, deps)
+ assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps))
class ProgramScannerTestCase8(unittest.TestCase):
def runTest(self):
@@ -233,13 +230,15 @@ def suite():
suite.addTest(ProgramScannerTestCase6())
suite.addTest(ProgramScannerTestCase7())
suite.addTest(ProgramScannerTestCase8())
- if hasattr(types, 'UnicodeType'):
+ try: unicode
+ except NameError: pass
+ else:
code = """if 1:
class ProgramScannerTestCase4(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"),
test.workpath("d1")],
- LIBS=string.split(u'l2 l3'))
+ LIBS=u'l2 l3'.split())
s = SCons.Scanner.Prog.ProgramScanner()
path = s.path(env)
deps = s(DummyNode('dummy'), env, path)
diff --git a/src/engine/SCons/Scanner/RC.py b/src/engine/SCons/Scanner/RC.py
index 23de58b..de7744b 100644
--- a/src/engine/SCons/Scanner/RC.py
+++ b/src/engine/SCons/Scanner/RC.py
@@ -28,7 +28,7 @@ Definition Language) files.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/RC.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/RC.py 5023 2010/06/14 22:05:46 scons"
import SCons.Node.FS
import SCons.Scanner
diff --git a/src/engine/SCons/Scanner/RCTests.py b/src/engine/SCons/Scanner/RCTests.py
index 62ca2d1..7da7e03 100644
--- a/src/engine/SCons/Scanner/RCTests.py
+++ b/src/engine/SCons/Scanner/RCTests.py
@@ -21,17 +21,16 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/RCTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/RCTests.py 5023 2010/06/14 22:05:46 scons"
import TestCmd
import SCons.Scanner.RC
import unittest
import sys
+import collections
import os
-import os.path
import SCons.Node.FS
import SCons.Warnings
-import UserDict
test = TestCmd.TestCmd(workdir = '')
@@ -71,9 +70,9 @@ for h in headers:
# define some helpers:
-class DummyEnvironment(UserDict.UserDict):
+class DummyEnvironment(collections.UserDict):
def __init__(self,**kw):
- UserDict.UserDict.__init__(self)
+ collections.UserDict.__init__(self)
self.data.update(kw)
self.fs = SCons.Node.FS.FS(test.workpath(''))
@@ -86,12 +85,12 @@ class DummyEnvironment(UserDict.UserDict):
return strSubst
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def has_key(self, key):
- return self.Dictionary().has_key(key)
+ return key in self.Dictionary()
def get_calculator(self):
return None
@@ -112,10 +111,8 @@ if os.path.normcase('foo') == os.path.normcase('FOO'):
my_normpath = os.path.normcase
def deps_match(self, deps, headers):
- scanned = map(my_normpath, map(str, deps))
- expect = map(my_normpath, headers)
- scanned.sort()
- expect.sort()
+ scanned = sorted(map(my_normpath, list(map(str, deps))))
+ expect = sorted(map(my_normpath, headers))
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
# define some tests:
diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py
index 2a65b36..c70b8a6 100644
--- a/src/engine/SCons/Scanner/ScannerTests.py
+++ b/src/engine/SCons/Scanner/ScannerTests.py
@@ -19,23 +19,24 @@
# 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__ = "src/engine/SCons/Scanner/ScannerTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/ScannerTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
+import collections
import sys
import unittest
-import UserDict
import SCons.Scanner
-class DummyFS:
+class DummyFS(object):
def File(self, name):
return DummyNode(name)
-class DummyEnvironment(UserDict.UserDict):
+class DummyEnvironment(collections.UserDict):
def __init__(self, dict=None, **kw):
- UserDict.UserDict.__init__(self, dict)
+ collections.UserDict.__init__(self, dict)
self.data.update(kw)
self.fs = DummyFS()
def subst(self, strSubst, target=None, source=None, conv=None):
@@ -47,13 +48,13 @@ class DummyEnvironment(UserDict.UserDict):
return [self.data[strSubst[1:]]]
return [[strSubst]]
def subst_path(self, path, target=None, source=None, conv=None):
- if type(path) != type([]):
+ if not isinstance(path, list):
path = [path]
- return map(self.subst, path)
+ return list(map(self.subst, path))
def get_factory(self, factory):
return factory or self.fs.File
-class DummyNode:
+class DummyNode(object):
def __init__(self, name, search_result=()):
self.name = name
self.search_result = tuple(search_result)
@@ -105,7 +106,7 @@ class ScannerTestCase(unittest.TestCase):
class BaseTestCase(unittest.TestCase):
- class skey_node:
+ class skey_node(object):
def __init__(self, key):
self.key = key
def scanner_key(self):
@@ -127,13 +128,13 @@ class BaseTestCase(unittest.TestCase):
self.deps = deps
path = scanner.path(env)
scanned = scanner(filename, env, path)
- scanned_strs = map(lambda x: str(x), scanned)
+ scanned_strs = [str(x) for x in scanned]
self.failUnless(self.filename == filename, "the filename was passed incorrectly")
self.failUnless(self.env == env, "the environment was passed incorrectly")
self.failUnless(scanned_strs == deps, "the dependencies were returned incorrectly")
for d in scanned:
- self.failUnless(type(d) != type(""), "got a string in the dependencies")
+ self.failUnless(not isinstance(d, str), "got a string in the dependencies")
if len(args) > 0:
self.failUnless(self.arg == args[0], "the argument was passed incorrectly")
@@ -241,7 +242,7 @@ class BaseTestCase(unittest.TestCase):
dict = {}
dict[s] = 777
i = hash(id(s))
- h = hash(dict.keys()[0])
+ h = hash(list(dict.keys())[0])
self.failUnless(h == i,
"hash Scanner base class expected %s, got %s" % (i, h))
@@ -280,7 +281,7 @@ class BaseTestCase(unittest.TestCase):
"recursive = 1 didn't return all nodes: %s" % n)
def odd_only(nodes):
- return filter(lambda n: n % 2, nodes)
+ return [n for n in nodes if n % 2]
s = SCons.Scanner.Base(function = self.func, recursive = odd_only)
n = s.recurse_nodes(nodes)
self.failUnless(n == [1, 3],
@@ -337,7 +338,7 @@ class BaseTestCase(unittest.TestCase):
assert s == 'xyzzy', s
class SelectorTestCase(unittest.TestCase):
- class skey_node:
+ class skey_node(object):
def __init__(self, key):
self.key = key
def scanner_key(self):
@@ -396,7 +397,7 @@ class SelectorTestCase(unittest.TestCase):
class CurrentTestCase(unittest.TestCase):
def test_class(self):
"""Test the Scanner.Current class"""
- class MyNode:
+ class MyNode(object):
def __init__(self):
self.called_has_builder = None
self.called_is_up_to_date = None
@@ -470,7 +471,7 @@ class ClassicTestCase(unittest.TestCase):
def test_scan(self):
"""Test the Scanner.Classic scan() method"""
- class MyNode:
+ class MyNode(object):
def __init__(self, name):
self.name = name
self._rfile = self
@@ -568,14 +569,7 @@ class ClassicCPPTestCase(unittest.TestCase):
assert n == 'path/bbb', n
assert i == 'bbb', i
- # TODO(1.5): remove when 2.2 is minimal; replace ccc
- # variable in find_include() call below with in-line u'ccc'.
- try:
- ccc = eval("u'ccc'")
- except SyntaxError:
- ccc = 'ccc'
-
- 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
@@ -595,7 +589,7 @@ def suite():
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
return suite
if __name__ == "__main__":
diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py
index 987df51..2a6f299 100644
--- a/src/engine/SCons/Scanner/__init__.py
+++ b/src/engine/SCons/Scanner/__init__.py
@@ -27,16 +27,15 @@ The Scanner package for the SCons software construction utility.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Scanner/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Scanner/__init__.py 5023 2010/06/14 22:05:46 scons"
import re
-import string
import SCons.Node.FS
import SCons.Util
-class _Null:
+class _Null(object):
pass
# This is used instead of None as a default argument value so None can be
@@ -56,13 +55,13 @@ def Scanner(function, *args, **kw):
patterned on SCons code.
"""
if SCons.Util.is_Dict(function):
- return apply(Selector, (function,) + args, kw)
+ return Selector(function, *args, **kw)
else:
- return apply(Base, (function,) + args, kw)
+ return Base(function, *args, **kw)
-class FindPathDirs:
+class FindPathDirs(object):
"""A class to bind a specific *PATH variable name to a function that
will return all of the *path directories."""
def __init__(self, variable):
@@ -80,7 +79,7 @@ class FindPathDirs:
-class Base:
+class Base(object):
"""
The base class for dependency scanners. This implements
straightforward, single-pass scanning of a single file.
@@ -171,7 +170,7 @@ class Base:
if skeys is _null:
if SCons.Util.is_Dict(function):
- skeys = function.keys()
+ skeys = list(function.keys())
else:
skeys = []
self.skeys = skeys
@@ -218,7 +217,7 @@ class Base:
nodes = []
for l in list:
if self.node_class and not isinstance(l, self.node_class):
- l = apply(node_factory, (l,), kw)
+ l = node_factory(l, **kw)
nodes.append(l)
return nodes
@@ -280,9 +279,9 @@ class Selector(Base):
for custom modules that may be out there.)
"""
def __init__(self, dict, *args, **kw):
- apply(Base.__init__, (self, None,)+args, kw)
+ Base.__init__(self, None, *args, **kw)
self.dict = dict
- self.skeys = dict.keys()
+ self.skeys = list(dict.keys())
def __call__(self, node, env, path = ()):
return self.select(node)(node, env, path)
@@ -309,7 +308,7 @@ class Current(Base):
def current_check(node, env):
return not node.has_builder() or node.is_up_to_date()
kw['scan_check'] = current_check
- apply(Base.__init__, (self,) + args, kw)
+ Base.__init__(self, *args, **kw)
class Classic(Current):
"""
@@ -339,7 +338,7 @@ class Classic(Current):
kw['skeys'] = suffixes
kw['name'] = name
- apply(Current.__init__, (self,) + args, kw)
+ Current.__init__(self, *args, **kw)
def find_include(self, include, source_dir, path):
n = SCons.Node.FS.find_file(include, (source_dir,) + tuple(path))
@@ -360,7 +359,7 @@ class Classic(Current):
includes = self.find_include_names (node)
# Intern the names of the include files. Saves some memory
# if the same header is included many times.
- node.includes = map(SCons.Util.silent_intern, includes)
+ node.includes = list(map(SCons.Util.silent_intern, includes))
# This is a hand-coded DSU (decorate-sort-undecorate, or
# Schwartzian transform) pattern. The sort key is the raw name
@@ -379,12 +378,9 @@ class Classic(Current):
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
else:
- sortkey = self.sort_key(include)
- nodes.append((sortkey, n))
+ nodes.append((self.sort_key(include), n))
- nodes.sort()
- nodes = map(lambda pair: pair[1], nodes)
- return nodes
+ return [pair[1] for pair in sorted(nodes)]
class ClassicCPP(Classic):
"""
@@ -408,7 +404,7 @@ class ClassicCPP(Classic):
return n, i
def sort_key(self, include):
- return SCons.Node.FS._my_normcase(string.join(include))
+ return SCons.Node.FS._my_normcase(' '.join(include))
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Script/Interactive.py b/src/engine/SCons/Script/Interactive.py
index 6218021..52fc753 100644
--- a/src/engine/SCons/Script/Interactive.py
+++ b/src/engine/SCons/Script/Interactive.py
@@ -19,9 +19,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.
-#
-__revision__ = "src/engine/SCons/Script/Interactive.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/Interactive.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
SCons interactive mode
@@ -90,7 +89,6 @@ import copy
import os
import re
import shlex
-import string
import sys
try:
@@ -134,7 +132,7 @@ class SConsInteractiveCmd(cmd.Cmd):
print "*** Unknown command: %s" % argv[0]
def onecmd(self, line):
- line = string.strip(line)
+ line = line.strip()
if not line:
print self.lastcmd
return self.emptyline()
@@ -144,7 +142,7 @@ class SConsInteractiveCmd(cmd.Cmd):
elif line[0] == '?':
line = 'help ' + line[1:]
if os.sep == '\\':
- line = string.replace(line, '\\', '\\\\')
+ line = line.replace('\\', '\\\\')
argv = shlex.split(line)
argv[0] = self.synonyms.get(argv[0], argv[0])
if not argv[0]:
@@ -222,8 +220,8 @@ class SConsInteractiveCmd(cmd.Cmd):
def get_unseen_children(node, parent, seen_nodes=seen_nodes):
def is_unseen(node, seen_nodes=seen_nodes):
- return not seen_nodes.has_key(node)
- return filter(is_unseen, node.children(scan=1))
+ return node not in seen_nodes
+ return list(filter(is_unseen, node.children(scan=1)))
def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
seen_nodes[node] = 1
@@ -247,9 +245,9 @@ class SConsInteractiveCmd(cmd.Cmd):
walker = SCons.Node.Walker(node,
kids_func=get_unseen_children,
eval_func=add_to_seen_nodes)
- n = walker.next()
+ n = walker.get_next()
while n:
- n = walker.next()
+ n = walker.get_next()
for node in seen_nodes.keys():
# Call node.clear() to clear most of the state
@@ -307,7 +305,7 @@ class SConsInteractiveCmd(cmd.Cmd):
def _strip_initial_spaces(self, s):
#lines = s.split('\n')
- lines = string.split(s, '\n')
+ lines = s.split('\n')
spaces = re.match(' *', lines[0]).group(0)
#def strip_spaces(l):
# if l.startswith(spaces):
@@ -318,8 +316,8 @@ class SConsInteractiveCmd(cmd.Cmd):
if l[:len(spaces)] == spaces:
l = l[len(spaces):]
return l
- lines = map(strip_spaces, lines)
- return string.join(lines, '\n')
+ lines = list(map(strip_spaces, lines))
+ return '\n'.join(lines)
def do_exit(self, argv):
"""\
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 74a28f2..2bd1560 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -8,10 +8,11 @@ should not be, or be considered, part of the build engine. If it's
something that we expect other software to want to use, it should go in
some other module. If it's specific to the "scons" script invocation,
it goes here.
-
"""
-#
+unsupported_python_version = (2, 3, 0)
+deprecated_python_version = (2, 4, 0)
+
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -32,13 +33,12 @@ it goes 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.
-#
-__revision__ = "src/engine/SCons/Script/Main.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/Main.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import os
-import os.path
-import string
import sys
import time
import traceback
@@ -89,7 +89,7 @@ progress_display = SCons.Util.DisplayEngine()
first_command_start = None
last_command_end = None
-class Progressor:
+class Progressor(object):
prev = ''
count = 0
target_string = '$TARGET'
@@ -107,7 +107,7 @@ class Progressor:
self.func = obj
elif SCons.Util.is_List(obj):
self.func = self.spinner
- elif string.find(obj, self.target_string) != -1:
+ elif obj.find(self.target_string) != -1:
self.func = self.replace_string
else:
self.func = self.string
@@ -132,7 +132,7 @@ class Progressor:
self.write(self.obj)
def replace_string(self, node):
- self.write(string.replace(self.obj, self.target_string, str(node)))
+ self.write(self.obj.replace(self.target_string, str(node)))
def __call__(self, node):
self.count = self.count + 1
@@ -145,7 +145,7 @@ ProgressObject = SCons.Util.Null()
def Progress(*args, **kw):
global ProgressObject
- ProgressObject = apply(Progressor, args, kw)
+ ProgressObject = Progressor(*args, **kw)
# Task control.
#
@@ -207,12 +207,10 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
t = self.targets[0]
if self.top and not t.has_builder() and not t.side_effect:
if not t.exists():
- def classname(obj):
- return string.split(str(obj.__class__), '.')[-1]
- if classname(t) in ('File', 'Dir', 'Entry'):
- errstr="Do not know how to make %s target `%s' (%s)." % (classname(t), t, t.abspath)
+ if t.__class__.__name__ in ('File', 'Dir', 'Entry'):
+ errstr="Do not know how to make %s target `%s' (%s)." % (t.__class__.__name__, t, t.abspath)
else: # Alias or Python or ...
- errstr="Do not know how to make %s target `%s'." % (classname(t), t)
+ errstr="Do not know how to make %s target `%s'." % (t.__class__.__name__, t)
sys.stderr.write("scons: *** " + errstr)
if not self.options.keep_going:
sys.stderr.write(" Stop.")
@@ -262,19 +260,16 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
node = buildError.node
if not SCons.Util.is_List(node):
node = [ node ]
- nodename = string.join(map(str, node), ', ')
+ nodename = ', '.join(map(str, node))
errfmt = "scons: *** [%s] %s\n"
sys.stderr.write(errfmt % (nodename, buildError))
if (buildError.exc_info[2] and buildError.exc_info[1] and
- # TODO(1.5)
- #not isinstance(
- # buildError.exc_info[1],
- # (EnvironmentError, SCons.Errors.StopError, SCons.Errors.UserError))):
- not isinstance(buildError.exc_info[1], EnvironmentError) and
- not isinstance(buildError.exc_info[1], SCons.Errors.StopError) and
- not isinstance(buildError.exc_info[1], SCons.Errors.UserError)):
+ not isinstance(
+ buildError.exc_info[1],
+ (EnvironmentError, SCons.Errors.StopError,
+ SCons.Errors.UserError))):
type, value, trace = buildError.exc_info
traceback.print_exception(type, value, trace)
elif tb and print_stacktrace:
@@ -316,11 +311,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
display("Removed " + pathstr)
elif os.path.isdir(path) and not os.path.islink(path):
# delete everything in the dir
- entries = os.listdir(path)
- # Sort for deterministic output (os.listdir() Can
- # return entries in a random order).
- entries.sort()
- for e in entries:
+ for e in sorted(os.listdir(path)):
p = os.path.join(path, e)
s = os.path.join(pathstr, e)
if os.path.isfile(p):
@@ -345,7 +336,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
for t in self.targets:
if not t.isdir():
display("Removed " + str(t))
- if SCons.Environment.CleanTargets.has_key(target):
+ if target in SCons.Environment.CleanTargets:
files = SCons.Environment.CleanTargets[target]
for f in files:
self.fs_delete(f.abspath, str(f), 0)
@@ -366,7 +357,7 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
else:
if removed:
display("Removed " + str(t))
- if SCons.Environment.CleanTargets.has_key(target):
+ if target in SCons.Environment.CleanTargets:
files = SCons.Environment.CleanTargets[target]
for f in files:
self.fs_delete(f.abspath, str(f))
@@ -405,7 +396,7 @@ class QuestionTask(SCons.Taskmaster.AlwaysTask):
pass
-class TreePrinter:
+class TreePrinter(object):
def __init__(self, derived=False, prune=False, status=False):
self.derived = derived
self.prune = prune
@@ -414,7 +405,7 @@ class TreePrinter:
return node.all_children()
def get_derived_children(self, node):
children = node.all_children(None)
- return filter(lambda x: x.has_builder(), children)
+ return [x for x in children if x.has_builder()]
def display(self, t):
if self.derived:
func = self.get_derived_children
@@ -425,13 +416,13 @@ class TreePrinter:
def python_version_string():
- return string.split(sys.version)[0]
+ return sys.version.split()[0]
def python_version_unsupported(version=sys.version_info):
- return version < (1, 5, 2)
+ return version < unsupported_python_version
def python_version_deprecated(version=sys.version_info):
- return version < (2, 4, 0)
+ return version < deprecated_python_version
# Global variables
@@ -447,7 +438,7 @@ this_build_status = 0 # "exit status" of an individual build
num_jobs = None
delayed_warnings = []
-class FakeOptionParser:
+class FakeOptionParser(object):
"""
A do-nothing option parser, used for the initial OptionsParser variable.
@@ -459,7 +450,7 @@ class FakeOptionParser:
without blowing up.
"""
- class FakeOptionValues:
+ class FakeOptionValues(object):
def __getattr__(self, attr):
return None
values = FakeOptionValues()
@@ -469,9 +460,9 @@ class FakeOptionParser:
OptionsParser = FakeOptionParser()
def AddOption(*args, **kw):
- if not kw.has_key('default'):
+ if 'default' not in kw:
kw['default'] = None
- result = apply(OptionsParser.add_local_option, args, kw)
+ result = OptionsParser.add_local_option(*args, **kw)
return result
def GetOption(name):
@@ -481,7 +472,7 @@ def SetOption(name, value):
return OptionsParser.values.set_option(name, value)
#
-class Stats:
+class Stats(object):
def __init__(self):
self.stats = []
self.labels = []
@@ -501,26 +492,24 @@ class CountStats(Stats):
def do_print(self):
stats_table = {}
for s in self.stats:
- for n in map(lambda t: t[0], s):
+ for n in [t[0] for t in s]:
stats_table[n] = [0, 0, 0, 0]
i = 0
for s in self.stats:
for n, c in s:
stats_table[n][i] = c
i = i + 1
- keys = stats_table.keys()
- keys.sort()
self.outfp.write("Object counts:\n")
pre = [" "]
post = [" %s\n"]
l = len(self.stats)
- fmt1 = string.join(pre + [' %7s']*l + post, '')
- fmt2 = string.join(pre + [' %7d']*l + post, '')
+ fmt1 = ''.join(pre + [' %7s']*l + post)
+ fmt2 = ''.join(pre + [' %7d']*l + post)
labels = self.labels[:l]
labels.append(("", "Class"))
- self.outfp.write(fmt1 % tuple(map(lambda x: x[0], labels)))
- self.outfp.write(fmt1 % tuple(map(lambda x: x[1], labels)))
- for k in keys:
+ self.outfp.write(fmt1 % tuple([x[0] for x in labels]))
+ self.outfp.write(fmt1 % tuple([x[1] for x in labels]))
+ for k in sorted(stats_table.keys()):
r = stats_table[k][:l] + [k]
self.outfp.write(fmt2 % tuple(r))
@@ -532,7 +521,7 @@ class MemStats(Stats):
self.stats.append(SCons.Debug.memory())
def do_print(self):
fmt = 'Memory %-32s %12d\n'
- for label, stats in map(None, self.labels, self.stats):
+ for label, stats in zip(self.labels, self.stats):
self.outfp.write(fmt % (label, stats))
memory_stats = MemStats()
@@ -563,7 +552,7 @@ def find_deepest_user_frame(tb):
# of SCons:
for frame in tb:
filename = frame[0]
- if string.find(filename, os.sep+'SCons'+os.sep) == -1:
+ if filename.find(os.sep+'SCons'+os.sep) == -1:
return frame
return tb[0]
@@ -598,7 +587,7 @@ def _scons_internal_warning(e):
*current call stack* rather than sys.exc_info() to get our stack trace.
This is used by the warnings framework to print warnings."""
filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_stack())
- sys.stderr.write("\nscons: warning: %s\n" % e[0])
+ sys.stderr.write("\nscons: warning: %s\n" % e.args[0])
sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine))
def _scons_internal_error():
@@ -687,7 +676,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
site_dir = os.path.join(topdir.path, site_dir_name)
if not os.path.exists(site_dir):
if err_if_not_found:
- raise SCons.Errors.UserError, "site dir %s not found."%site_dir
+ raise SCons.Errors.UserError("site dir %s not found."%site_dir)
return
site_init_filename = "site_init.py"
@@ -714,7 +703,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
m = sys.modules['SCons.Script']
except Exception, e:
fmt = 'cannot import site_init.py: missing SCons.Script module %s'
- raise SCons.Errors.InternalError, fmt % repr(e)
+ raise SCons.Errors.InternalError(fmt % repr(e))
try:
# This is the magic.
exec fp in m.__dict__
@@ -763,21 +752,8 @@ def _main(parser):
# suppress) appropriate warnings about anything that might happen,
# as configured by the user.
- default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
+ default_warnings = [ SCons.Warnings.WarningOnByDefault,
SCons.Warnings.DeprecatedWarning,
- SCons.Warnings.DuplicateEnvironmentWarning,
- SCons.Warnings.FutureReservedVariableWarning,
- SCons.Warnings.LinkWarning,
- SCons.Warnings.MissingSConscriptWarning,
- SCons.Warnings.NoMD5ModuleWarning,
- SCons.Warnings.NoMetaclassSupportWarning,
- SCons.Warnings.NoObjectCountWarning,
- SCons.Warnings.NoParallelSupportWarning,
- SCons.Warnings.MisleadingKeywordsWarning,
- SCons.Warnings.ReservedVariableWarning,
- SCons.Warnings.StackSizeWarning,
- SCons.Warnings.VisualVersionMismatch,
- SCons.Warnings.VisualCMissingWarning,
]
for warning in default_warnings:
@@ -855,7 +831,7 @@ def _main(parser):
# Give them the options usage now, before we fail
# trying to read a non-existent SConstruct file.
raise SConsPrintHelpException
- raise SCons.Errors.UserError, "No SConstruct file found."
+ raise SCons.Errors.UserError("No SConstruct file found.")
if scripts[0] == "-":
d = fs.getcwd()
@@ -955,7 +931,7 @@ def _main(parser):
# $SCONSFLAGS, or in the SConscript file, then the search through
# the list of deprecated warning classes will find that disabling
# first and not issue the warning.
- SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning)
+ #SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning)
SCons.Warnings.process_warn_strings(options.warn)
# Now that we've read the SConscript files, we can check for the
@@ -1087,7 +1063,7 @@ def _build_targets(fs, options, targets, target_top):
# or not a file, so go ahead and keep it as a default
# target and let the engine sort it out:
return 1
- d = filter(check_dir, SCons.Script.DEFAULT_TARGETS)
+ d = list(filter(check_dir, SCons.Script.DEFAULT_TARGETS))
SCons.Script.DEFAULT_TARGETS[:] = d
target_top = None
lookup_top = None
@@ -1122,7 +1098,7 @@ def _build_targets(fs, options, targets, target_top):
node = None
return node
- nodes = filter(None, map(Entry, targets))
+ nodes = [_f for _f in map(Entry, targets) if _f]
task_class = BuildTask # default action is to build targets
opening_message = "Building targets ..."
@@ -1154,7 +1130,7 @@ def _build_targets(fs, options, targets, target_top):
# This is cribbed from the implementation of
# random.shuffle() in Python 2.X.
d = dependencies
- for i in xrange(len(d)-1, 0, -1):
+ for i in range(len(d)-1, 0, -1):
j = int(random.random() * (i+1))
d[i], d[j] = d[j], d[i]
return d
@@ -1224,18 +1200,16 @@ def _build_targets(fs, options, targets, target_top):
def _exec_main(parser, values):
sconsflags = os.environ.get('SCONSFLAGS', '')
- all_args = string.split(sconsflags) + sys.argv[1:]
+ all_args = sconsflags.split() + sys.argv[1:]
options, args = parser.parse_args(all_args, values)
- if type(options.debug) == type([]) and "pdb" in options.debug:
+ if isinstance(options.debug, list) and "pdb" in options.debug:
import pdb
pdb.Pdb().runcall(_main, parser)
elif options.profile_file:
- try:
- from cProfile import Profile
- except ImportError, e:
- from profile import Profile
+ # compat layer imports "cProfile" for us if it's available.
+ from profile import Profile
# Some versions of Python 2.4 shipped a profiler that had the
# wrong 'c_exception' entry in its dispatch table. Make sure
@@ -1285,7 +1259,7 @@ def main():
pass
parts.append(version_string("engine", SCons))
parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation")
- version = string.join(parts, '')
+ version = ''.join(parts)
import SConsOptions
parser = SConsOptions.Parser(version)
diff --git a/src/engine/SCons/Script/MainTests.py b/src/engine/SCons/Script/MainTests.py
index d41d9c1..1855afa 100644
--- a/src/engine/SCons/Script/MainTests.py
+++ b/src/engine/SCons/Script/MainTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Script/MainTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/MainTests.py 5023 2010/06/14 22:05:46 scons"
import unittest
import SCons.Errors
@@ -42,7 +42,7 @@ if __name__ == "__main__":
tclasses = []
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Script/SConsOptions.py b/src/engine/SCons/Script/SConsOptions.py
index 545162b..913a6ee 100644
--- a/src/engine/SCons/Script/SConsOptions.py
+++ b/src/engine/SCons/Script/SConsOptions.py
@@ -21,20 +21,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Script/SConsOptions.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/SConsOptions.py 5023 2010/06/14 22:05:46 scons"
import optparse
import re
-import string
import sys
import textwrap
-try:
- no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')
-except re.error:
- # Pre-2.0 Python versions don't have the (?<= negative
- # look-behind assertion.
- no_hyphen_re = re.compile(r'(\s+|-*\w{2,}-(?=\w{2,}))')
+no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')
try:
from gettext import gettext
@@ -55,9 +49,10 @@ def diskcheck_convert(value):
if value is None:
return []
if not SCons.Util.is_List(value):
- value = string.split(value, ',')
+ value = value.split(',')
result = []
- for v in map(string.lower, value):
+ for v in value:
+ v = v.lower()
if v == 'all':
result = diskcheck_all
elif v == 'none':
@@ -65,7 +60,7 @@ def diskcheck_convert(value):
elif v in diskcheck_all:
result.append(v)
else:
- raise ValueError, v
+ raise ValueError(v)
return result
class SConsValues(optparse.Values):
@@ -139,7 +134,7 @@ class SConsValues(optparse.Values):
Sets an option from an SConscript file.
"""
if not name in self.settable:
- raise SCons.Errors.UserError, "This option is not settable from a SConscript file: %s"%name
+ raise SCons.Errors.UserError("This option is not settable from a SConscript file: %s"%name)
if name == 'num_jobs':
try:
@@ -147,19 +142,19 @@ class SConsValues(optparse.Values):
if value < 1:
raise ValueError
except ValueError:
- raise SCons.Errors.UserError, "A positive integer is required: %s"%repr(value)
+ raise SCons.Errors.UserError("A positive integer is required: %s"%repr(value))
elif name == 'max_drift':
try:
value = int(value)
except ValueError:
- raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
+ raise SCons.Errors.UserError("An integer is required: %s"%repr(value))
elif name == 'duplicate':
try:
value = str(value)
except ValueError:
- raise SCons.Errors.UserError, "A string is required: %s"%repr(value)
+ raise SCons.Errors.UserError("A string is required: %s"%repr(value))
if not value in SCons.Node.FS.Valid_Duplicates:
- raise SCons.Errors.UserError, "Not a valid duplication style: %s" % value
+ raise SCons.Errors.UserError("Not a valid duplication style: %s" % value)
# Set the duplicate style right away so it can affect linking
# of SConscript files.
SCons.Node.FS.set_duplicate(value)
@@ -167,8 +162,8 @@ class SConsValues(optparse.Values):
try:
value = diskcheck_convert(value)
except ValueError, v:
- raise SCons.Errors.UserError, "Not a valid diskcheck value: %s"%v
- if not self.__dict__.has_key('diskcheck'):
+ 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.
# Set this right away so it can affect the rest of the
# file/Node lookups while processing the SConscript files.
@@ -177,12 +172,12 @@ class SConsValues(optparse.Values):
try:
value = int(value)
except ValueError:
- raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
+ raise SCons.Errors.UserError("An integer is required: %s"%repr(value))
elif name == 'md5_chunksize':
try:
value = int(value)
except ValueError:
- raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
+ raise SCons.Errors.UserError("An integer is required: %s"%repr(value))
elif name == 'warn':
if SCons.Util.is_String(value):
value = [value]
@@ -197,7 +192,7 @@ class SConsOption(optparse.Option):
if self.nargs in (1, '?'):
return self.check_value(opt, value)
else:
- return tuple(map(lambda v, o=opt, s=self: s.check_value(o, v), value))
+ return tuple([self.check_value(opt, v) for v in value])
def process(self, opt, value, values, parser):
@@ -214,7 +209,7 @@ class SConsOption(optparse.Option):
def _check_nargs_optional(self):
if self.nargs == '?' and self._short_opts:
fmt = "option %s: nargs='?' is incompatible with short options"
- raise SCons.Errors.UserError, fmt % self._short_opts[0]
+ raise SCons.Errors.UserError(fmt % self._short_opts[0])
try:
_orig_CONST_ACTIONS = optparse.Option.CONST_ACTIONS
@@ -292,7 +287,7 @@ class SConsOptionParser(optparse.OptionParser):
# Value explicitly attached to arg? Pretend it's the next
# argument.
if "=" in arg:
- (opt, next_arg) = string.split(arg, "=", 1)
+ (opt, next_arg) = arg.split("=", 1)
rargs.insert(0, next_arg)
had_explicit_value = True
else:
@@ -356,7 +351,7 @@ class SConsOptionParser(optparse.OptionParser):
group = self.add_option_group(group)
self.local_option_group = group
- result = apply(group.add_option, args, kw)
+ result = group.add_option(*args, **kw)
if result:
# The option was added succesfully. We now have to add the
@@ -461,7 +456,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
result.append("%*s%s\n" % (self.help_position, "", line))
elif opts[-1] != "\n":
result.append("\n")
- return string.join(result, "")
+ return "".join(result)
# For consistent help output across Python versions, we provide a
# subclass copy of format_option_strings() and these two variables.
@@ -473,7 +468,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
def format_option_strings(self, option):
"""Return a comma-separated list of option strings & metavariables."""
if option.takes_value():
- metavar = option.metavar or string.upper(option.dest)
+ metavar = option.metavar or option.dest.upper()
short_opts = []
for sopt in option._short_opts:
short_opts.append(self._short_opt_fmt % (sopt, metavar))
@@ -489,7 +484,7 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
else:
opts = long_opts + short_opts
- return string.join(opts, ", ")
+ return ", ".join(opts)
def Parser(version):
"""
@@ -580,7 +575,7 @@ def Parser(version):
raise OptionValueError("Warning: %s is not a valid config type" % value)
setattr(parser.values, option.dest, value)
opt_config_help = "Controls Configure subsystem: %s." \
- % string.join(config_options, ", ")
+ % ", ".join(config_options)
op.add_option('--config',
nargs=1, type="string",
dest="config", default="auto",
@@ -604,7 +599,7 @@ def Parser(version):
debug_options = ["count", "explain", "findlibs",
"includes", "memoizer", "memory", "objects",
"pdb", "presub", "stacktrace",
- "time"] + deprecated_debug_options.keys()
+ "time"] + list(deprecated_debug_options.keys())
def opt_debug(option, opt, value, parser,
debug_options=debug_options,
@@ -618,12 +613,12 @@ def Parser(version):
parser.values.delayed_warnings = []
msg = deprecated_debug_options[value]
w = "The --debug=%s option is deprecated%s." % (value, msg)
- t = (SCons.Warnings.DeprecatedWarning, w)
+ t = (SCons.Warnings.DeprecatedDebugOptionsWarning, w)
parser.values.delayed_warnings.append(t)
else:
raise OptionValueError("Warning: %s is not a valid debug type" % value)
opt_debug_help = "Print various types of debugging information: %s." \
- % string.join(debug_options, ", ")
+ % ", ".join(debug_options)
op.add_option('--debug',
nargs=1, type="string",
dest="debug", default=[],
@@ -654,7 +649,7 @@ def Parser(version):
SCons.Node.FS.set_duplicate(value)
opt_duplicate_help = "Set the preferred duplication methods. Must be one of " \
- + string.join(SCons.Node.FS.Valid_Duplicates, ", ")
+ + ", ".join(SCons.Node.FS.Valid_Duplicates)
op.add_option('--duplicate',
nargs=1, type="string",
@@ -802,7 +797,7 @@ def Parser(version):
def opt_tree(option, opt, value, parser, tree_options=tree_options):
import Main
tp = Main.TreePrinter()
- for o in string.split(value, ','):
+ for o in value.split(','):
if o == 'all':
tp.derived = False
elif o == 'derived':
@@ -816,7 +811,7 @@ def Parser(version):
parser.values.tree_printers.append(tp)
opt_tree_help = "Print a dependency tree in various formats: %s." \
- % string.join(tree_options, ", ")
+ % ", ".join(tree_options)
op.add_option('--tree',
nargs=1, type="string",
@@ -846,7 +841,7 @@ def Parser(version):
def opt_warn(option, opt, value, parser, tree_options=tree_options):
if SCons.Util.is_String(value):
- value = string.split(value, ',')
+ value = value.split(',')
parser.values.warn.extend(value)
op.add_option('--warn', '--warning',
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index 98a3126..5a22db7 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -26,9 +26,9 @@ 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__ = "src/engine/SCons/Script/SConscript.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/SConscript.py 5023 2010/06/14 22:05:46 scons"
import SCons
import SCons.Action
@@ -45,14 +45,12 @@ import SCons.Script.Main
import SCons.Tool
import SCons.Util
+import collections
import os
import os.path
import re
-import string
import sys
import traceback
-import types
-import UserList
# The following variables used to live in this module. Some
# SConscript files out there may have referred to them directly as
@@ -80,7 +78,7 @@ sconscript_chdir = 1
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
+ try: 1//0
except ZeroDivisionError:
# Don't start iterating with the current stack-frame to
# prevent creating reference cycles (f_back is safe).
@@ -116,11 +114,11 @@ def compute_exports(exports):
except KeyError:
retval[export] = glob[export]
except KeyError, x:
- raise SCons.Errors.UserError, "Export of non-existent variable '%s'"%x
+ raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x)
return retval
-class Frame:
+class Frame(object):
"""A frame on the SConstruct/SConscript call stack"""
def __init__(self, fs, exports, sconscript):
self.globals = BuildDefaultGlobals()
@@ -145,10 +143,10 @@ def Return(*vars, **kw):
try:
fvars = SCons.Util.flatten(vars)
for var in fvars:
- for v in string.split(var):
+ for v in var.split():
retval.append(call_stack[-1].globals[v])
except KeyError, x:
- raise SCons.Errors.UserError, "Return of non-existent variable '%s'"%x
+ raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x)
if len(retval) == 1:
call_stack[-1].retval = retval[0]
@@ -312,7 +310,7 @@ def SConscript_exception(file=sys.stderr):
up to where we exec the SConscript."""
exc_type, exc_value, exc_tb = sys.exc_info()
tb = exc_tb
- while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
+ while tb and stack_bottom not in tb.tb_frame.f_locals:
tb = tb.tb_next
if not tb:
# We did not find our exec statement, so this was actually a bug
@@ -334,11 +332,11 @@ def annotate(node):
"""Annotate a node with the stack frame describing the
SConscript file and line number that created it."""
tb = sys.exc_info()[2]
- while tb and not tb.tb_frame.f_locals.has_key(stack_bottom):
+ while tb and stack_bottom not in tb.tb_frame.f_locals:
tb = tb.tb_next
if not tb:
# We did not find any exec of an SConscript file: what?!
- raise SCons.Errors.InternalError, "could not find SConscript stack frame"
+ raise SCons.Errors.InternalError("could not find SConscript stack frame")
node.creator = traceback.extract_stack(tb)[0]
# The following line would cause each Node to be annotated using the
@@ -369,7 +367,7 @@ class SConsEnvironment(SCons.Environment.Base):
This is complicated by the fact that a version string can be
something like 3.2b1."""
- version = string.split(string.split(version_string, ' ')[0], '.')
+ version = version_string.split(' ')[0].split('.')
v_major = int(version[0])
v_minor = int(re.match('\d+', version[1]).group())
if len(version) >= 3:
@@ -380,7 +378,7 @@ class SConsEnvironment(SCons.Environment.Base):
def _get_SConscript_filenames(self, ls, kw):
"""
- Convert the parameters passed to # SConscript() calls into a list
+ Convert the parameters passed to SConscript() calls into a list
of files and export variables. If the parameters are invalid,
throws SCons.Errors.UserError. Returns a tuple (l, e) where l
is a list of SConscript filenames and e is a list of exports.
@@ -391,16 +389,15 @@ class SConsEnvironment(SCons.Environment.Base):
try:
dirs = kw["dirs"]
except KeyError:
- raise SCons.Errors.UserError, \
- "Invalid SConscript usage - no parameters"
+ raise SCons.Errors.UserError("Invalid SConscript usage - no parameters")
if not SCons.Util.is_List(dirs):
dirs = [ dirs ]
- dirs = map(str, dirs)
+ dirs = list(map(str, dirs))
name = kw.get('name', 'SConscript')
- files = map(lambda n, name = name: os.path.join(n, name), dirs)
+ files = [os.path.join(n, name) for n in dirs]
elif len(ls) == 1:
@@ -413,8 +410,7 @@ class SConsEnvironment(SCons.Environment.Base):
else:
- raise SCons.Errors.UserError, \
- "Invalid SConscript() usage - too many arguments"
+ raise SCons.Errors.UserError("Invalid SConscript() usage - too many arguments")
if not SCons.Util.is_List(files):
files = [ files ]
@@ -425,8 +421,7 @@ class SConsEnvironment(SCons.Environment.Base):
variant_dir = kw.get('variant_dir') or kw.get('build_dir')
if variant_dir:
if len(files) != 1:
- raise SCons.Errors.UserError, \
- "Invalid SConscript() usage - can only specify one SConscript with a variant_dir"
+ raise SCons.Errors.UserError("Invalid SConscript() usage - can only specify one SConscript with a variant_dir")
duplicate = kw.get('duplicate', 1)
src_dir = kw.get('src_dir')
if not src_dir:
@@ -457,9 +452,9 @@ class SConsEnvironment(SCons.Environment.Base):
def Configure(self, *args, **kw):
if not SCons.Script.sconscript_reading:
- raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
+ raise SCons.Errors.UserError("Calling Configure from Builders is not supported.")
kw['_depth'] = kw.get('_depth', 0) + 1
- return apply(SCons.Environment.Base.Configure, (self,)+args, kw)
+ return SCons.Environment.Base.Configure(self, *args, **kw)
def Default(self, *targets):
SCons.Script._Set_Default_Targets(self, targets)
@@ -484,7 +479,7 @@ class SConsEnvironment(SCons.Environment.Base):
except AttributeError:
python_ver = self._get_major_minor_revision(sys.version)[:2]
if python_ver < (major, minor):
- v = string.split(sys.version, " ", 1)[0]
+ v = sys.version.split(" ", 1)[0]
print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v)
sys.exit(2)
@@ -520,21 +515,24 @@ class SConsEnvironment(SCons.Environment.Base):
globals.update(global_exports)
globals.update(exports)
else:
- if exports.has_key(v):
+ if v in exports:
globals[v] = exports[v]
else:
globals[v] = global_exports[v]
except KeyError,x:
- raise SCons.Errors.UserError, "Import of non-existent variable '%s'"%x
+ raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x)
def SConscript(self, *ls, **kw):
+ if 'build_dir' in kw:
+ msg = """The build_dir keyword has been deprecated; use the variant_dir keyword instead."""
+ SCons.Warnings.warn(SCons.Warnings.DeprecatedBuildDirWarning, msg)
def subst_element(x, subst=self.subst):
if SCons.Util.is_List(x):
- x = map(subst, x)
+ x = list(map(subst, x))
else:
x = subst(x)
return x
- ls = map(subst_element, ls)
+ ls = list(map(subst_element, ls))
subst_kw = {}
for key, val in kw.items():
if SCons.Util.is_String(val):
@@ -550,7 +548,7 @@ class SConsEnvironment(SCons.Environment.Base):
files, exports = self._get_SConscript_filenames(ls, subst_kw)
subst_kw['exports'] = exports
- return apply(_SConscript, [self.fs,] + files, subst_kw)
+ return _SConscript(self.fs, *files, **subst_kw)
def SConscriptChdir(self, flag):
global sconscript_chdir
@@ -567,9 +565,9 @@ SCons.Environment.Environment = SConsEnvironment
def Configure(*args, **kw):
if not SCons.Script.sconscript_reading:
- raise SCons.Errors.UserError, "Calling Configure from Builders is not supported."
+ raise SCons.Errors.UserError("Calling Configure from Builders is not supported.")
kw['_depth'] = 1
- return apply(SCons.SConf.SConf, args, kw)
+ return SCons.SConf.SConf(*args, **kw)
# It's very important that the DefaultEnvironmentCall() class stay in this
# file, with the get_calling_namespaces() function, the compute_exports()
@@ -595,7 +593,7 @@ def get_DefaultEnvironmentProxy():
_DefaultEnvironmentProxy = SCons.Environment.NoSubstitutionProxy(default_env)
return _DefaultEnvironmentProxy
-class DefaultEnvironmentCall:
+class DefaultEnvironmentCall(object):
"""A class that implements "global function" calls of
Environment methods by fetching the specified method from the
DefaultEnvironment's class. Note that this uses an intermediate
@@ -613,7 +611,7 @@ class DefaultEnvironmentCall:
def __call__(self, *args, **kw):
env = self.factory()
method = getattr(env, self.method_name)
- return apply(method, args, kw)
+ return method(*args, **kw)
def BuildDefaultGlobals():
@@ -629,7 +627,7 @@ def BuildDefaultGlobals():
import SCons.Script
d = SCons.Script.__dict__
def not_a_module(m, d=d, mtype=type(SCons.Script)):
- return type(d[m]) != mtype
+ return not isinstance(d[m], mtype)
for m in filter(not_a_module, dir(SCons.Script)):
GlobalDict[m] = d[m]
diff --git a/src/engine/SCons/Script/SConscriptTests.py b/src/engine/SCons/Script/SConscriptTests.py
index 4bf9dab..4036dd4 100644
--- a/src/engine/SCons/Script/SConscriptTests.py
+++ b/src/engine/SCons/Script/SConscriptTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Script/SConscriptTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/SConscriptTests.py 5023 2010/06/14 22:05:46 scons"
import SCons.Script.SConscript
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 97af6da..b5b5222 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -34,15 +34,14 @@ it goes here.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Script/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Script/__init__.py 5023 2010/06/14 22:05:46 scons"
import time
start_time = time.time()
+import collections
import os
-import string
import sys
-import UserList
# Special chicken-and-egg handling of the "--debug=memoizer" flag:
#
@@ -58,16 +57,15 @@ import UserList
# the "--debug=memoizer" flag and enable Memoizer before we import any
# of the other modules that use it.
-_args = sys.argv + string.split(os.environ.get('SCONSFLAGS', ''))
+_args = sys.argv + os.environ.get('SCONSFLAGS', '').split()
if "--debug=memoizer" in _args:
import SCons.Memoize
import SCons.Warnings
try:
SCons.Memoize.EnableMemoization()
except SCons.Warnings.Warning:
- # Some warning was thrown (inability to --debug=memoizer on
- # Python 1.5.2 because it doesn't have metaclasses). Arrange
- # for it to be displayed or not after warnings are configured.
+ # Some warning was thrown. Arrange for it to be displayed
+ # or not after warnings are configured.
import Main
exc_type, exc_value, tb = sys.exc_info()
Main.delayed_warnings.append((exc_type, exc_value))
@@ -184,7 +182,7 @@ CScan = SCons.Defaults.CScan
DefaultEnvironment = SCons.Defaults.DefaultEnvironment
# Other variables we provide.
-class TargetList(UserList.UserList):
+class TargetList(collections.UserList):
def _do_nothing(self, *args, **kw):
pass
def _add_Default(self, list):
@@ -211,7 +209,7 @@ _build_plus_default = TargetList()
def _Add_Arguments(alist):
for arg in alist:
- a, b = string.split(arg, '=', 1)
+ a, b = arg.split('=', 1)
ARGUMENTS[a] = b
ARGLIST.append((a, b))
diff --git a/src/engine/SCons/Sig.py b/src/engine/SCons/Sig.py
index 1da6ccb..49c00bf 100644
--- a/src/engine/SCons/Sig.py
+++ b/src/engine/SCons/Sig.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Sig.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Sig.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Place-holder for the old SCons.Sig module hierarchy
@@ -40,7 +40,7 @@ import SCons.Warnings
msg = 'The SCons.Sig module no longer exists.\n' \
' Remove the following "import SCons.Sig" line to eliminate this warning:'
-SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, msg)
+SCons.Warnings.warn(SCons.Warnings.DeprecatedSigModuleWarning, msg)
default_calc = None
default_module = None
diff --git a/src/engine/SCons/Subst.py b/src/engine/SCons/Subst.py
index fe18f08..d9b029a 100644
--- a/src/engine/SCons/Subst.py
+++ b/src/engine/SCons/Subst.py
@@ -25,15 +25,11 @@ SCons string substitution.
# 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__ = "src/engine/SCons/Subst.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Subst.py 5023 2010/06/14 22:05:46 scons"
+import collections
import re
-import string
-import types
-import UserList
-import UserString
import SCons.Errors
@@ -50,19 +46,19 @@ AllowableExceptions = (IndexError, NameError)
def SetAllowableExceptions(*excepts):
global AllowableExceptions
- AllowableExceptions = filter(None, excepts)
+ AllowableExceptions = [_f for _f in excepts if _f]
def raise_exception(exception, target, s):
name = exception.__class__.__name__
msg = "%s `%s' trying to evaluate `%s'" % (name, exception, s)
if target:
- raise SCons.Errors.BuildError, (target[0], msg)
+ raise SCons.Errors.BuildError(target[0], msg)
else:
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
-class Literal:
+class Literal(object):
"""A wrapper for a string. If you use this object wrapped
around a string, then it will be interpreted as literal.
When passed to the command interpreter, all special
@@ -82,7 +78,7 @@ class Literal:
def is_literal(self):
return 1
-class SpecialAttrWrapper:
+class SpecialAttrWrapper(object):
"""This is a wrapper for what we call a 'Node special attribute.'
This is any of the attributes of a Node that we can reference from
Environment variable substitution, such as $TARGET.abspath or
@@ -121,7 +117,7 @@ def quote_spaces(arg):
else:
return str(arg)
-class CmdStringHolder(UserString.UserString):
+class CmdStringHolder(collections.UserString):
"""This is a special class used to hold strings generated by
scons_subst() and scons_subst_list(). It defines a special method
escape(). When passed a function with an escape algorithm for a
@@ -129,7 +125,7 @@ class CmdStringHolder(UserString.UserString):
proper escape sequences inserted.
"""
def __init__(self, cmd, literal=None):
- UserString.UserString.__init__(self, cmd)
+ collections.UserString.__init__(self, cmd)
self.literal = literal
def is_literal(self):
@@ -152,7 +148,7 @@ class CmdStringHolder(UserString.UserString):
else:
return self.data
-def escape_list(list, escape_func):
+def escape_list(mylist, escape_func):
"""Escape a list of arguments by running the specified escape_func
on every object in the list that has an escape() method."""
def escape(obj, escape_func=escape_func):
@@ -162,9 +158,9 @@ def escape_list(list, escape_func):
return obj
else:
return e(escape_func)
- return map(escape, list)
+ return list(map(escape, mylist))
-class NLWrapper:
+class NLWrapper(object):
"""A wrapper class that delays turning a list of sources or targets
into a NodeList until it's needed. The specified function supplied
when the object is initialized is responsible for turning raw nodes
@@ -183,28 +179,28 @@ class NLWrapper:
def _return_nodelist(self):
return self.nodelist
def _gen_nodelist(self):
- list = self.list
- if list is None:
- list = []
- elif not is_Sequence(list):
- list = [list]
+ mylist = self.list
+ if mylist is None:
+ mylist = []
+ elif not is_Sequence(mylist):
+ mylist = [mylist]
# The map(self.func) call is what actually turns
# a list into appropriate proxies.
- self.nodelist = SCons.Util.NodeList(map(self.func, list))
+ self.nodelist = SCons.Util.NodeList(list(map(self.func, mylist)))
self._create_nodelist = self._return_nodelist
return self.nodelist
_create_nodelist = _gen_nodelist
-class Targets_or_Sources(UserList.UserList):
+class Targets_or_Sources(collections.UserList):
"""A class that implements $TARGETS or $SOURCES expansions by in turn
wrapping a NLWrapper. This class handles the different methods used
to access the list, calling the NLWrapper to create proxies on demand.
- Note that we subclass UserList.UserList purely so that the
+ Note that we subclass collections.UserList purely so that the
is_Sequence() function will identify an object of this class as
a list during variable expansion. We're not really using any
- UserList.UserList methods in practice.
+ collections.UserList methods in practice.
"""
def __init__(self, nl):
self.nl = nl
@@ -225,7 +221,7 @@ class Targets_or_Sources(UserList.UserList):
nl = self.nl._create_nodelist()
return repr(nl)
-class Target_or_Source:
+class Target_or_Source(object):
"""A class that implements $TARGET or $SOURCE expansions by in turn
wrapping a NLWrapper. This class handles the different methods used
to access an individual proxy Node, calling the NLWrapper to create
@@ -240,7 +236,7 @@ class Target_or_Source:
except IndexError:
# If there is nothing in the list, then we have no attributes to
# pass through, so raise AttributeError for everything.
- raise AttributeError, "NodeList has no attribute: %s" % attr
+ raise AttributeError("NodeList has no attribute: %s" % attr)
return getattr(nl0, attr)
def __str__(self):
nl = self.nl._create_nodelist()
@@ -256,9 +252,6 @@ class Target_or_Source:
class NullNodeList(SCons.Util.NullSeq):
def __call__(self, *args, **kwargs): return ''
def __str__(self): return ''
- # TODO(1.5): unneeded after new-style classes introduce iterators
- def __getitem__(self, i):
- raise IndexError
NullNodesList = NullNodeList()
@@ -344,7 +337,7 @@ _regex_remove = [ _rm, None, _remove ]
def _rm_list(list):
#return [ l for l in list if not l in ('$(', '$)') ]
- return filter(lambda l: not l in ('$(', '$)'), list)
+ return [l for l in list if not l in ('$(', '$)')]
def _remove_list(list):
result = []
@@ -399,10 +392,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
handles separating command lines into lists of arguments, so see
that function if that's what you're looking for.
"""
- if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
+ if isinstance(strSubst, str) and strSubst.find('$') < 0:
return strSubst
- class StringSubber:
+ class StringSubber(object):
"""A class to construct the results of a scons_subst() call.
This binds a specific construction environment, mode, target and
@@ -438,7 +431,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
return s
else:
key = s[1:]
- if key[0] == '{' or string.find(key, '.') >= 0:
+ if key[0] == '{' or key.find('.') >= 0:
if key[0] == '{':
key = key[1:-1]
try:
@@ -450,9 +443,9 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
return ''
raise_exception(e, lvars['TARGETS'], s)
else:
- if lvars.has_key(key):
+ if key in lvars:
s = lvars[key]
- elif self.gvars.has_key(key):
+ elif key in self.gvars:
s = self.gvars[key]
elif not NameError in AllowableExceptions:
raise_exception(NameError(key), lvars['TARGETS'], s)
@@ -472,13 +465,13 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
# are probably more the exception than the norm,
# so it should be tolerable for now.
lv = lvars.copy()
- var = string.split(key, '.')[0]
+ var = key.split('.')[0]
lv[var] = ''
return self.substitute(s, lv)
elif is_Sequence(s):
def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars):
return conv(substitute(l, lvars))
- return map(func, s)
+ return list(map(func, s))
elif callable(s):
try:
s = s(target=lvars['TARGETS'],
@@ -507,8 +500,8 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
if is_String(args) and not isinstance(args, CmdStringHolder):
args = str(args) # In case it's a UserString.
try:
- def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars):
- return conv(expand(match.group(1), lvars))
+ def sub_match(match):
+ return self.conv(self.expand(match.group(1), lvars))
result = _dollar_exps.sub(sub_match, args)
except TypeError:
# If the internal conversion routine doesn't return
@@ -523,7 +516,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
if len(result) == 1:
result = result[0]
else:
- result = string.join(map(str, result), '')
+ result = ''.join(map(str, result))
return result
else:
return self.expand(args, lvars)
@@ -540,7 +533,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
# If we dropped that behavior (or found another way to cover it),
# we could get rid of this call completely and just rely on the
# Executor setting the variables.
- if not lvars.has_key('TARGET'):
+ if 'TARGET' not in lvars:
d = subst_dict(target, source)
if d:
lvars = lvars.copy()
@@ -571,7 +564,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
if mode != SUBST_RAW:
# Compress strings of white space characters into
# a single space.
- result = string.strip(_space_sep.sub(' ', result))
+ result = _space_sep.sub(' ', result).strip()
elif is_Sequence(result):
remove = _list_remove[mode]
if remove:
@@ -595,7 +588,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
# Subst_List_Strings[strSubst] = 1
# import SCons.Debug
# SCons.Debug.caller_trace(1)
- class ListSubber(UserList.UserList):
+ class ListSubber(collections.UserList):
"""A class to construct the results of a scons_subst_list() call.
Like StringSubber, this class binds a specific construction
@@ -612,16 +605,16 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
internally.
"""
def __init__(self, env, mode, conv, gvars):
- UserList.UserList.__init__(self, [])
+ collections.UserList.__init__(self, [])
self.env = env
self.mode = mode
self.conv = conv
self.gvars = gvars
if self.mode == SUBST_RAW:
- self.add_strip = lambda x, s=self: s.append(x)
+ self.add_strip = lambda x: self.append(x)
else:
- self.add_strip = lambda x, s=self: None
+ self.add_strip = lambda x: None
self.in_strip = None
self.next_line()
@@ -653,7 +646,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
self.close_strip('$)')
else:
key = s[1:]
- if key[0] == '{' or string.find(key, '.') >= 0:
+ if key[0] == '{' or key.find('.') >= 0:
if key[0] == '{':
key = key[1:-1]
try:
@@ -665,9 +658,9 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
return
raise_exception(e, lvars['TARGETS'], s)
else:
- if lvars.has_key(key):
+ if key in lvars:
s = lvars[key]
- elif self.gvars.has_key(key):
+ elif key in self.gvars:
s = self.gvars[key]
elif not NameError in AllowableExceptions:
raise_exception(NameError(), lvars['TARGETS'], s)
@@ -680,7 +673,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
# string for the value of the variable name
# we just expanded.
lv = lvars.copy()
- var = string.split(key, '.')[0]
+ var = key.split('.')[0]
lv[var] = ''
self.substitute(s, lv, 0)
self.this_word()
@@ -735,7 +728,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
"""Arrange for the next word to start a new line. This
is like starting a new word, except that we have to append
another line to the result."""
- UserList.UserList.append(self, [])
+ collections.UserList.append(self, [])
self.next_word()
def this_word(self):
@@ -834,7 +827,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
# If we dropped that behavior (or found another way to cover it),
# we could get rid of this call completely and just rely on the
# Executor setting the variables.
- if not lvars.has_key('TARGET'):
+ if 'TARGET' not in lvars:
d = subst_dict(target, source)
if d:
lvars = lvars.copy()
@@ -870,7 +863,7 @@ def scons_subst_once(strSubst, env, key):
We do this with some straightforward, brute-force code here...
"""
- if type(strSubst) == types.StringType and string.find(strSubst, '$') < 0:
+ if isinstance(strSubst, str) and strSubst.find('$') < 0:
return strSubst
matchlist = ['$' + key, '${' + key + '}']
@@ -880,7 +873,7 @@ def scons_subst_once(strSubst, env, key):
if a in matchlist:
a = val
if is_Sequence(a):
- return string.join(map(str, a))
+ return ' '.join(map(str, a))
else:
return str(a)
diff --git a/src/engine/SCons/SubstTests.py b/src/engine/SCons/SubstTests.py
index fafedff..5078313 100644
--- a/src/engine/SCons/SubstTests.py
+++ b/src/engine/SCons/SubstTests.py
@@ -21,23 +21,21 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/SubstTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/SubstTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import os
-import os.path
-import string
-import StringIO
import sys
-import types
import unittest
-from UserDict import UserDict
+from collections import UserDict
import SCons.Errors
from SCons.Subst import *
-class DummyNode:
+class DummyNode(object):
"""Simple node work-alike."""
def __init__(self, name):
self.name = os.path.normpath(name)
@@ -50,7 +48,7 @@ class DummyNode:
def get_subst_proxy(self):
return self
-class DummyEnv:
+class DummyEnv(object):
def __init__(self, dict={}):
self.dict = dict
@@ -85,7 +83,7 @@ def CmdGen1(target, source, env, for_signature):
assert str(source) == 's', source
return "${CMDGEN2('foo', %d)}" % for_signature
-class CmdGen2:
+class CmdGen2(object):
def __init__(self, mystr, forsig):
self.mystr = mystr
self.expect_for_signature = forsig
@@ -101,14 +99,14 @@ if os.sep == '/':
return str
else:
def cvt(str):
- return string.replace(str, '/', os.sep)
+ return str.replace('/', os.sep)
class SubstTestCase(unittest.TestCase):
class MyNode(DummyNode):
"""Simple node work-alike with some extra stuff for testing."""
def __init__(self, name):
DummyNode.__init__(self, name)
- class Attribute:
+ class Attribute(object):
pass
self.attribute = Attribute()
self.attribute.attr1 = 'attr$1-' + os.path.basename(name)
@@ -117,7 +115,7 @@ class SubstTestCase(unittest.TestCase):
return self.name + extra
foo = 1
- class TestLiteral:
+ class TestLiteral(object):
def __init__(self, literal):
self.literal = literal
def __str__(self):
@@ -125,7 +123,7 @@ class SubstTestCase(unittest.TestCase):
def is_literal(self):
return 1
- class TestCallable:
+ class TestCallable(object):
def __init__(self, value):
self.value = value
def __call__(self):
@@ -149,7 +147,7 @@ class SubstTestCase(unittest.TestCase):
def _defines(defs):
l = []
for d in defs:
- if SCons.Util.is_List(d) or type(d) is types.TupleType:
+ if SCons.Util.is_List(d) or isinstance(d, tuple):
l.append(str(d[0]) + '=' + str(d[1]))
else:
l.append(str(d))
@@ -208,7 +206,7 @@ class SubstTestCase(unittest.TestCase):
'T' : ('x', 'y'),
'CS' : cs,
'CL' : cl,
- 'US' : UserString.UserString('us'),
+ 'US' : collections.UserString('us'),
# Test function calls within ${}.
'FUNCCALL' : '${FUNC1("$AAA $FUNC2 $BBB")}',
@@ -242,7 +240,7 @@ class SubstTestCase(unittest.TestCase):
input, expect = cases[:2]
expect = convert(expect)
try:
- result = apply(function, (input, env), kwargs)
+ result = function(input, env, **kwargs)
except Exception, e:
fmt = " input %s generated %s (%s)"
print fmt % (repr(input), e.__class__.__name__, repr(e))
@@ -366,9 +364,9 @@ class scons_subst_TestCase(SubstTestCase):
'$CL', 'cl',
# Various uses of UserString.
- UserString.UserString('x'), 'x',
- UserString.UserString('$X'), 'x',
- UserString.UserString('$US'), 'us',
+ collections.UserString('x'), 'x',
+ collections.UserString('$X'), 'x',
+ collections.UserString('$US'), 'us',
'$US', 'us',
# Test function calls within ${}.
@@ -513,7 +511,7 @@ class scons_subst_TestCase(SubstTestCase):
"""Test scons_subst(): handling attribute errors"""
env = DummyEnv(self.loc)
try:
- class Foo:
+ class Foo(object):
pass
scons_subst('${foo.bar}', env, gvars={'foo':Foo()})
except SCons.Errors.UserError, e:
@@ -521,10 +519,11 @@ class scons_subst_TestCase(SubstTestCase):
"AttributeError `bar' trying to evaluate `${foo.bar}'",
"AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
"AttributeError `'Foo' instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
+ "AttributeError `'Foo' object has no attribute 'bar'' trying to evaluate `${foo.bar}'",
]
assert str(e) in expect, e
else:
- raise AssertionError, "did not catch expected UserError"
+ raise AssertionError("did not catch expected UserError")
def test_subst_syntax_errors(self):
"""Test scons_subst(): handling syntax errors"""
@@ -533,16 +532,14 @@ class scons_subst_TestCase(SubstTestCase):
scons_subst('$foo.bar.3.0', env)
except SCons.Errors.UserError, e:
expect = [
- # Python 1.5
- "SyntaxError `invalid syntax' trying to evaluate `$foo.bar.3.0'",
- # Python 2.2, 2.3, 2.4
+ # Python 2.3, 2.4
"SyntaxError `invalid syntax (line 1)' trying to evaluate `$foo.bar.3.0'",
# Python 2.5
"SyntaxError `invalid syntax (<string>, line 1)' trying to evaluate `$foo.bar.3.0'",
]
assert str(e) in expect, e
else:
- raise AssertionError, "did not catch expected UserError"
+ raise AssertionError("did not catch expected UserError")
def test_subst_type_errors(self):
"""Test scons_subst(): handling type errors"""
@@ -551,14 +548,14 @@ class scons_subst_TestCase(SubstTestCase):
scons_subst("${NONE[2]}", env, gvars={'NONE':None})
except SCons.Errors.UserError, e:
expect = [
- # Python 1.5, 2.2, 2.3, 2.4
+ # Python 2.3, 2.4
"TypeError `unsubscriptable object' trying to evaluate `${NONE[2]}'",
# Python 2.5 and later
"TypeError `'NoneType' object is unsubscriptable' trying to evaluate `${NONE[2]}'",
]
assert str(e) in expect, e
else:
- raise AssertionError, "did not catch expected UserError"
+ raise AssertionError("did not catch expected UserError")
try:
def func(a, b, c):
@@ -566,14 +563,12 @@ class scons_subst_TestCase(SubstTestCase):
scons_subst("${func(1)}", env, gvars={'func':func})
except SCons.Errors.UserError, e:
expect = [
- # Python 1.5
- "TypeError `not enough arguments; expected 3, got 1' trying to evaluate `${func(1)}'",
- # Python 2.2, 2.3, 2.4, 2.5
+ # Python 2.3, 2.4, 2.5
"TypeError `func() takes exactly 3 arguments (1 given)' trying to evaluate `${func(1)}'"
]
assert str(e) in expect, repr(str(e))
else:
- raise AssertionError, "did not catch expected UserError"
+ raise AssertionError("did not catch expected UserError")
def test_subst_raw_function(self):
"""Test scons_subst(): fetch function with SUBST_RAW plus conv"""
@@ -758,12 +753,12 @@ class scons_subst_list_TestCase(SubstTestCase):
['$CL'], [['cl']],
# Various uses of UserString.
- UserString.UserString('x'), [['x']],
- [UserString.UserString('x')], [['x']],
- UserString.UserString('$X'), [['x']],
- [UserString.UserString('$X')], [['x']],
- UserString.UserString('$US'), [['us']],
- [UserString.UserString('$US')], [['us']],
+ collections.UserString('x'), [['x']],
+ [collections.UserString('x')], [['x']],
+ collections.UserString('$X'), [['x']],
+ [collections.UserString('$X')], [['x']],
+ collections.UserString('$US'), [['us']],
+ [collections.UserString('$US')], [['us']],
'$US', [['us']],
['$US'], [['us']],
@@ -798,7 +793,7 @@ class scons_subst_list_TestCase(SubstTestCase):
def test_scons_subst_list(self):
"""Test scons_subst_list(): basic substitution"""
def convert_lists(expect):
- return map(lambda l: map(cvt, l), expect)
+ return [list(map(cvt, l)) for l in expect]
return self.basic_comparisons(scons_subst_list, convert_lists)
subst_list_cases = [
@@ -967,7 +962,7 @@ class scons_subst_list_TestCase(SubstTestCase):
"""Test scons_subst_list(): handling attribute errors"""
env = DummyEnv()
try:
- class Foo:
+ class Foo(object):
pass
scons_subst_list('${foo.bar}', env, gvars={'foo':Foo()})
except SCons.Errors.UserError, e:
@@ -975,10 +970,11 @@ class scons_subst_list_TestCase(SubstTestCase):
"AttributeError `bar' trying to evaluate `${foo.bar}'",
"AttributeError `Foo instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
"AttributeError `'Foo' instance has no attribute 'bar'' trying to evaluate `${foo.bar}'",
+ "AttributeError `'Foo' object has no attribute 'bar'' trying to evaluate `${foo.bar}'",
]
assert str(e) in expect, e
else:
- raise AssertionError, "did not catch expected UserError"
+ raise AssertionError("did not catch expected UserError")
def test_subst_syntax_errors(self):
"""Test scons_subst_list(): handling syntax errors"""
@@ -993,7 +989,7 @@ class scons_subst_list_TestCase(SubstTestCase):
]
assert str(e) in expect, e
else:
- raise AssertionError, "did not catch expected SyntaxError"
+ raise AssertionError("did not catch expected SyntaxError")
def test_subst_raw_function(self):
"""Test scons_subst_list(): fetch function with SUBST_RAW plus conv"""
@@ -1111,7 +1107,7 @@ class quote_spaces_TestCase(unittest.TestCase):
q = quote_spaces('x\tx')
assert q == '"x\tx"', q
- class Node:
+ class Node(object):
def __init__(self, name, children=[]):
self.children = children
self.name = name
@@ -1181,16 +1177,14 @@ class subst_dict_TestCase(unittest.TestCase):
s1 = DummyNode('s1')
s2 = DummyNode('s2')
d = subst_dict(target=[t1, t2], source=[s1, s2])
- TARGETS = map(lambda x: str(x), d['TARGETS'])
- TARGETS.sort()
+ TARGETS = sorted([str(x) for x in d['TARGETS']])
assert TARGETS == ['t1', 't2'], d['TARGETS']
assert str(d['TARGET']) == 't1', d['TARGET']
- SOURCES = map(lambda x: str(x), d['SOURCES'])
- SOURCES.sort()
+ SOURCES = sorted([str(x) for x in d['SOURCES']])
assert SOURCES == ['s1', 's2'], d['SOURCES']
assert str(d['SOURCE']) == 's1', d['SOURCE']
- class V:
+ class V(object):
# Fake Value node with no rfile() method.
def __init__(self, name):
self.name = name
@@ -1210,11 +1204,9 @@ class subst_dict_TestCase(unittest.TestCase):
s4 = N('s4')
s5 = V('s5')
d = subst_dict(target=[t3, t4, t5], source=[s3, s4, s5])
- TARGETS = map(lambda x: str(x), d['TARGETS'])
- TARGETS.sort()
+ TARGETS = sorted([str(x) for x in d['TARGETS']])
assert TARGETS == ['t4', 'v-t3', 'v-t5'], TARGETS
- SOURCES = map(lambda x: str(x), d['SOURCES'])
- SOURCES.sort()
+ SOURCES = sorted([str(x) for x in d['SOURCES']])
assert SOURCES == ['s3', 'v-rstr-s4', 'v-s5'], SOURCES
if __name__ == "__main__":
@@ -1231,7 +1223,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index ec81af2..68ac1f5 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -19,7 +19,6 @@
# 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.
-#
__doc__ = """
Generic Taskmaster module for the SCons build engine.
@@ -48,11 +47,10 @@ interface and the SCons build engine. There are two key classes here:
target(s) that it decides need to be evaluated and/or built.
"""
-__revision__ = "src/engine/SCons/Taskmaster.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Taskmaster.py 5023 2010/06/14 22:05:46 scons"
from itertools import chain
import operator
-import string
import sys
import traceback
@@ -75,7 +73,7 @@ NODE_FAILED = SCons.Node.failed
CollectStats = None
-class Stats:
+class Stats(object):
"""
A simple class for holding statistics about the disposition of a
Node by the Taskmaster. If we're collecting statistics, each Node
@@ -107,13 +105,12 @@ fmt = "%(considered)3d "\
"%(build)3d "
def dump_stats():
- StatsNodes.sort(lambda a, b: cmp(str(a), str(b)))
- for n in StatsNodes:
+ for n in sorted(StatsNodes, key=lambda a: str(a)):
print (fmt % n.stats.__dict__) + str(n)
-class Task:
+class Task(object):
"""
Default SCons build engine task.
@@ -165,7 +162,7 @@ class Task:
the Action is actually called to build the targets.
"""
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
@@ -204,8 +201,9 @@ class Task:
# Deprecation Cycle) so the desired behavior is explicitly
# determined by which concrete subclass is used.
#raise NotImplementedError
- msg = ('Direct use of the Taskmaster.Task class will be deprecated\n'
- + '\tin a future release.')
+ msg = ('Taskmaster.Task is an abstract base class; instead of\n'
+ '\tusing it directly, '
+ 'derive from it and override the abstract methods.')
SCons.Warnings.warn(SCons.Warnings.TaskmasterNeedsExecuteWarning, msg)
return True
@@ -218,7 +216,7 @@ class Task:
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:
everything_was_cached = 1
@@ -370,7 +368,7 @@ class Task:
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 = []
@@ -415,7 +413,7 @@ class Task:
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
@@ -432,7 +430,7 @@ class Task:
# 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)
@@ -451,7 +449,7 @@ class Task:
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:
@@ -552,7 +550,7 @@ def find_cycle(stack, visited):
return None
-class Taskmaster:
+class Taskmaster(object):
"""
The Taskmaster for walking the dependency DAG.
"""
@@ -735,12 +733,12 @@ class Taskmaster:
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 1:
+ 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()
@@ -763,7 +761,7 @@ class Taskmaster:
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:
@@ -771,7 +769,7 @@ class Taskmaster:
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()
@@ -802,7 +800,7 @@ class Taskmaster:
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)
@@ -861,7 +859,7 @@ class Taskmaster:
# 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:
@@ -887,7 +885,7 @@ class Taskmaster:
# 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:
@@ -952,17 +950,8 @@ class Taskmaster:
T.write(self.trace_message(' removing node %s from the pending children set\n' %
self.trace_node(n)))
try:
- while 1:
- try:
- node = to_visit.pop()
- except AttributeError:
- # Python 1.5.2
- if len(to_visit):
- node = to_visit[0]
- to_visit.remove(node)
- else:
- break
-
+ while len(to_visit):
+ node = to_visit.pop()
node_func(node)
# Prune recursion by flushing the waiting children
@@ -982,7 +971,7 @@ class Taskmaster:
pass
# We have the stick back the pending_children list into the
- # task master because the python 1.5.2 compatibility does not
+ # taskmaster because the python 1.5.2 compatibility does not
# allow us to use in-place updates
self.pending_children = pending_children
@@ -999,16 +988,12 @@ class Taskmaster:
if not self.pending_children:
return
- # TODO(1.5)
- #nclist = [ (n, find_cycle([n], set())) for n in self.pending_children ]
- nclist = map(lambda n: (n, find_cycle([n], set())), self.pending_children)
+ nclist = [(n, find_cycle([n], set())) for n in self.pending_children]
- # TODO(1.5)
- #genuine_cycles = [
- # node for node, cycle in nclist
- # if cycle or node.get_state() != NODE_EXECUTED
- #]
- genuine_cycles = filter(lambda t: t[1] or t[0].get_state() != NODE_EXECUTED, nclist)
+ genuine_cycles = [
+ node for node,cycle in nclist
+ if cycle or node.get_state() != NODE_EXECUTED
+ ]
if not genuine_cycles:
# All of the "cycles" found were single nodes in EXECUTED state,
# which is to say, they really weren't cycles. Just return.
@@ -1017,13 +1002,13 @@ class Taskmaster:
desc = 'Found dependency cycle(s):\n'
for node, cycle in nclist:
if cycle:
- desc = desc + " " + string.join(map(str, cycle), " -> ") + "\n"
+ desc = desc + " " + " -> ".join(map(str, cycle)) + "\n"
else:
desc = desc + \
" Internal Error: no cycle found for node %s (%s) in state %s\n" % \
(node, repr(node), StateString[node.get_state()])
- raise SCons.Errors.UserError, desc
+ raise SCons.Errors.UserError(desc)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index 55c720a..4a07c79 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -20,8 +20,11 @@
# 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__ = "src/engine/SCons/TaskmasterTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/TaskmasterTests.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import copy
import sys
@@ -37,7 +40,7 @@ visited_nodes = []
executed = None
scan_called = 0
-class Node:
+class Node(object):
def __init__(self, name, kids = [], scans = []):
self.name = name
self.kids = kids
@@ -47,7 +50,7 @@ class Node:
self.scanner = None
self.targets = [self]
self.prerequisites = []
- class Builder:
+ class Builder(object):
def targets(self, node):
return node.targets
self.builder = Builder()
@@ -167,7 +170,7 @@ class Node:
def get_executor(self):
if not hasattr(self, 'executor'):
- class Executor:
+ class Executor(object):
def prepare(self):
pass
def get_action_targets(self):
@@ -537,7 +540,7 @@ class TaskmasterTestCase(unittest.TestCase):
"""
class MyTask(SCons.Taskmaster.Task):
def make_ready(self):
- raise MyException, "from make_ready()"
+ raise MyException("from make_ready()")
n1 = Node("n1")
tm = SCons.Taskmaster.Taskmaster(targets = [n1], tasker = MyTask)
@@ -613,7 +616,7 @@ class TaskmasterTestCase(unittest.TestCase):
"""
class StopNode(Node):
def children(self):
- raise SCons.Errors.StopError, "stop!"
+ raise SCons.Errors.StopError("stop!")
class ExitNode(Node):
def children(self):
sys.exit(77)
@@ -660,7 +663,7 @@ class TaskmasterTestCase(unittest.TestCase):
t = tm.next_task()
assert t.targets == [n1], t.targets
t.fail_stop()
- assert t.targets == [n3], map(str, t.targets)
+ assert t.targets == [n3], list(map(str, t.targets))
assert t.top == 1, t.top
def test_stop(self):
@@ -829,9 +832,9 @@ class TaskmasterTestCase(unittest.TestCase):
assert n10.prepared
# Make sure we call an Executor's prepare() method.
- class ExceptionExecutor:
+ class ExceptionExecutor(object):
def prepare(self):
- raise Exception, "Executor.prepare() exception"
+ raise Exception("Executor.prepare() exception")
def get_all_targets(self):
return self.nodes
def get_all_children(self):
@@ -854,7 +857,7 @@ class TaskmasterTestCase(unittest.TestCase):
except Exception, e:
assert str(e) == "Executor.prepare() exception", e
else:
- raise AssertionError, "did not catch expected exception"
+ raise AssertionError("did not catch expected exception")
def test_execute(self):
"""Test executing a task
@@ -879,7 +882,7 @@ class TaskmasterTestCase(unittest.TestCase):
except SCons.Errors.UserError:
pass
else:
- raise TestFailed, "did not catch expected UserError"
+ raise TestFailed("did not catch expected UserError")
def raise_BuildError():
raise SCons.Errors.BuildError
@@ -892,7 +895,7 @@ class TaskmasterTestCase(unittest.TestCase):
except SCons.Errors.BuildError:
pass
else:
- raise TestFailed, "did not catch expected BuildError"
+ raise TestFailed("did not catch expected BuildError")
# On a generic (non-BuildError) exception from a Builder,
# the target should throw a BuildError exception with the
@@ -910,9 +913,9 @@ class TaskmasterTestCase(unittest.TestCase):
assert e.errstr == "OtherError : ", e.errstr
assert len(e.exc_info) == 3, e.exc_info
exc_traceback = sys.exc_info()[2]
- assert type(e.exc_info[2]) == type(exc_traceback), e.exc_info[2]
+ assert isinstance(e.exc_info[2], type(exc_traceback)), e.exc_info[2]
else:
- raise TestFailed, "did not catch expected BuildError"
+ raise TestFailed("did not catch expected BuildError")
built_text = None
cache_text = []
@@ -967,7 +970,7 @@ class TaskmasterTestCase(unittest.TestCase):
t.exception_set(3)
assert t.exception == 3
- try: 1/0
+ try: 1//0
except: pass
t.exception_set(None)
exc_type, exc_value, exc_tb = t.exception
@@ -1008,7 +1011,7 @@ class TaskmasterTestCase(unittest.TestCase):
pass
try:
- 1/0
+ 1//0
except:
tb = sys.exc_info()[2]
t.exception_set((Exception3, "arg", tb))
@@ -1054,9 +1057,9 @@ class TaskmasterTestCase(unittest.TestCase):
def test_trace(self):
"""Test Taskmaster tracing
"""
- import StringIO
+ import io
- trace = StringIO.StringIO()
+ trace = io.StringIO()
n1 = Node("n1")
n2 = Node("n2")
n3 = Node("n3", [n1, n2])
diff --git a/src/engine/SCons/Tool/386asm.py b/src/engine/SCons/Tool/386asm.py
index 0891e96..5b8c8cb 100644
--- a/src/engine/SCons/Tool/386asm.py
+++ b/src/engine/SCons/Tool/386asm.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/386asm.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/386asm.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.PharLapCommon import addPharLapPaths
import SCons.Util
diff --git a/src/engine/SCons/Tool/BitKeeper.py b/src/engine/SCons/Tool/BitKeeper.py
index 121f579..a155a42 100644
--- a/src/engine/SCons/Tool/BitKeeper.py
+++ b/src/engine/SCons/Tool/BitKeeper.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/BitKeeper.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/BitKeeper.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
@@ -44,6 +44,8 @@ def generate(env):
def BitKeeperFactory(env=env):
""" """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The BitKeeper() factory is deprecated and there is no replacement.""")
act = SCons.Action.Action("$BITKEEPERCOM", "$BITKEEPERCOMSTR")
return SCons.Builder.Builder(action = act, env = env)
diff --git a/src/engine/SCons/Tool/CVS.py b/src/engine/SCons/Tool/CVS.py
index b30c319..bb9f956 100644
--- a/src/engine/SCons/Tool/CVS.py
+++ b/src/engine/SCons/Tool/CVS.py
@@ -8,7 +8,6 @@ selection method.
"""
-#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -29,9 +28,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/CVS.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/CVS.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
@@ -43,6 +41,8 @@ def generate(env):
def CVSFactory(repos, module='', env=env):
""" """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The CVS() factory is deprecated and there is no replacement.""")
# fail if repos is not an absolute path name?
if module != '':
# Don't use os.path.join() because the name we fetch might
diff --git a/src/engine/SCons/Tool/FortranCommon.py b/src/engine/SCons/Tool/FortranCommon.py
index 53c48e4..db89f96 100644
--- a/src/engine/SCons/Tool/FortranCommon.py
+++ b/src/engine/SCons/Tool/FortranCommon.py
@@ -27,10 +27,9 @@ Stuff for processing Fortran, common to all fortran dialects.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/FortranCommon.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/FortranCommon.py 5023 2010/06/14 22:05:46 scons"
import re
-import string
import os.path
import SCons.Action
@@ -73,7 +72,7 @@ def _fortranEmitter(target, source, env):
# Convert module name to a .mod filename
suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
- modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
+ modules = [x.lower() + suffix for x in modules]
for m in modules:
target.append(env.fs.File(m, moddir))
return (target, source)
@@ -91,8 +90,8 @@ def ComputeFortranSuffixes(suffixes, ppsuffixes):
pre-processed. Both should be sequences, not strings."""
assert len(suffixes) > 0
s = suffixes[0]
- sup = string.upper(s)
- upper_suffixes = map(string.upper, suffixes)
+ sup = s.upper()
+ upper_suffixes = [_.upper() for _ in suffixes]
if SCons.Util.case_sensitive_suffixes(s, sup):
ppsuffixes.extend(upper_suffixes)
else:
@@ -135,17 +134,17 @@ def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0):
static_obj.add_emitter(suffix, FortranEmitter)
shared_obj.add_emitter(suffix, ShFortranEmitter)
- if not env.has_key('%sFLAGS' % dialect):
+ if '%sFLAGS' % dialect not in env:
env['%sFLAGS' % dialect] = SCons.Util.CLVar('')
- if not env.has_key('SH%sFLAGS' % dialect):
+ if 'SH%sFLAGS' % dialect not in env:
env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
# If a tool does not define fortran prefix/suffix for include path, use C ones
- if not env.has_key('INC%sPREFIX' % dialect):
+ if 'INC%sPREFIX' % dialect not in env:
env['INC%sPREFIX' % dialect] = '$INCPREFIX'
- if not env.has_key('INC%sSUFFIX' % dialect):
+ if 'INC%sSUFFIX' % dialect not in env:
env['INC%sSUFFIX' % dialect] = '$INCSUFFIX'
env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect)
diff --git a/src/engine/SCons/Tool/JavaCommon.py b/src/engine/SCons/Tool/JavaCommon.py
index 635659a..bd6a30b 100644
--- a/src/engine/SCons/Tool/JavaCommon.py
+++ b/src/engine/SCons/Tool/JavaCommon.py
@@ -27,12 +27,11 @@ Stuff for processing Java.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/JavaCommon.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/JavaCommon.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
import re
-import string
java_parsing = 1
@@ -60,7 +59,7 @@ if java_parsing:
r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' +
r'/\*|\*/|\[\])')
- class OuterState:
+ class OuterState(object):
"""The initial state for parsing a Java file for classes,
interfaces, and anonymous inner classes."""
def __init__(self, version=default_java_version):
@@ -68,7 +67,7 @@ if java_parsing:
if not version in ('1.1', '1.2', '1.3','1.4', '1.5', '1.6',
'5', '6'):
msg = "Java version %s not supported" % version
- raise NotImplementedError, msg
+ raise NotImplementedError(msg)
self.version = version
self.listClasses = []
@@ -127,7 +126,7 @@ if java_parsing:
self.brackets = self.brackets - 1
if len(self.stackBrackets) and \
self.brackets == self.stackBrackets[-1]:
- self.listOutputs.append(string.join(self.listClasses, '$'))
+ self.listOutputs.append('$'.join(self.listClasses))
self.localClasses.pop()
self.listClasses.pop()
self.anonStacksStack.pop()
@@ -179,7 +178,7 @@ if java_parsing:
self.__getAnonStack()[-1] = self.__getAnonStack()[-1] + 1
for anon in self.__getAnonStack():
className.append(str(anon))
- self.listOutputs.append(string.join(className, '$'))
+ self.listOutputs.append('$'.join(className))
self.nextAnon = self.nextAnon + 1
self.__getAnonStack().append(0)
@@ -187,7 +186,7 @@ if java_parsing:
def setPackage(self, package):
self.package = package
- class AnonClassState:
+ class AnonClassState(object):
"""A state that looks for anonymous inner classes."""
def __init__(self, old_state):
# outer_state is always an instance of OuterState
@@ -222,7 +221,7 @@ if java_parsing:
self.outer_state.addAnonClass()
return self.old_state.parseToken(token)
- class SkipState:
+ class SkipState(object):
"""A state that will skip a specified number of tokens before
reverting to the previous state."""
def __init__(self, tokens_to_skip, old_state):
@@ -234,7 +233,7 @@ if java_parsing:
return self.old_state
return self
- class ClassState:
+ class ClassState(object):
"""A state we go into when we hit a class or interface keyword."""
def __init__(self, outer_state):
# outer_state is always an instance of OuterState
@@ -261,7 +260,7 @@ if java_parsing:
self.outer_state.anonStacksStack.append([0])
return self.outer_state
- class IgnoreState:
+ class IgnoreState(object):
"""A state that will ignore all tokens until it gets to a
specified token."""
def __init__(self, ignore_until, old_state):
@@ -272,7 +271,7 @@ if java_parsing:
return self.old_state
return self
- class PackageState:
+ class PackageState(object):
"""The state we enter when we encounter the package keyword.
We assume the next token will be the package name."""
def __init__(self, outer_state):
@@ -298,7 +297,7 @@ if java_parsing:
currstate = currstate.parseToken(token)
if trace: trace(token, currstate)
if initial.package:
- package = string.replace(initial.package, '.', os.sep)
+ package = initial.package.replace('.', os.sep)
return (package, initial.listOutputs)
else:
diff --git a/src/engine/SCons/Tool/JavaCommonTests.py b/src/engine/SCons/Tool/JavaCommonTests.py
index 936b474..e900433 100644
--- a/src/engine/SCons/Tool/JavaCommonTests.py
+++ b/src/engine/SCons/Tool/JavaCommonTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/JavaCommonTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/JavaCommonTests.py 5023 2010/06/14 22:05:46 scons"
import os.path
import sys
@@ -569,7 +569,7 @@ if __name__ == "__main__":
tclasses = [ parse_javaTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Tool/MSCommon/__init__.py b/src/engine/SCons/Tool/MSCommon/__init__.py
index a612d9b..6389078 100644
--- a/src/engine/SCons/Tool/MSCommon/__init__.py
+++ b/src/engine/SCons/Tool/MSCommon/__init__.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
Common functions for Microsoft Visual Studio and Visual C/C++.
diff --git a/src/engine/SCons/Tool/MSCommon/arch.py b/src/engine/SCons/Tool/MSCommon/arch.py
index 34de46c..ba6d2d6 100644
--- a/src/engine/SCons/Tool/MSCommon/arch.py
+++ b/src/engine/SCons/Tool/MSCommon/arch.py
@@ -21,14 +21,14 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to define supported Windows chip architectures.
"""
import os
-class ArchDefinition:
+class ArchDefinition(object):
"""
A class for defining architecture-specific settings and logic.
"""
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
index 2303d2b..ef1aae9 100644
--- a/src/engine/SCons/Tool/MSCommon/common.py
+++ b/src/engine/SCons/Tool/MSCommon/common.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
Common helper functions for working with the Microsoft tool chain.
@@ -99,46 +99,78 @@ def has_reg(value):
# Functions for fetching environment variable settings from batch files.
-def normalize_env(env, keys):
+def normalize_env(env, keys, force=False):
"""Given a dictionary representing a shell environment, add the variables
from os.environ needed for the processing of .bat files; the keys are
controlled by the keys argument.
It also makes sure the environment values are correctly encoded.
- Note: the environment is copied"""
+ If force=True, then all of the key values that exist are copied
+ into the returned dictionary. If force=false, values are only
+ copied if the key does not already exist in the copied dictionary.
+
+ Note: the environment is copied."""
normenv = {}
if env:
for k in env.keys():
normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
for k in keys:
- if os.environ.has_key(k):
+ if k in os.environ and (force or not k in normenv):
normenv[k] = os.environ[k].encode('mbcs')
return normenv
def get_output(vcbat, args = None, env = None):
"""Parse the output of given bat file, with given args."""
+
+ if env is None:
+ # Create a blank environment, for use in launching the tools
+ env = SCons.Environment.Environment(tools=[])
+
+ # TODO: This is a hard-coded list of the variables that (may) need
+ # to be imported from os.environ[] for v[sc]*vars*.bat file
+ # execution to work. This list should really be either directly
+ # controlled by vc.py, or else derived from the common_tools_var
+ # settings in vs.py.
+ vars = [
+ 'COMSPEC',
+ 'VS90COMNTOOLS',
+ 'VS80COMNTOOLS',
+ 'VS71COMNTOOLS',
+ 'VS70COMNTOOLS',
+ 'VS60COMNTOOLS',
+ ]
+ env['ENV'] = normalize_env(env['ENV'], vars, force=False)
+
if args:
debug("Calling '%s %s'" % (vcbat, args))
- popen = subprocess.Popen('"%s" %s & set' % (vcbat, args),
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env)
+ popen = SCons.Action._subproc(env,
+ '"%s" %s & set' % (vcbat, args),
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
else:
debug("Calling '%s'" % vcbat)
- popen = subprocess.Popen('"%s" & set' % vcbat,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env=env)
+ popen = SCons.Action._subproc(env,
+ '"%s" & set' % vcbat,
+ stdin = 'devnull',
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
# Use the .stdout and .stderr attributes directly because the
# .communicate() method uses the threading module on Windows
# and won't work under Pythons not built with threading.
stdout = popen.stdout.read()
+ stderr = popen.stderr.read()
+ if stderr:
+ # TODO: find something better to do with stderr;
+ # this at least prevents errors from getting swallowed.
+ import sys
+ sys.stderr.write(stderr)
if popen.wait() != 0:
- raise IOError(popen.stderr.read().decode("mbcs"))
+ raise IOError(stderr.decode("mbcs"))
output = stdout.decode("mbcs")
return output
@@ -147,9 +179,7 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
# dkeep is a dict associating key: path_list, where key is one item from
# keep, and pat_list the associated list of paths
- # TODO(1.5): replace with the following list comprehension:
- #dkeep = dict([(i, []) for i in keep])
- dkeep = dict(map(lambda i: (i, []), keep))
+ dkeep = dict([(i, []) for i in keep])
# rdk will keep the regex to match the .bat file output line starts
rdk = {}
diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py
index bd123dc..30be811 100644
--- a/src/engine/SCons/Tool/MSCommon/netframework.py
+++ b/src/engine/SCons/Tool/MSCommon/netframework.py
@@ -19,16 +19,14 @@
# 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__ = "src/engine/SCons/Tool/MSCommon/netframework.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
"""
import os
import re
-import string
from common import read_reg, debug
@@ -58,14 +56,14 @@ def query_versions():
contents = os.listdir(froot)
l = re.compile('v[0-9]+.*')
- versions = filter(lambda e, l=l: l.match(e), contents)
+ versions = [e for e in contents if l.match(e)]
def versrt(a,b):
# since version numbers aren't really floats...
aa = a[1:]
bb = b[1:]
- aal = string.split(aa, '.')
- bbl = string.split(bb, '.')
+ aal = aa.split('.')
+ bbl = bb.split('.')
# sequence comparison in python is lexicographical
# which is exactly what we want.
# Note we sort backwards so the highest version is first.
diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py
index 54be8ca..6debeb6 100644
--- a/src/engine/SCons/Tool/MSCommon/sdk.py
+++ b/src/engine/SCons/Tool/MSCommon/sdk.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to detect the Platform/Windows SDK
@@ -58,7 +58,7 @@ _CURINSTALLED_SDK_HKEY_ROOT = \
r"Software\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder"
-class SDKDefinition:
+class SDKDefinition(object):
"""
An abstract base class for trying to find installed SDK directories.
"""
@@ -131,7 +131,7 @@ class WindowsSDK(SDKDefinition):
"""
HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder'
def __init__(self, *args, **kw):
- apply(SDKDefinition.__init__, (self,)+args, kw)
+ SDKDefinition.__init__(self, *args, **kw)
self.hkey_data = self.version
class PlatformSDK(SDKDefinition):
@@ -140,7 +140,7 @@ class PlatformSDK(SDKDefinition):
"""
HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir'
def __init__(self, *args, **kw):
- apply(SDKDefinition.__init__, (self,)+args, kw)
+ SDKDefinition.__init__(self, *args, **kw)
self.hkey_data = self.uuid
#
@@ -310,9 +310,9 @@ def get_cur_sdk_dir_from_reg():
return val
def get_sdk_by_version(mssdk):
- if not SupportedSDKMap.has_key(mssdk):
+ if mssdk not in SupportedSDKMap:
msg = "SDK version %s is not supported" % repr(mssdk)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
get_installed_sdks()
return InstalledSDKMap.get(mssdk)
@@ -328,22 +328,22 @@ def get_default_sdk():
def mssdk_setup_env(env):
debug('sdk.py:mssdk_setup_env()')
- if env.has_key('MSSDK_DIR'):
+ if 'MSSDK_DIR' in env:
sdk_dir = env['MSSDK_DIR']
if sdk_dir is None:
return
sdk_dir = env.subst(sdk_dir)
debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir)
- elif env.has_key('MSSDK_VERSION'):
+ elif 'MSSDK_VERSION' in env:
sdk_version = env['MSSDK_VERSION']
if sdk_version is None:
msg = "SDK version %s is not installed" % repr(mssdk)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
sdk_version = env.subst(sdk_version)
mssdk = get_sdk_by_version(sdk_version)
sdk_dir = mssdk.get_sdk_dir()
debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir)
- elif env.has_key('MSVS_VERSION'):
+ elif 'MSVS_VERSION' in env:
msvs_version = env['MSVS_VERSION']
debug('sdk.py:mssdk_setup_env:Getting MSVS_VERSION from env:%s'%msvs_version)
if msvs_version is None:
@@ -382,7 +382,7 @@ def mssdk_exists(version=None):
sdks = get_installed_sdks()
if version is None:
return len(sdks) > 0
- return sdks.has_key(version)
+ return version in sdks
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py b/src/engine/SCons/Tool/MSCommon/vc.py
index 5ea5a53..f07f34c 100644
--- a/src/engine/SCons/Tool/MSCommon/vc.py
+++ b/src/engine/SCons/Tool/MSCommon/vc.py
@@ -30,15 +30,15 @@
# * test on 64 bits XP + VS 2005 (and VS 6 if possible)
# * SDK
# * Assembly
-__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module for Visual C/C++ detection and configuration.
"""
import SCons.compat
-import string
import os
import platform
+from string import digits as string_digits
import SCons.Warnings
@@ -71,13 +71,16 @@ class BatchFileExecutionError(VisualCException):
# Dict to 'canonalize' the arch
_ARCH_TO_CANONICAL = {
- "x86": "x86",
- "amd64": "amd64",
- "i386": "x86",
- "emt64": "amd64",
- "x86_64": "amd64",
- "itanium": "ia64",
- "ia64": "ia64",
+ "amd64" : "amd64",
+ "emt64" : "amd64",
+ "i386" : "x86",
+ "i486" : "x86",
+ "i586" : "x86",
+ "i686" : "x86",
+ "ia64" : "ia64",
+ "itanium" : "ia64",
+ "x86" : "x86",
+ "x86_64" : "amd64",
}
# Given a (host, target) tuple, return the argument for the bat file. Both host
@@ -91,6 +94,8 @@ _HOST_TARGET_ARCH_TO_BAT_ARCH = {
}
def get_host_target(env):
+ debug('vc.py:get_host_target()')
+
host_platform = env.get('HOST_ARCH')
if not host_platform:
host_platform = platform.machine()
@@ -99,22 +104,29 @@ def get_host_target(env):
# PROCESSOR_ARCHITECTURE.
if not host_platform:
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
- target_platform = env.get('TARGET_ARCH')
- if not target_platform:
+
+ # Retain user requested TARGET_ARCH
+ req_target_platform = env.get('TARGET_ARCH')
+ debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
+
+ if req_target_platform:
+ # If user requested a specific platform then only try that one.
+ target_platform = req_target_platform
+ else:
target_platform = host_platform
-
+
try:
- host = _ARCH_TO_CANONICAL[host_platform]
+ host = _ARCH_TO_CANONICAL[host_platform.lower()]
except KeyError, e:
msg = "Unrecognized host architecture %s"
raise ValueError(msg % repr(host_platform))
try:
- target = _ARCH_TO_CANONICAL[target_platform]
+ target = _ARCH_TO_CANONICAL[target_platform.lower()]
except KeyError, e:
raise ValueError("Unrecognized target architecture %s" % target_platform)
- return (host, target)
+ return (host, target,req_target_platform)
_VCVER = ["10.0", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
@@ -136,17 +148,19 @@ _VCVER_TO_PRODUCT_DIR = {
'6.0': [
r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir']
}
-
+
def msvc_version_to_maj_min(msvc_version):
- t = msvc_version.split(".")
- if not len(t) == 2:
- raise ValueError("Unrecognized version %s" % msvc_version)
- try:
- maj = int(t[0])
- min = int(t[1])
- return maj, min
- except ValueError, e:
- raise ValueError("Unrecognized version %s" % msvc_version)
+ msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
+
+ t = msvc_version_numeric.split(".")
+ if not len(t) == 2:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
+ try:
+ maj = int(t[0])
+ min = int(t[1])
+ return maj, min
+ except ValueError, e:
+ raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
def is_host_target_supported(host_target, msvc_version):
"""Return True if the given (host, target) tuple is supported given the
@@ -206,7 +220,7 @@ def find_vc_pdir(msvc_version):
raise MissingConfiguration("registry dir %s not found on the filesystem" % comps)
return None
-def find_batch_file(env,msvc_version):
+def find_batch_file(env,msvc_version,host_arch,target_arch):
"""
Find the location of the batch script which should set up the compiler
for any TARGET_ARCH whose compilers were installed by Visual Studio/VCExpress
@@ -218,7 +232,7 @@ def find_batch_file(env,msvc_version):
debug('vc.py: find_batch_file() pdir:%s'%pdir)
# filter out e.g. "Exp" from the version name
- msvc_ver_numeric = string.join(filter(lambda x: x in string.digits + ".", msvc_version), '')
+ msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
vernum = float(msvc_ver_numeric)
if 7 <= vernum < 8:
pdir = os.path.join(pdir, os.pardir, "Common7", "Tools")
@@ -234,7 +248,6 @@ def find_batch_file(env,msvc_version):
batfilename = None
installed_sdks=get_installed_sdks()
- (host_arch,target_arch)=get_host_target(env)
for _sdk in installed_sdks:
sdk_bat_file=_sdk.get_sdk_vc_script(host_arch,target_arch)
sdk_bat_file_path=os.path.join(pdir,sdk_bat_file)
@@ -330,6 +343,73 @@ def msvc_setup_env_once(env):
msvc_setup_env(env)
env["MSVC_SETUP_RUN"] = True
+def msvc_find_valid_batch_script(env,version):
+ debug('vc.py:msvc_find_valid_batch_script()')
+ # Find the host platform, target platform, and if present the requested
+ # target platform
+ (host_platform, target_platform,req_target_platform) = get_host_target(env)
+
+ # If the user hasn't specifically requested a TARGET_ARCH, and
+ # The TARGET_ARCH is amd64 then also try 32 bits if there are no viable
+ # 64 bit tools installed
+ try_target_archs = [target_platform]
+ if not req_target_platform and target_platform=='amd64':
+ try_target_archs.append('x86')
+
+ d = None
+ for tp in try_target_archs:
+ # Set to current arch.
+ env['TARGET_ARCH']=tp
+
+ debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
+ host_target = (host_platform, tp)
+ if not is_host_target_supported(host_target, version):
+ warn_msg = "host, target = %s not supported for MSVC version %s" % \
+ (host_target, version)
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
+ arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
+
+ # Try to locate a batch file for this host/target platform combo
+ 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:
+ msg = str(e)
+ debug('Caught exception while looking for batch file (%s)' % msg)
+ warn_msg = "VC version %s not installed. " + \
+ "C/C++ compilers are most likely not set correctly.\n" + \
+ " Installed versions are: %s"
+ warn_msg = warn_msg % (version, cached_get_installed_vcs())
+ SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
+ continue
+
+ # Try to use the located batch file for this host/target platform combo
+ debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
+ if vc_script:
+ try:
+ d = script_env(vc_script, args=arg)
+ except BatchFileExecutionError, 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
+ if not vc_script and sdk_script:
+ 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:
+ 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:
+ debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
+ continue
+
+ # If we cannot find a viable installed compiler, reset the TARGET_ARCH
+ # To it's initial value
+ if not d:
+ env['TARGET_ARCH']=req_target_platform
+
+ return d
+
+
def msvc_setup_env(env):
debug('msvc_setup_env()')
@@ -347,50 +427,16 @@ def msvc_setup_env(env):
env['MSVS_VERSION'] = version
env['MSVS'] = {}
- try:
- (vc_script,sdk_script) = find_batch_file(env,version)
- debug('vc.py:msvc_setup_env() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
- except VisualCException, e:
- msg = str(e)
- debug('Caught exception while looking for batch file (%s)' % msg)
- warn_msg = "VC version %s not installed. " + \
- "C/C++ compilers are most likely not set correctly.\n" + \
- " Installed versions are: %s"
- warn_msg = warn_msg % (version, cached_get_installed_vcs())
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
- return None
- debug('vc.py:msvc_setup_env() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
use_script = env.get('MSVC_USE_SCRIPT', True)
if SCons.Util.is_String(use_script):
- debug('use_script 1 %s\n' % repr(use_script))
+ debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
d = script_env(use_script)
- elif use_script:
- host_platform, target_platform = get_host_target(env)
- host_target = (host_platform, target_platform)
- if not is_host_target_supported(host_target, version):
- warn_msg = "host, target = %s not supported for MSVC version %s" % \
- (host_target, version)
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
- arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
- debug('use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
- if vc_script:
- try:
- d = script_env(vc_script, args=arg)
- except BatchFileExecutionError, e:
- debug('use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
- vc_script=None
- if not vc_script and sdk_script:
- debug('use_script 4: trying sdk script: %s'%(sdk_script))
- try:
- d = script_env(sdk_script,args=[])
- except BatchFileExecutionError,e:
- debug('use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
- return None
- elif not vc_script and not sdk_script:
- debug('use_script 6: Neither VC script nor SDK script found')
- return None
-
+ elif use_script:
+ d = msvc_find_valid_batch_script(env,version)
+ debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
+ if not d:
+ return d
else:
debug('MSVC_USE_SCRIPT set to False')
warn_msg = "MSVC_USE_SCRIPT set to False, assuming environment " \
diff --git a/src/engine/SCons/Tool/MSCommon/vc.py.bak b/src/engine/SCons/Tool/MSCommon/vc.py.bak
deleted file mode 100644
index 1bdd298..0000000
--- a/src/engine/SCons/Tool/MSCommon/vc.py.bak
+++ /dev/null
@@ -1,394 +0,0 @@
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
-# 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__ = "src/engine/SCons/Tool/MSCommon/vc.py.bak 4720 2010/03/24 03:14:11 jars"
-
-__doc__ = """Module for Visual C/C++ detection and configuration.
-"""
-
-import os
-import platform
-
-import SCons.Warnings
-
-import common
-
-debug = common.debug
-
-class VisualC:
- """
- An base class for finding installed versions of Visual C/C++.
- """
- def __init__(self, version, **kw):
- self.version = version
- self.__dict__.update(kw)
- self._cache = {}
-
- def vcbin_arch(self):
- if common.is_win64():
- result = {
- 'x86_64' : ['amd64', r'BIN\x86_amd64'],
- 'ia64' : [r'BIN\ia64'],
- }.get(target_arch, [])
- else:
- result = {
- 'x86_64' : ['x86_amd64'],
- 'ia64' : ['x86_ia64'],
- }.get(target_arch, [])
- # TODO(1.5)
- #return ';'.join(result)
- return string.join(result, ';')
-
- # Support for searching for an appropriate .bat file.
- # The map is indexed by (target_architecture, host_architecture).
- # Entries where the host_architecture is None specify the
- # cross-platform "default" .bat file if there isn't sn entry
- # specific to the current host architecture.
-
- batch_file_map = {
- ('x86_64', 'x86_64') : [
- r'bin\amd64\vcvarsamd64.bat',
- r'bin\x86_amd64\vcvarsx86_amd64.bat',
- r'bin\vcvarsx86_amd64.bat',
- ],
- ('x86_64', 'x86') : [
- r'bin\x86_amd64\vcvarsx86_amd64.bat',
- ],
- ('ia64', 'ia64') : [
- r'bin\ia64\vcvarsia64.bat',
- r'bin\x86_ia64\vcvarsx86_ia64.bat',
- ],
- ('ia64', None) : [
- r'bin\x86_ia64\vcvarsx86_ia64.bat',
- ],
- ('x86', None) : [
- r'bin\vcvars32.bat',
- ],
- }
-
- def find_batch_file(self, target_architecture, host_architecture):
- key = (target_architecture, host_architecture)
- potential_batch_files = self.batch_file_map.get(key)
- if not potential_batch_files:
- key = (target_architecture, None)
- potential_batch_files = self.batch_file_map.get(key)
- if potential_batch_files:
- product_dir = self.get_vc_dir()
- for batch_file in potential_batch_files:
- bf = os.path.join(product_dir, batch_file)
- if os.path.isfile(bf):
- return bf
- return None
-
- def find_vc_dir(self):
- root = 'Software\\'
- if common.is_win64():
- root = root + 'Wow6432Node\\'
- for key in self.hkeys:
- key = root + key
- try:
- comps = common.read_reg(key)
- except WindowsError, e:
- debug('find_vc_dir(): no VC registry key %s' % repr(key))
- else:
- debug('find_vc_dir(): found VC in registry: %s' % comps)
- if os.path.exists(comps):
- return comps
- else:
- debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\
- % comps)
- return None
- return None
-
- #
-
- def get_batch_file(self, target_architecture, host_architecture):
- try:
- return self._cache['batch_file']
- except KeyError:
- batch_file = self.find_batch_file(target_architecture, host_architecture)
- self._cache['batch_file'] = batch_file
- return batch_file
-
- def get_vc_dir(self):
- try:
- return self._cache['vc_dir']
- except KeyError:
- vc_dir = self.find_vc_dir()
- self._cache['vc_dir'] = vc_dir
- return vc_dir
-
- def reset(self):
- self._cache={}
-
-
-# The list of supported Visual C/C++ versions we know how to detect.
-#
-# The first VC found in the list is the one used by default if there
-# are multiple VC installed. Barring good reasons to the contrary,
-# this means we should list VC with from most recent to oldest.
-#
-# If you update this list, update the documentation in Tool/vc.xml.
-SupportedVCList = [
- VisualC('9.0',
- hkeys=[
- r'Microsoft\VisualStudio\9.0\Setup\VC\ProductDir',
- r'Microsoft\VCExpress\9.0\Setup\VC\ProductDir',
- ],
- default_install=r'Microsoft Visual Studio 9.0\VC',
- common_tools_var='VS90COMNTOOLS',
- vc_subdir=r'\VC',
- batch_file_base='vcvars',
- supported_arch=['x86', 'x86_64', 'ia64'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- 'x86_64' : r'ATLMFC\LIB\amd64',
- 'ia64' : r'ATLMFC\LIB\ia64',
- },
- crt_lib_subdir = {
- 'x86_64' : r'LIB\amd64',
- 'ia64' : r'LIB\ia64',
- },
- ),
- VisualC('8.0',
- hkeys=[
- r'Microsoft\VisualStudio\8.0\Setup\VC\ProductDir',
- r'Microsoft\VCExpress\8.0\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio 8\VC',
- common_tools_var='VS80COMNTOOLS',
- vc_subdir=r'\VC',
- batch_file_base='vcvars',
- supported_arch=['x86', 'x86_64', 'ia64'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- 'x86_64' : r'ATLMFC\LIB\amd64',
- 'ia64' : r'ATLMFC\LIB\ia64',
- },
- crt_lib_subdir = {
- 'x86_64' : r'LIB\amd64',
- 'ia64' : r'LIB\ia64',
- },
- ),
- VisualC('7.1',
- hkeys=[
- r'Microsoft\VisualStudio\7.1\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio 7.1.NET 2003\VC7',
- common_tools_var='VS71COMNTOOLS',
- vc_subdir=r'\VC7',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- },
- ),
- VisualC('7.0',
- hkeys=[
- r'Microsoft\VisualStudio\7.0\Setup\VC\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio .NET\VC7',
- common_tools_var='VS70COMNTOOLS',
- vc_subdir=r'\VC7',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATLMFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'ATLMFC\LIB',
- },
- ),
- VisualC('6.0',
- hkeys=[
- r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir',
- ],
- default_install=r'%s\Microsoft Visual Studio\VC98',
- common_tools_var='VS60COMNTOOLS',
- vc_subdir=r'\VC98',
- batch_file_base='vcvars',
- supported_arch=['x86'],
- atlmc_include_subdir = [r'ATL\INCLUDE', r'MFC\INCLUDE'],
- atlmfc_lib_subdir = {
- 'x86' : r'MFC\LIB',
- },
- ),
-]
-
-SupportedVCMap = {}
-for vc in SupportedVCList:
- SupportedVCMap[vc.version] = vc
-
-
-# Finding installed versions of Visual C/C++ isn't cheap, because it goes
-# not only to the registry but also to the disk to sanity-check that there
-# is, in fact, something installed there and that the registry entry isn't
-# just stale. Find this information once, when requested, and cache it.
-
-InstalledVCList = None
-InstalledVCMap = None
-
-def get_installed_vcs():
- global InstalledVCList
- global InstalledVCMap
- if InstalledVCList is None:
- InstalledVCList = []
- InstalledVCMap = {}
- for vc in SupportedVCList:
- debug('trying to find VC %s' % vc.version)
- if vc.get_vc_dir():
- debug('found VC %s' % vc.version)
- InstalledVCList.append(vc)
- InstalledVCMap[vc.version] = vc
- return InstalledVCList
-
-
-def set_vc_by_version(env, msvc):
- if not SupportedVCMap.has_key(msvc):
- msg = "VC version %s is not supported" % repr(msvc)
- raise SCons.Errors.UserError, msg
- get_installed_vcs()
- vc = InstalledVCMap.get(msvc)
- if not vc:
- msg = "VC version %s is not installed" % repr(msvc)
- raise SCons.Errors.UserError, msg
- set_vc_by_directory(env, vc.get_vc_dir())
-
-# New stuff
-
-def script_env(script, args=None):
- stdout = common.get_output(script, args)
- return common.parse_output(stdout)
-
-def get_default_version(env):
- debug('get_default_version()')
-
- msvc_version = env.get('MSVC_VERSION')
- if not msvc_version:
- installed_vcs = get_installed_vcs()
- debug('InstalledVCMap:%s'%InstalledVCMap)
- if not installed_vcs:
- msg = 'No installed VCs'
- debug('msv %s\n' % repr(msg))
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
- return None
- msvc = installed_vcs[0]
- msvc_version = msvc.version
- debug('msvc_setup_env: using default installed MSVC version %s\n' % repr(msvc_version))
-
- return msvc_version
-
-# Dict to 'canonalize' the arch
-_ARCH_TO_CANONICAL = {
- "x86": "x86",
- "amd64": "amd64",
- "i386": "x86",
- "emt64": "amd64",
- "x86_64": "amd64"
-}
-
-# Given a (host, target) tuple, return the argument for the bat file. Both host
-# and targets should be canonalized.
-_HOST_TARGET_ARCH_TO_BAT_ARCH = {
- ("x86", "x86"): "x86",
- ("x86", "amd64"): "x86_amd64",
- ("amd64", "amd64"): "amd64",
- ("amd64", "x86"): "x86"
-}
-
-def get_host_target(env):
- host_platform = env.get('HOST_ARCH')
- if not host_platform:
- #host_platform = get_default_host_platform()
- host_platform = platform.machine()
- target_platform = env.get('TARGET_ARCH')
- if not target_platform:
- target_platform = host_platform
-
- return (_ARCH_TO_CANONICAL[host_platform],
- _ARCH_TO_CANONICAL[target_platform])
-
-def msvc_setup_env_once(env):
- try:
- has_run = env["MSVC_SETUP_RUN"]
- except KeyError:
- has_run = False
-
- if not has_run:
- msvc_setup_env(env)
- env["MSVC_SETUP_RUN"] = False
-
-def msvc_setup_env(env):
- debug('msvc_setup_env()')
-
- version = get_default_version(env)
- host_platform, target_platform = get_host_target(env)
- debug('msvc_setup_env: using specified MSVC version %s\n' % repr(version))
- env['MSVC_VERSION'] = version
-
- msvc = InstalledVCMap.get(version)
- if not msvc:
- msg = 'VC version %s not installed' % version
- debug('msv %s\n' % repr(msg))
- SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, msg)
- return None
-
- use_script = env.get('MSVC_USE_SCRIPT', True)
- if SCons.Util.is_String(use_script):
- debug('use_script 1 %s\n' % repr(use_script))
- d = script_env(use_script)
- elif use_script:
- # XXX: this is VS 2008 specific, fix this
- script = os.path.join(msvc.find_vc_dir(), "vcvarsall.bat")
-
- arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[(host_platform, target_platform)]
- debug('use_script 2 %s, args:%s\n' % (repr(script), arg))
- d = script_env(script, args=arg)
- else:
- debug('msvc.get_default_env()\n')
- d = msvc.get_default_env()
-
- for k, v in d.items():
- env.PrependENVPath(k, v, delete_existing=True)
-
-def msvc_exists(version=None):
- vcs = get_installed_vcs()
- if version is None:
- return len(vcs) > 0
- return InstalledVCMap.has_key(version)
-
-
-def reset_installed_vcs():
- global InstalledVCList
- global InstalledVCMap
- InstalledVCList = None
- InstalledVCMap = None
- for vc in SupportedVCList:
- vc.reset()
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py
index e634a18..06030e2 100644
--- a/src/engine/SCons/Tool/MSCommon/vs.py
+++ b/src/engine/SCons/Tool/MSCommon/vs.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """Module to detect Visual Studio and/or Visual C/C++
"""
@@ -40,7 +40,7 @@ from common import debug, \
import SCons.Tool.MSCommon.vc
-class VisualStudio:
+class VisualStudio(object):
"""
An abstract base class for trying to find installed versions of
Visual Studio.
@@ -385,9 +385,9 @@ def get_vs_by_version(msvs):
global SupportedVSMap
debug('vs.py:get_vs_by_version()')
- if not SupportedVSMap.has_key(msvs):
+ if msvs not in SupportedVSMap:
msg = "Visual Studio version %s is not supported" % repr(msvs)
- raise SCons.Errors.UserError, msg
+ raise SCons.Errors.UserError(msg)
get_installed_visual_studios()
vs = InstalledVSMap.get(msvs)
debug('InstalledVSMap:%s'%InstalledVSMap)
@@ -415,15 +415,13 @@ def get_default_version(env):
version: str
the default version.
"""
- if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
- # TODO(1.5):
- #versions = [vs.version for vs in get_installed_visual_studios()]
- versions = map(lambda vs: vs.version, get_installed_visual_studios())
+ if 'MSVS' not in env or not SCons.Util.is_Dict(env['MSVS']):
+ versions = [vs.version for vs in get_installed_visual_studios()]
env['MSVS'] = {'VERSIONS' : versions}
else:
versions = env['MSVS'].get('VERSIONS', [])
- if not env.has_key('MSVS_VERSION'):
+ if 'MSVS_VERSION' not in env:
if versions:
env['MSVS_VERSION'] = versions[0] #use highest version by default
else:
@@ -451,7 +449,7 @@ def get_default_arch(env):
arch = 'x86'
elif not arch in msvs.get_supported_arch():
fmt = "Visual Studio version %s does not support architecture %s"
- raise SCons.Errors.UserError, fmt % (env['MSVS_VERSION'], arch)
+ raise SCons.Errors.UserError(fmt % (env['MSVS_VERSION'], arch))
return arch
@@ -473,11 +471,15 @@ def msvs_setup_env(env):
vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE')
msvs_list = get_installed_visual_studios()
- # TODO(1.5):
- #vscommonvarnames = [ vs.common_tools_var for vs in msvs_list ]
- vscommonvarnames = map(lambda vs: vs.common_tools_var, msvs_list)
- nenv = normalize_env(env['ENV'], vscommonvarnames + ['COMSPEC'])
- output = get_output(batfilename, arch, env=nenv)
+ vscommonvarnames = [vs.common_tools_var for vs in msvs_list]
+ save_ENV = env['ENV']
+ nenv = normalize_env(env['ENV'],
+ ['COMSPEC'] + vscommonvarnames,
+ force=True)
+ try:
+ output = get_output(batfilename, arch, env=nenv)
+ finally:
+ env['ENV'] = save_ENV
vars = parse_output(output, vars)
for k, v in vars.items():
@@ -487,9 +489,7 @@ def query_versions():
"""Query the system to get available versions of VS. A version is
considered when a batfile is found."""
msvs_list = get_installed_visual_studios()
- # TODO(1.5)
- #versions = [ msvs.version for msvs in msvs_list ]
- versions = map(lambda msvs: msvs.version, msvs_list)
+ versions = [msvs.version for msvs in msvs_list]
return versions
# Local Variables:
diff --git a/src/engine/SCons/Tool/Perforce.py b/src/engine/SCons/Tool/Perforce.py
index 08da75b..43d9f6e 100644
--- a/src/engine/SCons/Tool/Perforce.py
+++ b/src/engine/SCons/Tool/Perforce.py
@@ -8,7 +8,6 @@ selection method.
"""
-#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -29,9 +28,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/Perforce.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/Perforce.py 5023 2010/06/14 22:05:46 scons"
import os
@@ -44,7 +42,6 @@ import SCons.Util
from SCons.Tool.PharLapCommon import addPathIfNotExists
-
# Variables that we want to import from the base OS environment.
_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD',
'P4CHARSET', 'P4LANGUAGE', 'SystemRoot' ]
@@ -57,6 +54,8 @@ def generate(env):
def PerforceFactory(env=env):
""" """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The Perforce() factory is deprecated and there is no replacement.""")
return SCons.Builder.Builder(action = PerforceAction, env = env)
#setattr(env, 'Perforce', PerforceFactory)
diff --git a/src/engine/SCons/Tool/PharLapCommon.py b/src/engine/SCons/Tool/PharLapCommon.py
index 2cfb02a..64dd02f 100644
--- a/src/engine/SCons/Tool/PharLapCommon.py
+++ b/src/engine/SCons/Tool/PharLapCommon.py
@@ -29,14 +29,13 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
import SCons.Errors
import SCons.Util
import re
-import string
def getPharLapPath():
"""Reads the registry to find the installed path of the Phar Lap ETS
@@ -46,7 +45,7 @@ def getPharLapPath():
be found."""
if not SCons.Util.can_read_reg:
- raise SCons.Errors.InternalError, "No Windows registry module was found"
+ raise SCons.Errors.InternalError("No Windows registry module was found")
try:
k=SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
'SOFTWARE\\Pharlap\\ETS')
@@ -62,7 +61,7 @@ def getPharLapPath():
return os.path.normpath(val)
except SCons.Util.RegError:
- raise SCons.Errors.UserError, "Cannot find Phar Lap ETS path in the registry. Is it installed properly?"
+ raise SCons.Errors.UserError("Cannot find Phar Lap ETS path in the registry. Is it installed properly?")
REGEX_ETS_VER = re.compile(r'#define\s+ETS_VER\s+([0-9]+)')
@@ -79,7 +78,7 @@ def getPharLapVersion():
include_path = os.path.join(getPharLapPath(), os.path.normpath("include/embkern.h"))
if not os.path.exists(include_path):
- raise SCons.Errors.UserError, "Cannot find embkern.h in ETS include directory.\nIs Phar Lap ETS installed properly?"
+ raise SCons.Errors.UserError("Cannot find embkern.h in ETS include directory.\nIs Phar Lap ETS installed properly?")
mo = REGEX_ETS_VER.search(open(include_path, 'r').read())
if mo:
return int(mo.group(1))
@@ -97,14 +96,14 @@ def addPathIfNotExists(env_dict, key, path, sep=os.pathsep):
is_list = 1
paths = env_dict[key]
if not SCons.Util.is_List(env_dict[key]):
- paths = string.split(paths, sep)
+ paths = paths.split(sep)
is_list = 0
- if not os.path.normcase(path) in map(os.path.normcase, paths):
+ if os.path.normcase(path) not in list(map(os.path.normcase, paths)):
paths = [ path ] + paths
if is_list:
env_dict[key] = paths
else:
- env_dict[key] = string.join(paths, sep)
+ env_dict[key] = sep.join(paths)
except KeyError:
env_dict[key] = path
diff --git a/src/engine/SCons/Tool/PharLapCommonTests.py b/src/engine/SCons/Tool/PharLapCommonTests.py
index bde9835..70b7e69 100644
--- a/src/engine/SCons/Tool/PharLapCommonTests.py
+++ b/src/engine/SCons/Tool/PharLapCommonTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/PharLapCommonTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/PharLapCommonTests.py 5023 2010/06/14 22:05:46 scons"
import unittest
import os.path
diff --git a/src/engine/SCons/Tool/RCS.py b/src/engine/SCons/Tool/RCS.py
index 4d14af7..5c5a6bd 100644
--- a/src/engine/SCons/Tool/RCS.py
+++ b/src/engine/SCons/Tool/RCS.py
@@ -8,7 +8,6 @@ selection method.
"""
-#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -29,9 +28,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/RCS.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/RCS.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
@@ -43,6 +41,8 @@ def generate(env):
def RCSFactory(env=env):
""" """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The RCS() factory is deprecated and there is no replacement.""")
act = SCons.Action.Action('$RCS_COCOM', '$RCS_COCOMSTR')
return SCons.Builder.Builder(action = act, env = env)
diff --git a/src/engine/SCons/Tool/SCCS.py b/src/engine/SCons/Tool/SCCS.py
index 2893291..2983b83 100644
--- a/src/engine/SCons/Tool/SCCS.py
+++ b/src/engine/SCons/Tool/SCCS.py
@@ -8,7 +8,6 @@ selection method.
"""
-#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -29,9 +28,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/SCCS.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/SCCS.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
@@ -43,6 +41,8 @@ def generate(env):
def SCCSFactory(env=env):
""" """
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The SCCS() factory is deprecated and there is no replacement.""")
act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR')
return SCons.Builder.Builder(action = act, env = env)
diff --git a/src/engine/SCons/Tool/Subversion.py b/src/engine/SCons/Tool/Subversion.py
index 51a670a..26ff700 100644
--- a/src/engine/SCons/Tool/Subversion.py
+++ b/src/engine/SCons/Tool/Subversion.py
@@ -8,7 +8,6 @@ selection method.
"""
-#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
@@ -29,9 +28,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/Subversion.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/Subversion.py 5023 2010/06/14 22:05:46 scons"
import os.path
@@ -46,6 +44,8 @@ def generate(env):
def SubversionFactory(repos, module='', env=env):
""" """
# fail if repos is not an absolute path name?
+ import SCons.Warnings as W
+ W.warn(W.DeprecatedSourceCodeWarning, """The Subversion() factory is deprecated and there is no replacement.""")
if module != '':
module = os.path.join(module, '')
act = SCons.Action.Action('$SVNCOM', '$SVNCOMSTR')
diff --git a/src/engine/SCons/Tool/ToolTests.py b/src/engine/SCons/Tool/ToolTests.py
index f2a0964..ea9b475 100644
--- a/src/engine/SCons/Tool/ToolTests.py
+++ b/src/engine/SCons/Tool/ToolTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ToolTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ToolTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -32,7 +32,7 @@ import SCons.Tool
class ToolTestCase(unittest.TestCase):
def test_Tool(self):
"""Test the Tool() function"""
- class Environment:
+ class Environment(object):
def __init__(self):
self.dict = {}
def Detect(self, progs):
@@ -45,8 +45,10 @@ class ToolTestCase(unittest.TestCase):
return self.dict[key]
def __setitem__(self, key, val):
self.dict[key] = val
+ def __contains__(self, key):
+ return self.dict.__contains__(key)
def has_key(self, key):
- return self.dict.has_key(key)
+ return key in self.dict
env = Environment()
env['BUILDERS'] = {}
env['ENV'] = {}
diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py
index 4a41a8c..e38d85f 100644
--- a/src/engine/SCons/Tool/__init__.py
+++ b/src/engine/SCons/Tool/__init__.py
@@ -34,9 +34,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/__init__.py 5023 2010/06/14 22:05:46 scons"
import imp
import sys
@@ -85,7 +84,7 @@ for suffix in LaTeXSuffixes:
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner)
-class Tool:
+class Tool(object):
def __init__(self, name, toolpath=[], **kw):
self.name = name
self.toolpath = toolpath + DefaultToolpath
@@ -113,7 +112,7 @@ class Tool:
file.close()
except ImportError, e:
if str(e)!="No module named %s"%self.name:
- raise SCons.Errors.EnvironmentError, e
+ raise SCons.Errors.EnvironmentError(e)
try:
import zipimport
except ImportError:
@@ -143,7 +142,7 @@ class Tool:
return module
except ImportError, e:
if str(e)!="No module named %s"%self.name:
- raise SCons.Errors.EnvironmentError, e
+ raise SCons.Errors.EnvironmentError(e)
try:
import zipimport
importer = zipimport.zipimporter( sys.modules['SCons.Tool'].__path__[0] )
@@ -152,10 +151,10 @@ class Tool:
return module
except ImportError, e:
m = "No tool named '%s': %s" % (self.name, e)
- raise SCons.Errors.EnvironmentError, m
+ raise SCons.Errors.EnvironmentError(m)
except ImportError, e:
m = "No tool named '%s': %s" % (self.name, e)
- raise SCons.Errors.EnvironmentError, m
+ raise SCons.Errors.EnvironmentError(m)
def __call__(self, env, *args, **kw):
if self.init_kw is not None:
@@ -170,7 +169,7 @@ class Tool:
env.Append(TOOLS = [ self.name ])
if hasattr(self, 'options'):
import SCons.Variables
- if not env.has_key('options'):
+ if 'options' not in env:
from SCons.Script import ARGUMENTS
env['options']=SCons.Variables.Variables(args=ARGUMENTS)
opts=env['options']
@@ -178,7 +177,7 @@ class Tool:
self.options(opts)
opts.Update(env)
- apply(self.generate, ( env, ) + args, kw)
+ self.generate(env, *args, **kw)
def __str__(self):
return self.name
@@ -428,7 +427,7 @@ def CreateJavaFileBuilder(env):
env['JAVASUFFIX'] = '.java'
return java_file
-class ToolInitializerMethod:
+class ToolInitializerMethod(object):
"""
This is added to a construction environment in place of a
method(s) normally called for a Builder (env.Object, env.StaticObject,
@@ -474,9 +473,9 @@ class ToolInitializerMethod:
builder = self.get_builder(env)
if builder is None:
return [], []
- return apply(builder, args, kw)
+ return builder(*args, **kw)
-class ToolInitializer:
+class ToolInitializer(object):
"""
A class for delayed initialization of Tools modules.
@@ -530,9 +529,9 @@ class ToolInitializer:
def Initializers(env):
ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
def Install(self, *args, **kw):
- return apply(self._InternalInstall, args, kw)
+ return self._InternalInstall(*args, **kw)
def InstallAs(self, *args, **kw):
- return apply(self._InternalInstallAs, args, kw)
+ return self._InternalInstallAs(*args, **kw)
env.AddMethod(Install)
env.AddMethod(InstallAs)
@@ -546,7 +545,7 @@ def FindTool(tools, env):
def FindAllTools(tools, env):
def ToolExists(tool, env=env):
return Tool(tool).exists(env)
- return filter (ToolExists, tools)
+ return list(filter (ToolExists, tools))
def tool_list(platform, env):
@@ -646,27 +645,34 @@ def tool_list(platform, env):
fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0]
ar = FindTool(ars, env) or ars[0]
- other_tools = FindAllTools(['BitKeeper', 'CVS',
- 'dmd',
- 'filesystem',
- 'dvipdf', 'dvips', 'gs',
- 'jar', 'javac', 'javah',
- 'latex', 'lex',
- 'm4', #'midl', 'msvs',
- 'pdflatex', 'pdftex', 'Perforce',
- 'RCS', 'rmic', 'rpcgen',
- 'SCCS',
- # 'Subversion',
- 'swig',
- 'tar', 'tex',
- 'yacc', 'zip', 'rpm', 'wix']+other_plat_tools,
- env)
+ other_tools = FindAllTools(other_plat_tools + [
+ 'dmd',
+ #TODO: merge 'install' into 'filesystem' and
+ # make 'filesystem' the default
+ 'filesystem',
+ 'm4',
+ 'wix', #'midl', 'msvs',
+ # Parser generators
+ 'lex', 'yacc',
+ # Foreign function interface
+ 'rpcgen', 'swig',
+ # Java
+ 'jar', 'javac', 'javah', 'rmic',
+ # TeX
+ 'dvipdf', 'dvips', 'gs',
+ 'tex', 'latex', 'pdflatex', 'pdftex',
+ # Archivers
+ 'tar', 'zip', 'rpm',
+ # SourceCode factories
+ 'BitKeeper', 'CVS', 'Perforce',
+ 'RCS', 'SCCS', # 'Subversion',
+ ], env)
tools = ([linker, c_compiler, cxx_compiler,
fortran_compiler, assembler, ar]
+ other_tools)
- return filter(lambda x: x, tools)
+ return [x for x in tools if x]
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/__init__.xml b/src/engine/SCons/Tool/__init__.xml
index 093ca0c..a8a8507 100644
--- a/src/engine/SCons/Tool/__init__.xml
+++ b/src/engine/SCons/Tool/__init__.xml
@@ -209,7 +209,7 @@ according to the suffix mappings in the
<literal>SourceFileScanner</literal>
object.
See the section "Scanner Objects,"
-below, for a more information.
+below, for more information.
</summary>
</builder>
@@ -305,7 +305,7 @@ according to the suffix mappings in
<literal>SourceFileScanner</literal>
object.
See the section "Scanner Objects,"
-below, for a more information.
+below, for more information.
</summary>
</builder>
diff --git a/src/engine/SCons/Tool/aixc++.py b/src/engine/SCons/Tool/aixc++.py
index 035ece4..62c5ef7 100644
--- a/src/engine/SCons/Tool/aixc++.py
+++ b/src/engine/SCons/Tool/aixc++.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/aixc++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/aixc++.py 5023 2010/06/14 22:05:46 scons"
import os.path
diff --git a/src/engine/SCons/Tool/aixcc.py b/src/engine/SCons/Tool/aixcc.py
index 1c6ae14..bf1de34 100644
--- a/src/engine/SCons/Tool/aixcc.py
+++ b/src/engine/SCons/Tool/aixcc.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/aixcc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/aixcc.py 5023 2010/06/14 22:05:46 scons"
import os.path
diff --git a/src/engine/SCons/Tool/aixf77.py b/src/engine/SCons/Tool/aixf77.py
index a5a9d8c..f680247 100644
--- a/src/engine/SCons/Tool/aixf77.py
+++ b/src/engine/SCons/Tool/aixf77.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/aixf77.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/aixf77.py 5023 2010/06/14 22:05:46 scons"
import os.path
diff --git a/src/engine/SCons/Tool/aixlink.py b/src/engine/SCons/Tool/aixlink.py
index 0e1b974..9531a4b 100644
--- a/src/engine/SCons/Tool/aixlink.py
+++ b/src/engine/SCons/Tool/aixlink.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/aixlink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/aixlink.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py
index a56462d..4b3ae77 100644
--- a/src/engine/SCons/Tool/applelink.py
+++ b/src/engine/SCons/Tool/applelink.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/applelink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/applelink.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/ar.py b/src/engine/SCons/Tool/ar.py
index b0ae76b..68effb1 100644
--- a/src/engine/SCons/Tool/ar.py
+++ b/src/engine/SCons/Tool/ar.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ar.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ar.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/as.py b/src/engine/SCons/Tool/as.py
index bdd00db..f18ff57 100644
--- a/src/engine/SCons/Tool/as.py
+++ b/src/engine/SCons/Tool/as.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/as.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/as.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/bcc32.py b/src/engine/SCons/Tool/bcc32.py
index 67325d0..b7c7bf2 100644
--- a/src/engine/SCons/Tool/bcc32.py
+++ b/src/engine/SCons/Tool/bcc32.py
@@ -27,11 +27,10 @@ XXX
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/bcc32.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/bcc32.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
-import string
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/c++.py b/src/engine/SCons/Tool/c++.py
index d74cd96..907324d 100644
--- a/src/engine/SCons/Tool/c++.py
+++ b/src/engine/SCons/Tool/c++.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/c++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/c++.py 5023 2010/06/14 22:05:46 scons"
import os.path
diff --git a/src/engine/SCons/Tool/cc.py b/src/engine/SCons/Tool/cc.py
index c565225..c3a6b92 100644
--- a/src/engine/SCons/Tool/cc.py
+++ b/src/engine/SCons/Tool/cc.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/cc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/cc.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool
import SCons.Defaults
@@ -45,7 +45,7 @@ def add_common_cc_variables(env):
Add underlying common "C compiler" variables that
are used by multiple tools (specifically, c++).
"""
- if not env.has_key('_CCCOMCOM'):
+ if '_CCCOMCOM' not in env:
env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
# It's a hack to test for darwin here, but the alternative
# of creating an applecc.py to contain this seems overkill.
@@ -56,10 +56,10 @@ def add_common_cc_variables(env):
if env['PLATFORM'] == 'darwin':
env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH'
- if not env.has_key('CCFLAGS'):
+ if 'CCFLAGS' not in env:
env['CCFLAGS'] = SCons.Util.CLVar('')
- if not env.has_key('SHCCFLAGS'):
+ if 'SHCCFLAGS' not in env:
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
def generate(env):
@@ -73,18 +73,6 @@ def generate(env):
shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
-#<<<<<<< .working
-#
-# env['_CCCOMCOM'] = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS'
-# # It's a hack to test for darwin here, but the alternative of creating
-# # an applecc.py to contain this seems overkill. Maybe someday the Apple
-# # platform will require more setup and this logic will be moved.
-# env['FRAMEWORKS'] = SCons.Util.CLVar('')
-# env['FRAMEWORKPATH'] = SCons.Util.CLVar('')
-# if env['PLATFORM'] == 'darwin':
-# env['_CCCOMCOM'] = env['_CCCOMCOM'] + ' $_FRAMEWORKPATH'
-#=======
-#>>>>>>> .merge-right.r1907
add_common_cc_variables(env)
diff --git a/src/engine/SCons/Tool/cvf.py b/src/engine/SCons/Tool/cvf.py
index 7930a38..4860241 100644
--- a/src/engine/SCons/Tool/cvf.py
+++ b/src/engine/SCons/Tool/cvf.py
@@ -27,7 +27,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/cvf.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/cvf.py 5023 2010/06/14 22:05:46 scons"
import fortran
diff --git a/src/engine/SCons/Tool/default.py b/src/engine/SCons/Tool/default.py
index b477c7b..a2883d7 100644
--- a/src/engine/SCons/Tool/default.py
+++ b/src/engine/SCons/Tool/default.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/default.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/default.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool
diff --git a/src/engine/SCons/Tool/dmd.py b/src/engine/SCons/Tool/dmd.py
index d5dc5c1..a269354 100644
--- a/src/engine/SCons/Tool/dmd.py
+++ b/src/engine/SCons/Tool/dmd.py
@@ -54,10 +54,9 @@ Lib tool variables:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/dmd.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/dmd.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import SCons.Action
import SCons.Builder
@@ -112,7 +111,7 @@ def generate(env):
# This is merely for the convenience of the dependency scanner.
dmd_path = env.WhereIs(dc)
if dmd_path:
- x = string.rindex(dmd_path, dc)
+ x = dmd_path.rindex(dc)
phobosDir = dmd_path[:x] + '/../src/phobos'
if os.path.isdir(phobosDir):
env.Append(DPATH = [phobosDir])
diff --git a/src/engine/SCons/Tool/dvi.py b/src/engine/SCons/Tool/dvi.py
index ce91cca..7eb9de4 100644
--- a/src/engine/SCons/Tool/dvi.py
+++ b/src/engine/SCons/Tool/dvi.py
@@ -27,7 +27,7 @@ Common DVI Builder definition for various other Tool modules that use it.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/dvi.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/dvi.py 5023 2010/06/14 22:05:46 scons"
import SCons.Builder
import SCons.Tool
diff --git a/src/engine/SCons/Tool/dvipdf.py b/src/engine/SCons/Tool/dvipdf.py
index cf6909d..1b352b3 100644
--- a/src/engine/SCons/Tool/dvipdf.py
+++ b/src/engine/SCons/Tool/dvipdf.py
@@ -29,9 +29,8 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/dvipdf.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/dvipdf.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Defaults
@@ -88,7 +87,7 @@ def PDFEmitter(target, source, env):
"""
def strip_suffixes(n):
return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log']
- source = filter(strip_suffixes, source)
+ source = list(filter(strip_suffixes, source))
return (target, source)
def generate(env):
diff --git a/src/engine/SCons/Tool/dvips.py b/src/engine/SCons/Tool/dvips.py
index be8a5fe..d6e7006 100644
--- a/src/engine/SCons/Tool/dvips.py
+++ b/src/engine/SCons/Tool/dvips.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/dvips.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/dvips.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
diff --git a/src/engine/SCons/Tool/f77.py b/src/engine/SCons/Tool/f77.py
index 17e7b6e..d4ec887 100644
--- a/src/engine/SCons/Tool/f77.py
+++ b/src/engine/SCons/Tool/f77.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/f77.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/f77.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Scanner.Fortran
diff --git a/src/engine/SCons/Tool/f90.py b/src/engine/SCons/Tool/f90.py
index 8db5824..b8829b7 100644
--- a/src/engine/SCons/Tool/f90.py
+++ b/src/engine/SCons/Tool/f90.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/f90.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/f90.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Scanner.Fortran
diff --git a/src/engine/SCons/Tool/f95.py b/src/engine/SCons/Tool/f95.py
index fc00566..66be308 100644
--- a/src/engine/SCons/Tool/f95.py
+++ b/src/engine/SCons/Tool/f95.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/f95.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/f95.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/filesystem.py b/src/engine/SCons/Tool/filesystem.py
index c015390..6bceb14 100644
--- a/src/engine/SCons/Tool/filesystem.py
+++ b/src/engine/SCons/Tool/filesystem.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/filesystem.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/filesystem.py 5023 2010/06/14 22:05:46 scons"
import SCons
from SCons.Tool.install import copyFunc
@@ -44,12 +44,12 @@ def copyto_emitter(target, source, env):
n_target = []
for t in target:
- n_target = n_target + map( lambda s, t=t: t.File( str( s ) ), source )
+ n_target = n_target + [t.File( str( s ) ) for s in source]
return (n_target, source)
def copy_action_func(target, source, env):
- assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(map(str, target),map(str, source))
+ assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(map(str, source)))
for t, s in zip(target, source):
if copyFunc(t.get_path(), s.get_path(), env):
diff --git a/src/engine/SCons/Tool/fortran.py b/src/engine/SCons/Tool/fortran.py
index fea2660..f7b4e8d 100644
--- a/src/engine/SCons/Tool/fortran.py
+++ b/src/engine/SCons/Tool/fortran.py
@@ -31,10 +31,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/fortran.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/fortran.py 5023 2010/06/14 22:05:46 scons"
import re
-import string
import SCons.Action
import SCons.Defaults
diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py
index 019939a..fa93329 100644
--- a/src/engine/SCons/Tool/g++.py
+++ b/src/engine/SCons/Tool/g++.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/g++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/g++.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
diff --git a/src/engine/SCons/Tool/g77.py b/src/engine/SCons/Tool/g77.py
index 3b50b6d..c21f34b 100644
--- a/src/engine/SCons/Tool/g77.py
+++ b/src/engine/SCons/Tool/g77.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/g77.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/g77.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env
diff --git a/src/engine/SCons/Tool/gas.py b/src/engine/SCons/Tool/gas.py
index 52255ab..0ec021a 100644
--- a/src/engine/SCons/Tool/gas.py
+++ b/src/engine/SCons/Tool/gas.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/gas.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/gas.py 5023 2010/06/14 22:05:46 scons"
as_module = __import__('as', globals(), locals(), [])
diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py
index 5994854..5d1a7d5 100644
--- a/src/engine/SCons/Tool/gcc.py
+++ b/src/engine/SCons/Tool/gcc.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/gcc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/gcc.py 5023 2010/06/14 22:05:46 scons"
import cc
import os
diff --git a/src/engine/SCons/Tool/gfortran.py b/src/engine/SCons/Tool/gfortran.py
index 863e82a..2a3872e 100644
--- a/src/engine/SCons/Tool/gfortran.py
+++ b/src/engine/SCons/Tool/gfortran.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/gfortran.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/gfortran.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py
index 71071f1..9845a69 100644
--- a/src/engine/SCons/Tool/gnulink.py
+++ b/src/engine/SCons/Tool/gnulink.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/gnulink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/gnulink.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/gs.py b/src/engine/SCons/Tool/gs.py
index 0e6deef..8ab63d7 100644
--- a/src/engine/SCons/Tool/gs.py
+++ b/src/engine/SCons/Tool/gs.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/gs.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/gs.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Platform
@@ -69,7 +69,7 @@ def generate(env):
def exists(env):
- if env.has_key('PS2PDF'):
+ if 'PS2PDF' in env:
return env.Detect(env['PS2PDF'])
else:
return env.Detect(gs) or SCons.Util.WhereIs(gs)
diff --git a/src/engine/SCons/Tool/hpc++.py b/src/engine/SCons/Tool/hpc++.py
index 28d766f..5be3854 100644
--- a/src/engine/SCons/Tool/hpc++.py
+++ b/src/engine/SCons/Tool/hpc++.py
@@ -31,10 +31,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/hpc++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/hpc++.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import SCons.Util
@@ -67,8 +66,8 @@ def generate(env):
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS +Z')
# determine version of aCC
line = os.popen(acc + ' -V 2>&1').readline().rstrip()
- if string.find(line, 'aCC: HP ANSI C++') == 0:
- env['CXXVERSION'] = string.split(line)[-1]
+ if line.find('aCC: HP ANSI C++') == 0:
+ env['CXXVERSION'] = line.split()[-1]
if env['PLATFORM'] == 'cygwin':
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
diff --git a/src/engine/SCons/Tool/hpcc.py b/src/engine/SCons/Tool/hpcc.py
index f2ab04f..24b48c7 100644
--- a/src/engine/SCons/Tool/hpcc.py
+++ b/src/engine/SCons/Tool/hpcc.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/hpcc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/hpcc.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/hplink.py b/src/engine/SCons/Tool/hplink.py
index f6eff45..b2ad1ca 100644
--- a/src/engine/SCons/Tool/hplink.py
+++ b/src/engine/SCons/Tool/hplink.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/hplink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/hplink.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
diff --git a/src/engine/SCons/Tool/icc.py b/src/engine/SCons/Tool/icc.py
index 0d4e617..fd5affe 100644
--- a/src/engine/SCons/Tool/icc.py
+++ b/src/engine/SCons/Tool/icc.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/icc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/icc.py 5023 2010/06/14 22:05:46 scons"
import cc
diff --git a/src/engine/SCons/Tool/icl.py b/src/engine/SCons/Tool/icl.py
index ce98156..f1da778 100644
--- a/src/engine/SCons/Tool/icl.py
+++ b/src/engine/SCons/Tool/icl.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/icl.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/icl.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool.intelc
@@ -40,10 +40,10 @@ import SCons.Tool.intelc
def generate(*args, **kw):
"""Add Builders and construction variables for icl to an Environment."""
- return apply(SCons.Tool.intelc.generate, args, kw)
+ return SCons.Tool.intelc.generate(*args, **kw)
def exists(*args, **kw):
- return apply(SCons.Tool.intelc.exists, args, kw)
+ return SCons.Tool.intelc.exists(*args, **kw)
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Tool/ifl.py b/src/engine/SCons/Tool/ifl.py
index 93dc977..17ceb34 100644
--- a/src/engine/SCons/Tool/ifl.py
+++ b/src/engine/SCons/Tool/ifl.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ifl.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ifl.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
from SCons.Scanner.Fortran import FortranScan
@@ -43,12 +43,12 @@ def generate(env):
SCons.Tool.SourceFileScanner.add_scanner('.i', fscan)
SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan)
- if not env.has_key('FORTRANFILESUFFIXES'):
+ if 'FORTRANFILESUFFIXES' not in env:
env['FORTRANFILESUFFIXES'] = ['.i']
else:
env['FORTRANFILESUFFIXES'].append('.i')
- if not env.has_key('F90FILESUFFIXES'):
+ if 'F90FILESUFFIXES' not in env:
env['F90FILESUFFIXES'] = ['.i90']
else:
env['F90FILESUFFIXES'].append('.i90')
diff --git a/src/engine/SCons/Tool/ifort.py b/src/engine/SCons/Tool/ifort.py
index 047afba..06bf484 100644
--- a/src/engine/SCons/Tool/ifort.py
+++ b/src/engine/SCons/Tool/ifort.py
@@ -32,9 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ifort.py 4720 2010/03/24 03:14:11 jars"
-
-import string
+__revision__ = "src/engine/SCons/Tool/ifort.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
from SCons.Scanner.Fortran import FortranScan
@@ -48,12 +46,12 @@ def generate(env):
SCons.Tool.SourceFileScanner.add_scanner('.i', fscan)
SCons.Tool.SourceFileScanner.add_scanner('.i90', fscan)
- if not env.has_key('FORTRANFILESUFFIXES'):
+ if 'FORTRANFILESUFFIXES' not in env:
env['FORTRANFILESUFFIXES'] = ['.i']
else:
env['FORTRANFILESUFFIXES'].append('.i')
- if not env.has_key('F90FILESUFFIXES'):
+ if 'F90FILESUFFIXES' not in env:
env['F90FILESUFFIXES'] = ['.i90']
else:
env['F90FILESUFFIXES'].append('.i90')
@@ -75,7 +73,7 @@ def generate(env):
for dialect in ['F77', 'F90', 'FORTRAN', 'F95']:
for var in ['%sCOM' % dialect, '%sPPCOM' % dialect,
'SH%sCOM' % dialect, 'SH%sPPCOM' % dialect]:
- env[var] = string.replace(env[var], '-o $TARGET', '-object:$TARGET')
+ env[var] = env[var].replace('-o $TARGET', '-object:$TARGET')
env['FORTRANMODDIRPREFIX'] = "/module:"
else:
env['FORTRANMODDIRPREFIX'] = "-module "
diff --git a/src/engine/SCons/Tool/ilink.py b/src/engine/SCons/Tool/ilink.py
index 4d8395f..71025d1 100644
--- a/src/engine/SCons/Tool/ilink.py
+++ b/src/engine/SCons/Tool/ilink.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ilink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ilink.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/ilink32.py b/src/engine/SCons/Tool/ilink32.py
index 1765193..fb570f8 100644
--- a/src/engine/SCons/Tool/ilink32.py
+++ b/src/engine/SCons/Tool/ilink32.py
@@ -27,7 +27,7 @@ XXX
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ilink32.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ilink32.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool
import SCons.Tool.bcc32
diff --git a/src/engine/SCons/Tool/install.py b/src/engine/SCons/Tool/install.py
index 0d7b9d5..7b61bde 100644
--- a/src/engine/SCons/Tool/install.py
+++ b/src/engine/SCons/Tool/install.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/install.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/install.py 5023 2010/06/14 22:05:46 scons"
import os
import shutil
@@ -54,7 +54,7 @@ def copyFunc(dest, source, env):
if os.path.isdir(source):
if os.path.exists(dest):
if not os.path.isdir(dest):
- raise SCons.Errors.UserError, "cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source))
+ raise SCons.Errors.UserError("cannot overwrite non-directory `%s' with a directory `%s'" % (str(dest), str(source)))
else:
parent = os.path.split(dest)[0]
if not os.path.exists(parent):
@@ -76,7 +76,7 @@ def installFunc(target, source, env):
raise SCons.Errors.UserError('Missing INSTALL construction variable.')
assert len(target)==len(source), \
- "Installing source %s into target %s: target and source lists must have same length."%(map(str, source), map(str, target))
+ "Installing source %s into target %s: target and source lists must have same length."%(list(map(str, source)), list(map(str, target)))
for t,s in zip(target,source):
if install(t.get_path(),s.get_path(),env):
return 1
@@ -108,7 +108,7 @@ def add_targets_to_INSTALLED_FILES(target, source, env):
_UNIQUE_INSTALLED_FILES = None
return (target, source)
-class DESTDIR_factory:
+class DESTDIR_factory(object):
""" a node factory, where all files will be relative to the dir supplied
in the constructor.
"""
@@ -135,7 +135,7 @@ BaseInstallBuilder = None
def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
if target and dir:
import SCons.Errors
- raise SCons.Errors.UserError, "Both target and dir defined for Install(), only one may be defined."
+ raise SCons.Errors.UserError("Both target and dir defined for Install(), only one may be defined.")
if not dir:
dir=target
@@ -149,7 +149,7 @@ def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
try:
dnodes = env.arg2nodes(dir, target_factory.Dir)
except TypeError:
- raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir)
+ raise SCons.Errors.UserError("Target `%s' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?" % str(dir))
sources = env.arg2nodes(source, env.fs.Entry)
tgt = []
for dnode in dnodes:
@@ -159,14 +159,14 @@ def InstallBuilderWrapper(env, target=None, source=None, dir=None, **kw):
# be relative to the top-level SConstruct directory.
target = env.fs.Entry('.'+os.sep+src.name, dnode)
#tgt.extend(BaseInstallBuilder(env, target, src, **kw))
- tgt.extend(apply(BaseInstallBuilder, (env, target, src), kw))
+ tgt.extend(BaseInstallBuilder(env, target, src, **kw))
return tgt
def InstallAsBuilderWrapper(env, target=None, source=None, **kw):
result = []
for src, tgt in map(lambda x, y: (x, y), source, target):
#result.extend(BaseInstallBuilder(env, tgt, src, **kw))
- result.extend(apply(BaseInstallBuilder, (env, tgt, src), kw))
+ result.extend(BaseInstallBuilder(env, tgt, src, **kw))
return result
added = None
diff --git a/src/engine/SCons/Tool/intelc.py b/src/engine/SCons/Tool/intelc.py
index a9b23d3..10e92cd 100644
--- a/src/engine/SCons/Tool/intelc.py
+++ b/src/engine/SCons/Tool/intelc.py
@@ -30,15 +30,15 @@ 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__ = "src/engine/SCons/Tool/intelc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/intelc.py 5023 2010/06/14 22:05:46 scons"
import math, sys, os.path, glob, string, re
is_windows = sys.platform == 'win32'
is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or
- (os.environ.has_key('PROCESSOR_ARCHITEW6432') and
+ ('PROCESSOR_ARCHITEW6432' in os.environ and
os.environ['PROCESSOR_ARCHITEW6432'] == 'AMD64'))
is_linux = sys.platform == 'linux2'
is_mac = sys.platform == 'darwin'
@@ -69,7 +69,7 @@ def uniquify(s):
u = {}
for x in s:
u[x] = 1
- return u.keys()
+ return list(u.keys())
def linux_ver_normalize(vstr):
"""Normalize a Linux compiler version number.
@@ -81,7 +81,7 @@ def linux_ver_normalize(vstr):
m = re.match(r'([0-9]+)\.([0-9]+)\.([0-9]+)', vstr)
if m:
vmaj,vmin,build = m.groups()
- return float(vmaj) * 10 + float(vmin) + float(build) / 1000.;
+ return float(vmaj) * 10. + float(vmin) + float(build) / 1000.;
else:
f = float(vstr)
if is_windows:
@@ -117,9 +117,8 @@ def check_abi(abi):
try:
abi = valid_abis[abi]
except KeyError:
- raise SCons.Errors.UserError, \
- "Intel compiler: Invalid ABI %s, valid values are %s"% \
- (abi, valid_abis.keys())
+ raise SCons.Errors.UserError("Intel compiler: Invalid ABI %s, valid values are %s"% \
+ (abi, list(valid_abis.keys())))
return abi
def vercmp(a, b):
@@ -156,16 +155,14 @@ def get_intel_registry_value(valuename, version=None, abi=None):
try:
k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE, K)
except SCons.Util.RegError:
- raise MissingRegistryError, \
- "%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi)
+ raise MissingRegistryError("%s was not found in the registry, for Intel compiler version %s, abi='%s'"%(K, version,abi))
# Get the value:
try:
v = SCons.Util.RegQueryValueEx(k, valuename)[0]
return v # or v.encode('iso-8859-1', 'replace') to remove unicode?
except SCons.Util.RegError:
- raise MissingRegistryError, \
- "%s\\%s was not found in the registry."%(K, valuename)
+ raise MissingRegistryError("%s\\%s was not found in the registry."%(K, valuename))
def get_all_compiler_versions():
@@ -243,9 +240,7 @@ def get_all_compiler_versions():
m = re.search(r'([0-9.]+)$', d)
if m:
versions.append(m.group(1))
- versions = uniquify(versions) # remove dups
- versions.sort(vercmp)
- return versions
+ return sorted(uniquify(versions)) # remove dups
def get_intel_compiler_top(version, abi):
"""
@@ -257,13 +252,12 @@ def get_intel_compiler_top(version, abi):
if is_windows:
if not SCons.Util.can_read_reg:
- raise NoRegistryModuleError, "No Windows registry module was found"
+ raise NoRegistryModuleError("No Windows registry module was found")
top = get_intel_registry_value('ProductDir', version, abi)
# pre-11, icl was in Bin. 11 and later, it's in Bin/<abi> apparently.
if not os.path.exists(os.path.join(top, "Bin", "icl.exe")) \
and not os.path.exists(os.path.join(top, "Bin", abi, "icl.exe")):
- raise MissingDirError, \
- "Can't find Intel compiler in %s"%(top)
+ raise MissingDirError("Can't find Intel compiler in %s"%(top))
elif is_mac or is_linux:
# first dir is new (>=9.0) style, second is old (8.0) style.
dirs=('/opt/intel/cc/%s', '/opt/intel_cc_%s')
@@ -275,8 +269,7 @@ def get_intel_compiler_top(version, abi):
top = d%version
break
if not top:
- raise MissingDirError, \
- "Can't find version %s Intel compiler in %s (abi='%s')"%(version,top, abi)
+ raise MissingDirError("Can't find version %s Intel compiler in %s (abi='%s')"%(version,top, abi))
return top
@@ -312,9 +305,8 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
# get_version_from_list does that mapping.
v = get_version_from_list(version, vlist)
if not v:
- raise SCons.Errors.UserError, \
- "Invalid Intel compiler version %s: "%version + \
- "installed versions are %s"%(', '.join(vlist))
+ raise SCons.Errors.UserError("Invalid Intel compiler version %s: "%version + \
+ "installed versions are %s"%(', '.join(vlist)))
version = v
# if abi is unspecified, use ia32
@@ -406,7 +398,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
# Couldn't get it from registry: use default subdir of topdir
env.PrependENVPath(p[0], os.path.join(topdir, p[2]))
else:
- env.PrependENVPath(p[0], string.split(path, os.pathsep))
+ env.PrependENVPath(p[0], path.split(os.pathsep))
# print "ICL %s: %s, final=%s"%(p[0], path, str(env['ENV'][p[0]]))
if is_windows:
@@ -445,7 +437,7 @@ def generate(env, version=None, abi=None, topdir=None, verbose=0):
for ld in [envlicdir, reglicdir]:
# If the string contains an '@', then assume it's a network
# license (port@system) and good by definition.
- if ld and (string.find(ld, '@') != -1 or os.path.exists(ld)):
+ if ld and (ld.find('@') != -1 or os.path.exists(ld)):
licdir = ld
break
if not licdir:
diff --git a/src/engine/SCons/Tool/ipkg.py b/src/engine/SCons/Tool/ipkg.py
index 3e8d223..c692053 100644
--- a/src/engine/SCons/Tool/ipkg.py
+++ b/src/engine/SCons/Tool/ipkg.py
@@ -33,10 +33,9 @@ packages fake_root.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/ipkg.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/ipkg.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import SCons.Builder
@@ -53,11 +52,8 @@ def generate(env):
env['IPKG'] = 'ipkg-build'
env['IPKGCOM'] = '$IPKG $IPKGFLAGS ${SOURCE}'
- # TODO(1.5)
- #env['IPKGUSER'] = os.popen('id -un').read().strip()
- #env['IPKGGROUP'] = os.popen('id -gn').read().strip()
- env['IPKGUSER'] = string.strip(os.popen('id -un').read())
- env['IPKGGROUP'] = string.strip(os.popen('id -gn').read())
+ env['IPKGUSER'] = os.popen('id -un').read().strip()
+ env['IPKGGROUP'] = os.popen('id -gn').read().strip()
env['IPKGFLAGS'] = SCons.Util.CLVar('-o $IPKGUSER -g $IPKGGROUP')
env['IPKGSUFFIX'] = '.ipk'
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py
index 2aaab96..9cb4eff 100644
--- a/src/engine/SCons/Tool/jar.py
+++ b/src/engine/SCons/Tool/jar.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/jar.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/jar.py 5023 2010/06/14 22:05:46 scons"
import SCons.Subst
import SCons.Util
diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py
index df237a8..66651c3 100644
--- a/src/engine/SCons/Tool/javac.py
+++ b/src/engine/SCons/Tool/javac.py
@@ -29,13 +29,11 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/javac.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/javac.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
-import string
import SCons.Action
import SCons.Builder
@@ -45,7 +43,7 @@ import SCons.Util
def classname(path):
"""Turn a string (path name) into a Java class name."""
- return string.replace(os.path.normpath(path), os.sep, '.')
+ return os.path.normpath(path).replace(os.sep, '.')
def emit_java_classes(target, source, env):
"""Create and return lists of source java files
@@ -67,27 +65,25 @@ def emit_java_classes(target, source, env):
slist = []
js = _my_normcase(java_suffix)
- find_java = lambda n, js=js, ljs=len(js): _my_normcase(n[-ljs:]) == js
for entry in source:
entry = entry.rentry().disambiguate()
if isinstance(entry, SCons.Node.FS.File):
slist.append(entry)
elif isinstance(entry, SCons.Node.FS.Dir):
result = SCons.Util.OrderedDict()
- def visit(arg, dirname, names, fj=find_java, dirnode=entry.rdir()):
- java_files = filter(fj, names)
- # The on-disk entries come back in arbitrary order. Sort
- # them so our target and source lists are determinate.
- java_files.sort()
- mydir = dirnode.Dir(dirname)
- java_paths = map(lambda f, d=mydir: d.File(f), java_files)
+ dirnode = entry.rdir()
+ def find_java_files(arg, dirpath, filenames):
+ java_files = sorted([n for n in filenames
+ if _my_normcase(n).endswith(js)])
+ mydir = dirnode.Dir(dirpath)
+ java_paths = [mydir.File(f) for f in java_files]
for jp in java_paths:
arg[jp] = True
+ for dirpath, dirnames, filenames in os.walk(dirnode.get_abspath()):
+ find_java_files(result, dirpath, filenames)
+ entry.walk(find_java_files, result)
- os.path.walk(entry.rdir().get_abspath(), visit, result)
- entry.walk(visit, result)
-
- slist.extend(result.keys())
+ slist.extend(list(result.keys()))
else:
raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__)
@@ -139,7 +135,7 @@ JavaBuilder = SCons.Builder.Builder(action = JavaAction,
target_factory = SCons.Node.FS.Entry,
source_factory = SCons.Node.FS.Entry)
-class pathopt:
+class pathopt(object):
"""
Callable object for generating javac-style path options from
a construction variable (e.g. -classpath, -sourcepath).
@@ -156,8 +152,8 @@ class pathopt:
if self.default:
path = path + [ env[self.default] ]
if path:
- return [self.opt, string.join(path, os.pathsep)]
- #return self.opt + " " + string.join(path, os.pathsep)
+ return [self.opt, os.pathsep.join(path)]
+ #return self.opt + " " + os.pathsep.join(path)
else:
return []
#return ""
@@ -194,7 +190,7 @@ def Java(env, target, source, *args, **kw):
b = env.JavaClassFile
else:
b = env.JavaClassDir
- result.extend(apply(b, (t, s) + args, kw))
+ result.extend(b(t, s, *args, **kw))
return result
diff --git a/src/engine/SCons/Tool/javah.py b/src/engine/SCons/Tool/javah.py
index 6a4314c..e92c423 100644
--- a/src/engine/SCons/Tool/javah.py
+++ b/src/engine/SCons/Tool/javah.py
@@ -31,10 +31,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/javah.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/javah.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import SCons.Action
import SCons.Builder
@@ -93,7 +92,7 @@ def emit_java_headers(target, source, env):
target[0]._morph()
tlist = []
for s in source:
- fname = string.replace(s.attributes.java_classname, '.', '_') + '.h'
+ fname = s.attributes.java_classname.replace('.', '_') + '.h'
t = target[0].File(fname)
t.attributes.java_lookupdir = target[0]
tlist.append(t)
@@ -112,7 +111,7 @@ def JavaHOutFlagGenerator(target, source, env, for_signature):
def getJavaHClassPath(env,target, source, for_signature):
path = "${SOURCE.attributes.java_classdir}"
- if env.has_key('JAVACLASSPATH') and env['JAVACLASSPATH']:
+ if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']:
path = SCons.Util.AppendPath(path, env['JAVACLASSPATH'])
return "-classpath %s" % (path)
diff --git a/src/engine/SCons/Tool/latex.py b/src/engine/SCons/Tool/latex.py
index 56db43f..e4f1a51 100644
--- a/src/engine/SCons/Tool/latex.py
+++ b/src/engine/SCons/Tool/latex.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/latex.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/latex.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Defaults
@@ -44,7 +44,7 @@ import SCons.Tool.tex
def LaTeXAuxFunction(target = None, source= None, env=None):
result = SCons.Tool.tex.InternalLaTeXAuxAction( SCons.Tool.tex.LaTeXAction, target, source, env )
if result != 0:
- print env['LATEX']," returned an error, check the log file"
+ SCons.Tool.tex.check_file_error_message(env['LATEX'])
return result
LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction,
diff --git a/src/engine/SCons/Tool/lex.py b/src/engine/SCons/Tool/lex.py
index 920ff5f..aad5004 100644
--- a/src/engine/SCons/Tool/lex.py
+++ b/src/engine/SCons/Tool/lex.py
@@ -31,12 +31,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/lex.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/lex.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
-
import SCons.Action
import SCons.Tool
import SCons.Util
@@ -62,7 +60,7 @@ def lexEmitter(target, source, env):
if option[:l] == fileGenOption:
# A file generating option is present, so add the
# file name to the target list.
- fileName = string.strip(option[l:])
+ fileName = option[l:].strip()
target.append(fileName)
return (target, source)
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index 2b6ccec..5905fe9 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/link.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/link.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py
index abf29f4..ab5b735 100644
--- a/src/engine/SCons/Tool/linkloc.py
+++ b/src/engine/SCons/Tool/linkloc.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/linkloc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/linkloc.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
@@ -61,7 +61,7 @@ def repl_linker_command(m):
# to find it with recursive substitution
return m.group(1) + '#' + m.group(2)
-class LinklocGenerator:
+class LinklocGenerator(object):
def __init__(self, cmdline):
self.cmdline = cmdline
diff --git a/src/engine/SCons/Tool/m4.py b/src/engine/SCons/Tool/m4.py
index 48935cf..f43b594 100644
--- a/src/engine/SCons/Tool/m4.py
+++ b/src/engine/SCons/Tool/m4.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/m4.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/m4.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
diff --git a/src/engine/SCons/Tool/masm.py b/src/engine/SCons/Tool/masm.py
index a4e91fc..5bb936a 100644
--- a/src/engine/SCons/Tool/masm.py
+++ b/src/engine/SCons/Tool/masm.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/masm.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/masm.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py
index f1f4375..67660d1 100644
--- a/src/engine/SCons/Tool/midl.py
+++ b/src/engine/SCons/Tool/midl.py
@@ -31,9 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/midl.py 4720 2010/03/24 03:14:11 jars"
-
-import string
+__revision__ = "src/engine/SCons/Tool/midl.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
@@ -53,10 +51,10 @@ def midl_emitter(target, source, env):
midlcom = env['MIDLCOM']
- if string.find(midlcom, '/proxy') != -1:
+ if midlcom.find('/proxy') != -1:
proxy = base + '_p.c'
t.append(proxy)
- if string.find(midlcom, '/dlldata') != -1:
+ if midlcom.find('/dlldata') != -1:
dlldata = base + '_data.c'
t.append(dlldata)
diff --git a/src/engine/SCons/Tool/mingw.py b/src/engine/SCons/Tool/mingw.py
index e93f1ad..6df46e0 100644
--- a/src/engine/SCons/Tool/mingw.py
+++ b/src/engine/SCons/Tool/mingw.py
@@ -31,11 +31,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mingw.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mingw.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
-import string
import SCons.Action
import SCons.Builder
@@ -73,7 +72,7 @@ def shlib_emitter(target, source, env):
no_import_lib = env.get('no_import_lib', 0)
if not dll:
- raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
+ raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX"))
if not no_import_lib and \
not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'):
diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py
index c568abd..a2933cb 100644
--- a/src/engine/SCons/Tool/mslib.py
+++ b/src/engine/SCons/Tool/mslib.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mslib.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mslib.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py
index 36ad2fe..c291ba9 100644
--- a/src/engine/SCons/Tool/mslink.py
+++ b/src/engine/SCons/Tool/mslink.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mslink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mslink.py 5023 2010/06/14 22:05:46 scons"
import os.path
@@ -103,7 +103,7 @@ def _dllEmitter(target, source, env, paramtp):
no_import_lib = env.get('no_import_lib', 0)
if not dll:
- raise SCons.Errors.UserError, 'A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp)
+ raise SCons.Errors.UserError('A shared library should have exactly one target with the suffix: %s' % env.subst('$%sSUFFIX' % paramtp))
insert_def = env.subst("$WINDOWS_INSERT_DEF")
if not insert_def in ['', '0', 0] and \
@@ -123,7 +123,7 @@ def _dllEmitter(target, source, env, paramtp):
'%sPREFIX' % paramtp, '%sSUFFIX' % paramtp,
"WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
- if env.has_key('PDB') and env['PDB']:
+ if 'PDB' in env and env['PDB']:
pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
extratargets.append(pdb)
target[0].attributes.pdb = pdb
@@ -161,7 +161,7 @@ def prog_emitter(target, source, env):
exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX")
if not exe:
- raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")
+ raise SCons.Errors.UserError("An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX"))
version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0'))
if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0):
@@ -171,7 +171,7 @@ def prog_emitter(target, source, env):
"PROGPREFIX", "PROGSUFFIX",
"WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
- if env.has_key('PDB') and env['PDB']:
+ if 'PDB' in env and env['PDB']:
pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
extratargets.append(pdb)
target[0].attributes.pdb = pdb
@@ -179,10 +179,10 @@ def prog_emitter(target, source, env):
return (target+extratargets,source)
def RegServerFunc(target, source, env):
- if env.has_key('register') and env['register']:
+ if 'register' in env and env['register']:
ret = regServerAction([target[0]], [source[0]], env)
if ret:
- raise SCons.Errors.UserError, "Unable to register %s" % target[0]
+ raise SCons.Errors.UserError("Unable to register %s" % target[0])
else:
print "Registered %s sucessfully" % target[0]
return ret
diff --git a/src/engine/SCons/Tool/mssdk.py b/src/engine/SCons/Tool/mssdk.py
index ed5bd5c..08898c6 100644
--- a/src/engine/SCons/Tool/mssdk.py
+++ b/src/engine/SCons/Tool/mssdk.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mssdk.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mssdk.py 5023 2010/06/14 22:05:46 scons"
"""engine.SCons.Tool.mssdk
diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py
index f145816..8c13580 100644
--- a/src/engine/SCons/Tool/msvc.py
+++ b/src/engine/SCons/Tool/msvc.py
@@ -31,11 +31,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/msvc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/msvc.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
-import string
import sys
import SCons.Action
@@ -55,11 +54,11 @@ CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
def validate_vars(env):
"""Validate the PCH and PCHSTOP construction variables."""
- if env.has_key('PCH') and env['PCH']:
- if not env.has_key('PCHSTOP'):
- raise SCons.Errors.UserError, "The PCHSTOP construction must be defined if PCH is defined."
+ if 'PCH' in env and env['PCH']:
+ if 'PCHSTOP' not in env:
+ raise SCons.Errors.UserError("The PCHSTOP construction must be defined if PCH is defined.")
if not SCons.Util.is_String(env['PCHSTOP']):
- raise SCons.Errors.UserError, "The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']
+ raise SCons.Errors.UserError("The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP'])
def pch_emitter(target, source, env):
"""Adds the object file target."""
@@ -99,7 +98,7 @@ def object_emitter(target, source, env, parent_emitter):
# See issue #2505 for a discussion of what to do if it turns
# out this assumption causes trouble in the wild:
# http://scons.tigris.org/issues/show_bug.cgi?id=2505
- if env.has_key('PCH'):
+ if 'PCH' in env:
pch = env['PCH']
if str(target[0]) != SCons.Util.splitext(str(pch))[0] + '.obj':
env.Depends(target, pch)
@@ -254,9 +253,9 @@ def generate(env):
env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
env['BUILDERS']['PCH'] = pch_builder
- if not env.has_key('ENV'):
+ if 'ENV' not in env:
env['ENV'] = {}
- if not env['ENV'].has_key('SystemRoot'): # required for dlls in the winsxs folders
+ if 'SystemRoot' not in env['ENV']: # required for dlls in the winsxs folders
env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
def exists(env):
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index 17bb9a0..34fc0e7 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -29,17 +29,18 @@ 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.
-#
-__revision__ = "src/engine/SCons/Tool/msvs.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/msvs.py 5023 2010/06/14 22:05:46 scons"
+
+import SCons.compat
import base64
import hashlib
import ntpath
import os
+# compat layer imports "cPickle" for us if it's available.
import pickle
import re
-import string
import sys
import SCons.Builder
@@ -57,23 +58,10 @@ from SCons.Defaults import processDefines
# DSP/DSW/SLN/VCPROJ files.
##############################################################################
-def _hexdigest(s):
- """Return a string as a string of hex characters.
- """
- # NOTE: This routine is a method in the Python 2.0 interface
- # of the native md5 module, but we want SCons to operate all
- # the way back to at least Python 1.5.2, which doesn't have it.
- h = string.hexdigits
- r = ''
- for c in s:
- i = ord(c)
- r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
- return r
-
def xmlify(s):
- s = string.replace(s, "&", "&amp;") # do this first
- s = string.replace(s, "'", "&apos;")
- s = string.replace(s, '"', "&quot;")
+ s = s.replace("&", "&amp;") # do this first
+ s = s.replace("'", "&apos;")
+ s = s.replace('"', "&quot;")
return s
external_makefile_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}'
@@ -88,9 +76,7 @@ def _generateGUID(slnfile, name):
# the generated file has a consistent GUID even if we generate
# it on a non-Windows platform.
m.update(ntpath.normpath(str(slnfile)) + str(name))
- # TODO(1.5)
- #solution = m.hexdigest().upper()
- solution = string.upper(_hexdigest(m.digest()))
+ solution = m.hexdigest().upper()
# convert most of the signature to GUID form (discard the rest)
solution = "{" + solution[:8] + "-" + solution[8:12] + "-" + solution[12:16] + "-" + solution[16:20] + "-" + solution[20:32] + "}"
return solution
@@ -116,7 +102,7 @@ def msvs_parse_version(s):
# which works regardless of how we were invoked.
def getExecScriptMain(env, xml=None):
scons_home = env.get('SCONS_HOME')
- if not scons_home and os.environ.has_key('SCONS_LIB_DIR'):
+ if not scons_home and 'SCONS_LIB_DIR' in os.environ:
scons_home = os.environ['SCONS_LIB_DIR']
if scons_home:
exec_script_main = "from os.path import join; import sys; sys.path = [ r'%s' ] + sys.path; import SCons.Script; SCons.Script.main()" % scons_home
@@ -139,7 +125,7 @@ else:
python_executable = os.path.join('$$(PYTHON_ROOT)',
os.path.split(sys.executable)[1])
-class Config:
+class Config(object):
pass
def splitFully(path):
@@ -161,7 +147,7 @@ def makeHierarchy(sources):
if len(path):
dict = hierarchy
for part in path[:-1]:
- if not dict.has_key(part):
+ if part not in dict:
dict[part] = {}
dict = dict[part]
dict[path[-1]] = file
@@ -169,7 +155,7 @@ def makeHierarchy(sources):
# print 'Warning: failed to decompose path for '+str(file)
return hierarchy
-class _DSPGenerator:
+class _DSPGenerator(object):
""" Base class for DSP generators """
srcargs = [
@@ -188,23 +174,21 @@ class _DSPGenerator:
else:
self.dspabs = get_abspath()
- if not env.has_key('variant'):
- raise SCons.Errors.InternalError, \
- "You must specify a 'variant' argument (i.e. 'Debug' or " +\
- "'Release') to create an MSVSProject."
+ if 'variant' not in env:
+ raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\
+ "'Release') to create an MSVSProject.")
elif SCons.Util.is_String(env['variant']):
variants = [env['variant']]
elif SCons.Util.is_List(env['variant']):
variants = env['variant']
- if not env.has_key('buildtarget') or env['buildtarget'] == None:
+ if 'buildtarget' not in env or env['buildtarget'] == None:
buildtarget = ['']
elif SCons.Util.is_String(env['buildtarget']):
buildtarget = [env['buildtarget']]
elif SCons.Util.is_List(env['buildtarget']):
if len(env['buildtarget']) != len(variants):
- raise SCons.Errors.InternalError, \
- "Sizes of 'buildtarget' and 'variant' lists must be the same."
+ raise SCons.Errors.InternalError("Sizes of 'buildtarget' and 'variant' lists must be the same.")
buildtarget = []
for bt in env['buildtarget']:
if SCons.Util.is_String(bt):
@@ -219,14 +203,13 @@ class _DSPGenerator:
for _ in variants:
buildtarget.append(bt)
- if not env.has_key('outdir') or env['outdir'] == None:
+ if 'outdir' not in env or env['outdir'] == None:
outdir = ['']
elif SCons.Util.is_String(env['outdir']):
outdir = [env['outdir']]
elif SCons.Util.is_List(env['outdir']):
if len(env['outdir']) != len(variants):
- raise SCons.Errors.InternalError, \
- "Sizes of 'outdir' and 'variant' lists must be the same."
+ raise SCons.Errors.InternalError("Sizes of 'outdir' and 'variant' lists must be the same.")
outdir = []
for s in env['outdir']:
if SCons.Util.is_String(s):
@@ -241,14 +224,13 @@ class _DSPGenerator:
for v in variants:
outdir.append(s)
- if not env.has_key('runfile') or env['runfile'] == None:
+ if 'runfile' not in env or env['runfile'] == None:
runfile = buildtarget[-1:]
elif SCons.Util.is_String(env['runfile']):
runfile = [env['runfile']]
elif SCons.Util.is_List(env['runfile']):
if len(env['runfile']) != len(variants):
- raise SCons.Errors.InternalError, \
- "Sizes of 'runfile' and 'variant' lists must be the same."
+ raise SCons.Errors.InternalError("Sizes of 'runfile' and 'variant' lists must be the same.")
runfile = []
for s in env['runfile']:
if SCons.Util.is_String(s):
@@ -269,7 +251,7 @@ class _DSPGenerator:
self.env = env
- if self.env.has_key('name'):
+ if 'name' in self.env:
self.name = self.env['name']
else:
self.name = os.path.basename(SCons.Util.splitext(self.dspfile)[0])
@@ -289,14 +271,14 @@ class _DSPGenerator:
self.configs = {}
self.nokeep = 0
- if env.has_key('nokeep') and env['variant'] != 0:
+ if 'nokeep' in env and env['variant'] != 0:
self.nokeep = 1
if self.nokeep == 0 and os.path.exists(self.dspabs):
self.Parse()
for t in zip(sourcenames,self.srcargs):
- if self.env.has_key(t[1]):
+ if t[1] in self.env:
if SCons.Util.is_List(self.env[t[1]]):
for i in self.env[t[1]]:
if not i in self.sources[t[0]]:
@@ -306,9 +288,9 @@ class _DSPGenerator:
self.sources[t[0]].append(self.env[t[1]])
for n in sourcenames:
- # TODO(1.5):
- #self.sources[n].sort(lambda a, b: cmp(a.lower(), b.lower()))
- self.sources[n].sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
+ #TODO 2.4: compat layer supports sorted(key=) but not sort(key=)
+ #TODO 2.4: self.sources[n].sort(key=lambda a: a.lower())
+ self.sources[n] = sorted(self.sources[n], key=lambda a: a.lower())
def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, dspfile=dspfile):
config = Config()
@@ -367,8 +349,7 @@ class _GenerateV6DSP(_DSPGenerator):
def PrintHeader(self):
# pick a default config
- confkeys = self.configs.keys()
- confkeys.sort()
+ confkeys = sorted(self.configs.keys())
name = self.name
confkey = confkeys[0]
@@ -388,8 +369,7 @@ class _GenerateV6DSP(_DSPGenerator):
'# PROP Scc_LocalPath ""\n\n')
first = 1
- confkeys = self.configs.keys()
- confkeys.sort()
+ confkeys = sorted(self.configs.keys())
for kind in confkeys:
outdir = self.configs[kind].outdir
buildtarget = self.configs[kind].buildtarget
@@ -399,7 +379,7 @@ class _GenerateV6DSP(_DSPGenerator):
else:
self.file.write('\n!ELSEIF "$(CFG)" == "%s - Win32 %s"\n\n' % (name, kind))
- env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET')
+ env_has_buildtarget = 'MSVSBUILDTARGET' in self.env
if not env_has_buildtarget:
self.env['MSVSBUILDTARGET'] = buildtarget
@@ -407,9 +387,7 @@ class _GenerateV6DSP(_DSPGenerator):
for base in ("BASE ",""):
self.file.write('# PROP %sUse_MFC 0\n'
'# PROP %sUse_Debug_Libraries ' % (base, base))
- # TODO(1.5):
- #if kind.lower().find('debug') < 0:
- if string.find(string.lower(kind), 'debug') < 0:
+ if kind.lower().find('debug') < 0:
self.file.write('0\n')
else:
self.file.write('1\n')
@@ -459,18 +437,12 @@ class _GenerateV6DSP(_DSPGenerator):
'Resource Files': 'r|rc|ico|cur|bmp|dlg|rc2|rct|bin|cnt|rtf|gif|jpg|jpeg|jpe',
'Other Files': ''}
- cats = categories.keys()
- # TODO(1.5):
- #cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
- cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
- for kind in cats:
+ for kind in sorted(categories.keys(), key=lambda a: a.lower()):
if not self.sources[kind]:
continue # skip empty groups
self.file.write('# Begin Group "' + kind + '"\n\n')
- # TODO(1.5)
- #typelist = categories[kind].replace('|', ';')
- typelist = string.replace(categories[kind], '|', ';')
+ typelist = categories[kind].replace('|', ';')
self.file.write('# PROP Default_Filter "' + typelist + '"\n')
for file in self.sources[kind]:
@@ -493,9 +465,7 @@ class _GenerateV6DSP(_DSPGenerator):
line = dspfile.readline()
while line:
- # TODO(1.5):
- #if line.find("# End Project") > -1:
- if string.find(line, "# End Project") > -1:
+ if line.find("# End Project") > -1:
break
line = dspfile.readline()
@@ -539,7 +509,7 @@ class _GenerateV6DSP(_DSPGenerator):
try:
self.file = open(self.dspabs,'w')
except IOError, detail:
- raise SCons.Errors.InternalError, 'Unable to open "' + self.dspabs + '" for writing:' + str(detail)
+ raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail))
else:
self.PrintHeader()
self.PrintProject()
@@ -664,8 +634,7 @@ class _GenerateV7DSP(_DSPGenerator):
def PrintProject(self):
self.file.write('\t<Configurations>\n')
- confkeys = self.configs.keys()
- confkeys.sort()
+ confkeys = sorted(self.configs.keys())
for kind in confkeys:
variant = self.configs[kind].variant
platform = self.configs[kind].platform
@@ -674,7 +643,7 @@ class _GenerateV7DSP(_DSPGenerator):
runfile = self.configs[kind].runfile
cmdargs = self.configs[kind].cmdargs
- env_has_buildtarget = self.env.has_key('MSVSBUILDTARGET')
+ env_has_buildtarget = 'MSVSBUILDTARGET' in self.env
if not env_has_buildtarget:
self.env['MSVSBUILDTARGET'] = buildtarget
@@ -687,11 +656,8 @@ class _GenerateV7DSP(_DSPGenerator):
rebuildcmd = xmlify(starting + self.env.subst('$MSVSREBUILDCOM', 1) + cmdargs)
cleancmd = xmlify(starting + self.env.subst('$MSVSCLEANCOM', 1) + cmdargs)
- # TODO(1.5)
- #preprocdefs = xmlify(';'.join(self.env.get('CPPDEFINES', [])))
- #includepath = xmlify(';'.join(self.env.get('CPPPATH', [])))
- preprocdefs = xmlify(string.join(processDefines(self.env.get('CPPDEFINES', [])), ';'))
- includepath = xmlify(string.join(self.env.get('CPPPATH', []), ';'))
+ preprocdefs = xmlify(';'.join(processDefines(self.env.get('CPPDEFINES', []))))
+ includepath = xmlify(';'.join(self.env.get('CPPPATH', [])))
if not env_has_buildtarget:
del self.env['MSVSBUILDTARGET']
@@ -718,10 +684,7 @@ class _GenerateV7DSP(_DSPGenerator):
self.file.write(pdata + '-->\n')
def printSources(self, hierarchy, commonprefix):
- sorteditems = hierarchy.items()
- # TODO(1.5):
- #sorteditems.sort(lambda a, b: cmp(a[0].lower(), b[0].lower()))
- sorteditems.sort(lambda a, b: cmp(string.lower(a[0]), string.lower(b[0])))
+ sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower())
# First folders, then files
for key, value in sorteditems:
@@ -751,11 +714,8 @@ class _GenerateV7DSP(_DSPGenerator):
self.file.write('\t<Files>\n')
- cats = categories.keys()
- # TODO(1.5)
- #cats.sort(lambda a, b: cmp(a.lower(), b.lower()))
- cats.sort(lambda a, b: cmp(string.lower(a), string.lower(b)))
- cats = filter(lambda k, s=self: s.sources[k], cats)
+ cats = sorted([k for k in categories.keys() if self.sources[k]],
+ key=lambda a: a.lower())
for kind in cats:
if len(cats) > 1:
self.file.write('\t\t<Filter\n'
@@ -767,14 +727,14 @@ class _GenerateV7DSP(_DSPGenerator):
# First remove any common prefix
commonprefix = None
if len(sources) > 1:
- s = map(os.path.normpath, sources)
+ s = list(map(os.path.normpath, sources))
# take the dirname because the prefix may include parts
# of the filenames (e.g. if you have 'dir\abcd' and
# 'dir\acde' then the cp will be 'dir\a' )
cp = os.path.dirname( os.path.commonprefix(s) )
if cp and s[0][len(cp)] == os.sep:
# +1 because the filename starts after the separator
- sources = map(lambda s, l=len(cp)+1: s[l:], sources)
+ sources = [s[len(cp)+1:] for s in sources]
commonprefix = cp
elif len(sources) == 1:
commonprefix = os.path.dirname( sources[0] )
@@ -803,9 +763,7 @@ class _GenerateV7DSP(_DSPGenerator):
line = dspfile.readline()
while line:
- # TODO(1.5)
- #if line.find('<!-- SCons Data:') > -1:
- if string.find(line, '<!-- SCons Data:') > -1:
+ if line.find('<!-- SCons Data:') > -1:
break
line = dspfile.readline()
@@ -848,32 +806,29 @@ class _GenerateV7DSP(_DSPGenerator):
try:
self.file = open(self.dspabs,'w')
except IOError, detail:
- raise SCons.Errors.InternalError, 'Unable to open "' + self.dspabs + '" for writing:' + str(detail)
+ raise SCons.Errors.InternalError('Unable to open "' + self.dspabs + '" for writing:' + str(detail))
else:
self.PrintHeader()
self.PrintProject()
self.file.close()
-class _DSWGenerator:
+class _DSWGenerator(object):
""" Base class for DSW generators """
def __init__(self, dswfile, source, env):
self.dswfile = os.path.normpath(str(dswfile))
self.env = env
- if not env.has_key('projects'):
- raise SCons.Errors.UserError, \
- "You must specify a 'projects' argument to create an MSVSSolution."
+ if 'projects' not in env:
+ raise SCons.Errors.UserError("You must specify a 'projects' argument to create an MSVSSolution.")
projects = env['projects']
if not SCons.Util.is_List(projects):
- raise SCons.Errors.InternalError, \
- "The 'projects' argument must be a list of nodes."
+ raise SCons.Errors.InternalError("The 'projects' argument must be a list of nodes.")
projects = SCons.Util.flatten(projects)
if len(projects) < 1:
- raise SCons.Errors.UserError, \
- "You must specify at least one project to create an MSVSSolution."
- self.dspfiles = map(str, projects)
+ raise SCons.Errors.UserError("You must specify at least one project to create an MSVSSolution.")
+ self.dspfiles = list(map(str, projects))
- if self.env.has_key('name'):
+ if 'name' in self.env:
self.name = self.env['name']
else:
self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0])
@@ -898,7 +853,7 @@ class _GenerateV7DSW(_DSWGenerator):
if self.version_num >= 8.0:
self.versionstr = '9.00'
- if env.has_key('slnguid') and env['slnguid']:
+ if 'slnguid' in env and env['slnguid']:
self.slnguid = env['slnguid']
else:
self.slnguid = _generateGUID(dswfile, self.name)
@@ -906,7 +861,7 @@ class _GenerateV7DSW(_DSWGenerator):
self.configs = {}
self.nokeep = 0
- if env.has_key('nokeep') and env['variant'] != 0:
+ if 'nokeep' in env and env['variant'] != 0:
self.nokeep = 1
if self.nokeep == 0 and os.path.exists(self.dswfile):
@@ -926,10 +881,9 @@ class _GenerateV7DSW(_DSWGenerator):
self.configs[variant] = config
print "Adding '" + self.name + ' - ' + config.variant + '|' + config.platform + "' to '" + str(dswfile) + "'"
- if not env.has_key('variant'):
- raise SCons.Errors.InternalError, \
- "You must specify a 'variant' argument (i.e. 'Debug' or " +\
- "'Release') to create an MSVS Solution File."
+ if 'variant' not in env:
+ raise SCons.Errors.InternalError("You must specify a 'variant' argument (i.e. 'Debug' or " +\
+ "'Release') to create an MSVS Solution File.")
elif SCons.Util.is_String(env['variant']):
AddConfig(self, env['variant'])
elif SCons.Util.is_List(env['variant']):
@@ -992,11 +946,11 @@ class _GenerateV7DSW(_DSWGenerator):
self.file.write('Global\n')
env = self.env
- if env.has_key('MSVS_SCC_PROVIDER'):
+ if 'MSVS_SCC_PROVIDER' in env:
dspfile_base = os.path.basename(self.dspfile)
slnguid = self.slnguid
scc_provider = env.get('MSVS_SCC_PROVIDER', '')
- scc_provider = string.replace(scc_provider, ' ', r'\u0020')
+ scc_provider = scc_provider.replace(' ', r'\u0020')
scc_project_name = env.get('MSVS_SCC_PROJECT_NAME', '')
# scc_aux_path = env.get('MSVS_SCC_AUX_PATH', '')
scc_local_path = env.get('MSVS_SCC_LOCAL_PATH', '')
@@ -1022,8 +976,7 @@ class _GenerateV7DSW(_DSWGenerator):
else:
self.file.write('\tGlobalSection(SolutionConfiguration) = preSolution\n')
- confkeys = self.configs.keys()
- confkeys.sort()
+ confkeys = sorted(self.configs.keys())
cnt = 0
for name in confkeys:
variant = self.configs[name].variant
@@ -1077,7 +1030,7 @@ class _GenerateV7DSW(_DSWGenerator):
try:
self.file = open(self.dswfile,'w')
except IOError, detail:
- raise SCons.Errors.InternalError, 'Unable to open "' + self.dswfile + '" for writing:' + str(detail)
+ raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail))
else:
self.PrintSolution()
self.file.close()
@@ -1126,7 +1079,7 @@ class _GenerateV6DSW(_DSWGenerator):
try:
self.file = open(self.dswfile,'w')
except IOError, detail:
- raise SCons.Errors.InternalError, 'Unable to open "' + self.dswfile + '" for writing:' + str(detail)
+ raise SCons.Errors.InternalError('Unable to open "' + self.dswfile + '" for writing:' + str(detail))
else:
self.PrintWorkspace()
self.file.close()
@@ -1136,7 +1089,7 @@ def GenerateDSP(dspfile, source, env):
"""Generates a Project file based on the version of MSVS that is being used"""
version_num = 6.0
- if env.has_key('MSVS_VERSION'):
+ if 'MSVS_VERSION' in env:
version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
if version_num >= 7.0:
g = _GenerateV7DSP(dspfile, source, env)
@@ -1149,7 +1102,7 @@ def GenerateDSW(dswfile, source, env):
"""Generates a Solution/Workspace file based on the version of MSVS that is being used"""
version_num = 6.0
- if env.has_key('MSVS_VERSION'):
+ if 'MSVS_VERSION' in env:
version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
if version_num >= 7.0:
g = _GenerateV7DSW(dswfile, source, env)
@@ -1225,7 +1178,7 @@ def projectEmitter(target, source, env):
source = source + env.subst('$MSVSSCONSCOM', 1)
source = source + env.subst('$MSVSENCODING', 1)
- if env.has_key('buildtarget') and env['buildtarget'] != None:
+ if 'buildtarget' in env and env['buildtarget'] != None:
if SCons.Util.is_String(env['buildtarget']):
source = source + ' "%s"' % env['buildtarget']
elif SCons.Util.is_List(env['buildtarget']):
@@ -1234,14 +1187,12 @@ def projectEmitter(target, source, env):
source = source + ' "%s"' % bt
else:
try: source = source + ' "%s"' % bt.get_abspath()
- except AttributeError: raise SCons.Errors.InternalError, \
- "buildtarget can be a string, a node, a list of strings or nodes, or None"
+ except AttributeError: raise SCons.Errors.InternalError("buildtarget can be a string, a node, a list of strings or nodes, or None")
else:
try: source = source + ' "%s"' % env['buildtarget'].get_abspath()
- except AttributeError: raise SCons.Errors.InternalError, \
- "buildtarget can be a string, a node, a list of strings or nodes, or None"
+ except AttributeError: raise SCons.Errors.InternalError("buildtarget can be a string, a node, a list of strings or nodes, or None")
- if env.has_key('outdir') and env['outdir'] != None:
+ if 'outdir' in env and env['outdir'] != None:
if SCons.Util.is_String(env['outdir']):
source = source + ' "%s"' % env['outdir']
elif SCons.Util.is_List(env['outdir']):
@@ -1250,20 +1201,18 @@ def projectEmitter(target, source, env):
source = source + ' "%s"' % s
else:
try: source = source + ' "%s"' % s.get_abspath()
- except AttributeError: raise SCons.Errors.InternalError, \
- "outdir can be a string, a node, a list of strings or nodes, or None"
+ except AttributeError: raise SCons.Errors.InternalError("outdir can be a string, a node, a list of strings or nodes, or None")
else:
try: source = source + ' "%s"' % env['outdir'].get_abspath()
- except AttributeError: raise SCons.Errors.InternalError, \
- "outdir can be a string, a node, a list of strings or nodes, or None"
+ except AttributeError: raise SCons.Errors.InternalError("outdir can be a string, a node, a list of strings or nodes, or None")
- if env.has_key('name'):
+ if 'name' in env:
if SCons.Util.is_String(env['name']):
source = source + ' "%s"' % env['name']
else:
- raise SCons.Errors.InternalError, "name must be a string"
+ raise SCons.Errors.InternalError("name must be a string")
- if env.has_key('variant'):
+ if 'variant' in env:
if SCons.Util.is_String(env['variant']):
source = source + ' "%s"' % env['variant']
elif SCons.Util.is_List(env['variant']):
@@ -1271,14 +1220,14 @@ def projectEmitter(target, source, env):
if SCons.Util.is_String(variant):
source = source + ' "%s"' % variant
else:
- raise SCons.Errors.InternalError, "name must be a string or a list of strings"
+ raise SCons.Errors.InternalError("name must be a string or a list of strings")
else:
- raise SCons.Errors.InternalError, "variant must be a string or a list of strings"
+ raise SCons.Errors.InternalError("variant must be a string or a list of strings")
else:
- raise SCons.Errors.InternalError, "variant must be specified"
+ raise SCons.Errors.InternalError("variant must be specified")
for s in _DSPGenerator.srcargs:
- if env.has_key(s):
+ if s in env:
if SCons.Util.is_String(env[s]):
source = source + ' "%s' % env[s]
elif SCons.Util.is_List(env[s]):
@@ -1286,9 +1235,9 @@ def projectEmitter(target, source, env):
if SCons.Util.is_String(t):
source = source + ' "%s"' % t
else:
- raise SCons.Errors.InternalError, s + " must be a string or a list of strings"
+ raise SCons.Errors.InternalError(s + " must be a string or a list of strings")
else:
- raise SCons.Errors.InternalError, s + " must be a string or a list of strings"
+ raise SCons.Errors.InternalError(s + " must be a string or a list of strings")
source = source + ' "%s"' % str(target[0])
source = [SCons.Node.Python.Value(source)]
@@ -1320,13 +1269,13 @@ def solutionEmitter(target, source, env):
if not source:
source = 'sln_inputs:'
- if env.has_key('name'):
+ if 'name' in env:
if SCons.Util.is_String(env['name']):
source = source + ' "%s"' % env['name']
else:
- raise SCons.Errors.InternalError, "name must be a string"
+ raise SCons.Errors.InternalError("name must be a string")
- if env.has_key('variant'):
+ if 'variant' in env:
if SCons.Util.is_String(env['variant']):
source = source + ' "%s"' % env['variant']
elif SCons.Util.is_List(env['variant']):
@@ -1334,19 +1283,19 @@ def solutionEmitter(target, source, env):
if SCons.Util.is_String(variant):
source = source + ' "%s"' % variant
else:
- raise SCons.Errors.InternalError, "name must be a string or a list of strings"
+ raise SCons.Errors.InternalError("name must be a string or a list of strings")
else:
- raise SCons.Errors.InternalError, "variant must be a string or a list of strings"
+ raise SCons.Errors.InternalError("variant must be a string or a list of strings")
else:
- raise SCons.Errors.InternalError, "variant must be specified"
+ raise SCons.Errors.InternalError("variant must be specified")
- if env.has_key('slnguid'):
+ if 'slnguid' in env:
if SCons.Util.is_String(env['slnguid']):
source = source + ' "%s"' % env['slnguid']
else:
- raise SCons.Errors.InternalError, "slnguid must be a string"
+ raise SCons.Errors.InternalError("slnguid must be a string")
- if env.has_key('projects'):
+ if 'projects' in env:
if SCons.Util.is_String(env['projects']):
source = source + ' "%s"' % env['projects']
elif SCons.Util.is_List(env['projects']):
@@ -1410,11 +1359,11 @@ def generate(env):
# Set-up ms tools paths for default version
msvc_setup_env_once(env)
- if env.has_key('MSVS_VERSION'):
+ if 'MSVS_VERSION' in env:
version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
else:
(version_num, suite) = (7.0, None) # guess at a default
- if not env.has_key('MSVS'):
+ if 'MSVS' not in env:
env['MSVS'] = {}
if (version_num < 7.0):
env['MSVS']['PROJECTSUFFIX'] = '.dsp'
diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py
index ce4edd5..f45b702 100644
--- a/src/engine/SCons/Tool/msvsTests.py
+++ b/src/engine/SCons/Tool/msvsTests.py
@@ -21,10 +21,9 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/msvsTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/msvsTests.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import sys
import TestCmd
import unittest
@@ -39,7 +38,7 @@ from SCons.Tool.MSCommon.common import debug
from SCons.Tool.MSCommon import get_default_version, \
query_versions
-regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
+regdata_6a = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0]
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks]
"sp3"=""
@@ -49,9 +48,9 @@ regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudi
"ProductDir"="C:\Program Files\Microsoft Visual Studio\MSDN98\98VSa\1033"
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++]
"ProductDir"="C:\Program Files\Microsoft Visual Studio\VC98"
-''','\n')
+'''.split('\n')
-regdata_6b = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
+regdata_6b = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0]
"InstallDir"="C:\VS6\Common\IDE\IDE98"
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks]
@@ -68,9 +67,9 @@ regdata_6b = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudi
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Microsoft VSEE Client]
"ProductDir"="C:\VS6\Common\Tools"
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\Setup\Visual Studio 98]
-''','\n')
+'''.split('\n')
-regdata_7 = string.split(r'''
+regdata_7 = r'''
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.0]
"InstallDir"="C:\Program Files\Microsoft Visual Studio .NET\Common7\IDE\"
"Source Directories"="C:\Program Files\Microsoft Visual Studio .NET\Vc7\crt\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET\Vc7\atlmfc\src\atl\"
@@ -134,9 +133,9 @@ regdata_7 = string.split(r'''
"Include Dirs"="$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(VCInstallDir)PlatformSDK\include\prerelease;$(VCInstallDir)PlatformSDK\include;$(FrameworkSDKDir)include"
"Source Dirs"="$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src"
"Reference Dirs"=""
-''','\n')
+'''.split('\n')
-regdata_7_1 = string.split(r'''
+regdata_7_1 = r'''
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\7.1]
@=""
"Source Directories"="C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\crt\src\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\atl\"
@@ -240,9 +239,9 @@ regdata_7_1 = string.split(r'''
"VCManagedWrapperGeneratorTool"=""
"VCAuxiliaryManagedWrapperGeneratorTool"=""
"VCPrimaryInteropTool"=""
-''','\n')
+'''.split('\n')
-regdata_8exp = string.split(r'''
+regdata_8exp = r'''
[HKEY_LOCAL_MACHINE\Software\Microsoft\VCExpress\8.0]
"CLR Version"="v2.0.50727"
"ApplicationID"="VCExpress"
@@ -284,9 +283,9 @@ regdata_8exp = string.split(r'''
"VCXMLDataGeneratorTool"="*.xsd"
"VCManifestTool"="*.manifest"
"VCXDCMakeTool"="*.xdc"
-''','\n')
+'''.split('\n')
-regdata_80 = string.split(r'''
+regdata_80 = r'''
[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0]
"CLR Version"="v2.0.50727"
"ApplicationID"="VisualStudio"
@@ -346,18 +345,18 @@ regdata_80 = string.split(r'''
"VCXMLDataGeneratorTool"="*.xsd"
"VCManifestTool"="*.manifest"
"VCXDCMakeTool"="*.xdc"
-''','\n')
+'''.split('\n')
-regdata_cv = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
+regdata_cv = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
"ProgramFilesDir"="C:\Program Files"
"CommonFilesDir"="C:\Program Files\Common Files"
"MediaPath"="C:\WINDOWS\Media"
-''','\n')
+'''.split('\n')
regdata_none = []
-class DummyEnv:
+class DummyEnv(object):
def __init__(self, dict=None):
if dict:
self.dict = dict
@@ -375,17 +374,20 @@ class DummyEnv:
def __getitem__(self,key):
return self.dict[key]
+ def __contains__(self,key):
+ return key in self.dict
+
def has_key(self,name):
- return self.dict.has_key(name)
+ return name in self.dict
-class RegKey:
+class RegKey(object):
"""key class for storing an 'open' registry key"""
def __init__(self,key):
self.key = key
# Warning: this is NOT case-insensitive, unlike the Windows registry.
# So e.g. HKLM\Software is NOT the same key as HKLM\SOFTWARE.
-class RegNode:
+class RegNode(object):
"""node in the dummy registry"""
def __init__(self,name):
self.valdict = {}
@@ -395,7 +397,7 @@ class RegNode:
self.name = name
def value(self,val):
- if self.valdict.has_key(val):
+ if val in self.valdict:
return (self.valdict[val],1)
else:
raise SCons.Util.RegError
@@ -428,13 +430,13 @@ class RegNode:
raise SCons.Util.RegError
def addKey(self,name,sep = '\\'):
- if string.find(name, sep) != -1:
- keyname, subkeys = string.split(name, sep, 1)
+ if name.find(sep) != -1:
+ keyname, subkeys = name.split(sep, 1)
else:
keyname = name
subkeys = ""
- if not self.keydict.has_key(keyname):
+ if keyname not in self.keydict:
self.keydict[keyname] = RegNode(keyname)
self.keyarray.append(keyname)
@@ -460,7 +462,7 @@ class RegNode:
rv = rv + indent + '}\n'
return rv
-class DummyRegistry:
+class DummyRegistry(object):
"""registry class for storing fake registry attributes"""
def __init__(self,data):
"""parse input data into the fake registry"""
@@ -739,7 +741,7 @@ if __name__ == "__main__":
for k in ['VS71COMNTOOLS',
'VS80COMNTOOLS',
'VS90COMNTOOLS']:
- if os.environ.has_key(k):
+ if k in os.environ:
del os.environ[k]
suite = unittest.makeSuite(test_class, 'test_')
diff --git a/src/engine/SCons/Tool/mwcc.py b/src/engine/SCons/Tool/mwcc.py
index ec97ab5..fe6f0b3 100644
--- a/src/engine/SCons/Tool/mwcc.py
+++ b/src/engine/SCons/Tool/mwcc.py
@@ -30,11 +30,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mwcc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mwcc.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
-import string
import SCons.Util
@@ -80,8 +79,8 @@ def set_vars(env):
ENV['CWFolder'] = version.path
ENV['LM_LICENSE_FILE'] = version.license
plus = lambda x: '+%s' % x
- ENV['MWCIncludes'] = string.join(map(plus, version.includes), os.pathsep)
- ENV['MWLibraries'] = string.join(map(plus, version.libs), os.pathsep)
+ ENV['MWCIncludes'] = os.pathsep.join(map(plus, version.includes))
+ ENV['MWLibraries'] = os.pathsep.join(map(plus, version.libs))
return 1
@@ -100,7 +99,7 @@ def find_versions():
product_key = SCons.Util.RegOpenKeyEx(HLM, product)
i = 0
- while 1:
+ while True:
name = product + '\\' + SCons.Util.RegEnumKey(product_key, i)
name_key = SCons.Util.RegOpenKeyEx(HLM, name)
@@ -120,7 +119,7 @@ def find_versions():
return versions
-class MWVersion:
+class MWVersion(object):
def __init__(self, version, path, platform):
self.version = version
self.path = path
diff --git a/src/engine/SCons/Tool/mwld.py b/src/engine/SCons/Tool/mwld.py
index 9880876..73d9f32 100644
--- a/src/engine/SCons/Tool/mwld.py
+++ b/src/engine/SCons/Tool/mwld.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/mwld.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/mwld.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool
@@ -85,7 +85,7 @@ def shlib_emitter(target, source, env):
no_import_lib = env.get('no_import_lib', 0)
if not dll:
- raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
+ raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX"))
if not no_import_lib and \
not env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX'):
diff --git a/src/engine/SCons/Tool/nasm.py b/src/engine/SCons/Tool/nasm.py
index fe469d6..212e323 100644
--- a/src/engine/SCons/Tool/nasm.py
+++ b/src/engine/SCons/Tool/nasm.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/nasm.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/nasm.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/packaging/__init__.py b/src/engine/SCons/Tool/packaging/__init__.py
index 3ef610c..e7d684e 100644
--- a/src/engine/SCons/Tool/packaging/__init__.py
+++ b/src/engine/SCons/Tool/packaging/__init__.py
@@ -24,9 +24,8 @@ SCons Packaging 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.
-#
-__revision__ = "src/engine/SCons/Tool/packaging/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/__init__.py 5023 2010/06/14 22:05:46 scons"
import SCons.Environment
from SCons.Variables import *
@@ -58,7 +57,7 @@ def Tag(env, target, source, *more_tags, **kw_tags):
kw_tags[first_tag[0]] = ''
if len(kw_tags) == 0 and len(more_tags) == 0:
- raise UserError, "No tags given."
+ raise UserError("No tags given.")
# XXX: sanity checks
for x in more_tags:
@@ -91,7 +90,7 @@ def Package(env, target=None, source=None, **kw):
source = env.FindInstalledFiles()
if len(source)==0:
- raise UserError, "No source for Package() given"
+ raise UserError("No source for Package() given")
# decide which types of packages shall be built. Can be defined through
# four mechanisms: command line argument, keyword argument,
@@ -105,16 +104,16 @@ def Package(env, target=None, source=None, **kw):
kw['PACKAGETYPE'] = GetOption('package_type')
if kw['PACKAGETYPE'] == None:
- if env['BUILDERS'].has_key('Tar'):
+ if 'Tar' in env['BUILDERS']:
kw['PACKAGETYPE']='targz'
- elif env['BUILDERS'].has_key('Zip'):
+ elif 'Zip' in env['BUILDERS']:
kw['PACKAGETYPE']='zip'
else:
- raise UserError, "No type for Package() given"
+ raise UserError("No type for Package() given")
PACKAGETYPE=kw['PACKAGETYPE']
if not is_List(PACKAGETYPE):
- PACKAGETYPE=string.split(PACKAGETYPE, ',')
+ PACKAGETYPE=PACKAGETYPE.split(',')
# load the needed packagers.
def load_packager(type):
@@ -124,7 +123,7 @@ def Package(env, target=None, source=None, **kw):
except ImportError, e:
raise EnvironmentError("packager %s not available: %s"%(type,str(e)))
- packagers=map(load_packager, PACKAGETYPE)
+ packagers=list(map(load_packager, PACKAGETYPE))
# set up targets and the PACKAGEROOT
try:
@@ -139,7 +138,7 @@ def Package(env, target=None, source=None, **kw):
default_target = default_name%kw
target.extend( [default_target]*size_diff )
- if not kw.has_key('PACKAGEROOT'):
+ if 'PACKAGEROOT' not in kw:
kw['PACKAGEROOT'] = default_name%kw
except KeyError, e:
@@ -153,7 +152,7 @@ def Package(env, target=None, source=None, **kw):
try:
for packager in packagers:
t=[target.pop(0)]
- t=apply(packager.package, [env,t,source], kw)
+ t=packager.package(env,t,source, **kw)
targets.extend(t)
assert( len(target) == 0 )
@@ -173,8 +172,7 @@ def Package(env, target=None, source=None, **kw):
args.remove('target')
args.remove('source')
# now remove any args for which we have a value in kw.
- #args=[x for x in args if not kw.has_key(x)]
- args=filter(lambda x, kw=kw: not kw.has_key(x), args)
+ args=[x for x in args if x not in kw]
if len(args)==0:
raise # must be a different error, so reraise
@@ -222,7 +220,7 @@ def options(opts):
opts.AddVariables(
EnumVariable( 'PACKAGETYPE',
'the type of package to create.',
- None, allowed_values=map( str, __all__ ),
+ None, allowed_values=list(map( str, __all__ )),
ignorecase=2
)
)
@@ -236,8 +234,8 @@ def copy_attr(f1, f2):
"""
#pattrs = [x for x in dir(f1) if not hasattr(f2, x) and\
# x.startswith('PACKAGING_')]
- copyit = lambda x, f2=f2: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
- pattrs = filter(copyit, dir(f1))
+ copyit = lambda x: not hasattr(f2, x) and x[:10] == 'PACKAGING_'
+ pattrs = list(filter(copyit, dir(f1)))
for attr in pattrs:
setattr(f2, attr, getattr(f1, attr))
def putintopackageroot(target, source, env, pkgroot, honor_install_location=1):
@@ -291,7 +289,7 @@ def stripinstallbuilder(target, source, env):
(file.builder.name=="InstallBuilder" or\
file.builder.name=="InstallAsBuilder"))
- if len(filter(has_no_install_location, source)):
+ if len(list(filter(has_no_install_location, source))):
warn(Warning, "there are files to package which have no\
InstallBuilder attached, this might lead to irreproducible packages")
diff --git a/src/engine/SCons/Tool/packaging/ipk.py b/src/engine/SCons/Tool/packaging/ipk.py
index de1de7c..266bb70 100644
--- a/src/engine/SCons/Tool/packaging/ipk.py
+++ b/src/engine/SCons/Tool/packaging/ipk.py
@@ -24,7 +24,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/ipk.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/ipk.py 5023 2010/06/14 22:05:46 scons"
import SCons.Builder
import SCons.Node.FS
@@ -58,7 +58,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
buildarchitecture = os.uname()[4]
buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
- if kw.has_key('ARCHITECTURE'):
+ if 'ARCHITECTURE' in kw:
buildarchitecture = kw['ARCHITECTURE']
# setup the kw to contain the mandatory arguments to this fucntion.
@@ -76,7 +76,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION, DESCRIPTION,
target=[ "%s_%s_%s.ipk"%(NAME, VERSION, buildarchitecture) ]
# now apply the Ipkg builder
- return apply(bld, [env, target, specfile], kw)
+ return bld(env, target, specfile, **kw)
def gen_ipk_dir(proot, source, env, kw):
# make sure the packageroot is a Dir object.
@@ -98,7 +98,7 @@ def gen_ipk_dir(proot, source, env, kw):
spec_target.append(control.File('preinst'))
# apply the builder to the specfile targets
- apply(s_bld, [env, spec_target, source], kw)
+ s_bld(env, spec_target, source, **kw)
# the packageroot directory does now contain the specfiles.
return proot
@@ -125,7 +125,7 @@ def build_specfiles(source, target, env):
control_file=open_file('control', target)
- if not env.has_key('X_IPK_DESCRIPTION'):
+ if 'X_IPK_DESCRIPTION' not in env:
env['X_IPK_DESCRIPTION']="%s\n %s"%(env['SUMMARY'],
env['DESCRIPTION'].replace('\n', '\n '))
@@ -173,7 +173,7 @@ Description: $X_IPK_DESCRIPTION
f.close()
# call a user specified function
- if env.has_key('CHANGE_SPECFILE'):
+ if 'CHANGE_SPECFILE' in env:
content += env['CHANGE_SPECFILE'](target)
return 0
diff --git a/src/engine/SCons/Tool/packaging/msi.py b/src/engine/SCons/Tool/packaging/msi.py
index cea3483..76dca18 100644
--- a/src/engine/SCons/Tool/packaging/msi.py
+++ b/src/engine/SCons/Tool/packaging/msi.py
@@ -24,9 +24,8 @@ The msi packager.
# 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__ = "src/engine/SCons/Tool/packaging/msi.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/msi.py 5023 2010/06/14 22:05:46 scons"
import os
import SCons
@@ -65,14 +64,14 @@ def convert_to_id(s, id_set):
charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxyz0123456789_.'
if s[0] in '0123456789.':
s += '_'+s
- id = filter( lambda c : c in charset, s )
+ id = [c for c in s if c in charset]
# did we already generate an id for this file?
try:
return id_set[id][s]
except KeyError:
# no we did not so initialize with the id
- if not id_set.has_key(id): id_set[id] = { s : id }
+ if id not in id_set: id_set[id] = { s : id }
# there is a collision, generate an id which is unique by appending
# the collision number
else: id_set[id][s] = id + str(len(id_set[id]))
@@ -109,7 +108,7 @@ def gen_dos_short_file_name(file, filename_set):
# strip forbidden characters.
forbidden = '."/[]:;=, '
- fname = filter( lambda c : c not in forbidden, fname )
+ fname = [c for c in fname if c not in forbidden]
# check if we already generated a filename with the same number:
# thisis1.txt, thisis2.txt etc.
@@ -137,7 +136,7 @@ def create_feature_dict(files):
feature = [ feature ]
for f in feature:
- if not dict.has_key( f ):
+ if f not in dict:
dict[ f ] = [ file ]
else:
dict[ f ].append( file )
@@ -214,7 +213,7 @@ def build_wxsfile(target, source, env):
file.write( doc.toprettyxml() )
# call a user specified function
- if env.has_key('CHANGE_SPECFILE'):
+ if 'CHANGE_SPECFILE' in env:
env['CHANGE_SPECFILE'](target, source)
except KeyError, e:
@@ -296,9 +295,11 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set,
upper_dir = ''
# walk down the xml tree finding parts of the directory
- dir_parts = filter( lambda d: d != '', dir_parts )
+ dir_parts = [d for d in dir_parts if d != '']
for d in dir_parts[:]:
- already_created = filter( lambda c: c.nodeName == 'Directory' and c.attributes['LongName'].value == escape(d), Directory.childNodes )
+ already_created = [c for c in Directory.childNodes
+ if c.nodeName == 'Directory'
+ and c.attributes['LongName'].value == escape(d)]
if already_created != []:
Directory = already_created[0]
@@ -464,7 +465,7 @@ def build_wxsfile_header_section(root, spec):
Product.childNodes.append( Package )
# set "mandatory" default values
- if not spec.has_key('X_MSI_LANGUAGE'):
+ if 'X_MSI_LANGUAGE' not in spec:
spec['X_MSI_LANGUAGE'] = '1033' # select english
# mandatory sections, will throw a KeyError if the tag is not available
@@ -475,10 +476,10 @@ def build_wxsfile_header_section(root, spec):
Package.attributes['Description'] = escape( spec['SUMMARY'] )
# now the optional tags, for which we avoid the KeyErrror exception
- if spec.has_key( 'DESCRIPTION' ):
+ if 'DESCRIPTION' in spec:
Package.attributes['Comments'] = escape( spec['DESCRIPTION'] )
- if spec.has_key( 'X_MSI_UPGRADE_CODE' ):
+ if 'X_MSI_UPGRADE_CODE' in spec:
Package.attributes['X_MSI_UPGRADE_CODE'] = escape( spec['X_MSI_UPGRADE_CODE'] )
# We hardcode the media tag as our current model cannot handle it.
@@ -511,7 +512,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
# put the arguments into the env and call the specfile builder.
env['msi_spec'] = kw
- specfile = apply( wxs_builder, [env, target, source], kw )
+ specfile = wxs_builder(* [env, target, source], **kw)
# now call the WiX Tool with the built specfile added as a source.
msifile = env.WiX(target, specfile)
diff --git a/src/engine/SCons/Tool/packaging/rpm.py b/src/engine/SCons/Tool/packaging/rpm.py
index 80d5a89..ff693b9 100644
--- a/src/engine/SCons/Tool/packaging/rpm.py
+++ b/src/engine/SCons/Tool/packaging/rpm.py
@@ -24,12 +24,10 @@ The rpm packager.
# 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__ = "src/engine/SCons/Tool/packaging/rpm.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/rpm.py 5023 2010/06/14 22:05:46 scons"
import os
-import string
import SCons.Builder
@@ -65,7 +63,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
buildarchitecture = os.uname()[4]
buildarchitecture = archmap.get(buildarchitecture, buildarchitecture)
- if kw.has_key('ARCHITECTURE'):
+ if 'ARCHITECTURE' in kw:
buildarchitecture = kw['ARCHITECTURE']
fmt = '%s-%s-%s.%s.rpm'
@@ -81,9 +79,9 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
del kw['source'], kw['target'], kw['env']
# if no "SOURCE_URL" tag is given add a default one.
- if not kw.has_key('SOURCE_URL'):
+ if 'SOURCE_URL' not in kw:
#kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
- kw['SOURCE_URL']=string.replace(str(target[0])+".tar.gz", '.rpm', '')
+ kw['SOURCE_URL']=(str(target[0])+".tar.gz").replace('.rpm', '')
# mangle the source and target list for the rpmbuild
env = OverrideEnvironment(env, kw)
@@ -92,7 +90,7 @@ def package(env, target, source, PACKAGEROOT, NAME, VERSION,
target, source = collectintargz(target, source, env)
# now call the rpm builder to actually build the packet.
- return apply(bld, [env, target, source], kw)
+ return bld(env, target, source, **kw)
def collectintargz(target, source, env):
""" Puts all source files into a tar.gz file. """
@@ -102,21 +100,21 @@ def collectintargz(target, source, env):
# filter out the target we are building the source list for.
#sources = [s for s in sources if not (s in target)]
- sources = filter(lambda s, t=target: not (s in t), sources)
+ sources = [s for s in sources if s not in target]
# find the .spec file for rpm and add it since it is not necessarily found
# by the FindSourceFiles function.
#sources.extend( [s for s in source if str(s).rfind('.spec')!=-1] )
- spec_file = lambda s: string.rfind(str(s), '.spec') != -1
- sources.extend( filter(spec_file, source) )
+ spec_file = lambda s: str(s).rfind('.spec') != -1
+ sources.extend( list(filter(spec_file, source)) )
# as the source contains the url of the source package this rpm package
# is built from, we extract the target name
#tarball = (str(target[0])+".tar.gz").replace('.rpm', '')
- tarball = string.replace(str(target[0])+".tar.gz", '.rpm', '')
+ tarball = (str(target[0])+".tar.gz").replace('.rpm', '')
try:
#tarball = env['SOURCE_URL'].split('/')[-1]
- tarball = string.split(env['SOURCE_URL'], '/')[-1]
+ tarball = env['SOURCE_URL'].split('/')[-1]
except KeyError, e:
raise SCons.Errors.UserError( "Missing PackageTag '%s' for RPM packager" % e.args[0] )
@@ -150,7 +148,7 @@ def build_specfile(target, source, env):
file.close()
# call a user specified function
- if env.has_key('CHANGE_SPECFILE'):
+ if 'CHANGE_SPECFILE' in env:
env['CHANGE_SPECFILE'](target, source)
except KeyError, e:
@@ -188,16 +186,16 @@ def build_specfile_sections(spec):
# Default prep, build, install and clean rules
# TODO: optimize those build steps, to not compile the project a second time
- if not spec.has_key('X_RPM_PREP'):
+ if 'X_RPM_PREP' not in spec:
spec['X_RPM_PREP'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"' + '\n%setup -q'
- if not spec.has_key('X_RPM_BUILD'):
+ if 'X_RPM_BUILD' not in spec:
spec['X_RPM_BUILD'] = 'mkdir "$RPM_BUILD_ROOT"'
- if not spec.has_key('X_RPM_INSTALL'):
+ if 'X_RPM_INSTALL' not in spec:
spec['X_RPM_INSTALL'] = 'scons --install-sandbox="$RPM_BUILD_ROOT" "$RPM_BUILD_ROOT"'
- if not spec.has_key('X_RPM_CLEAN'):
+ if 'X_RPM_CLEAN' not in spec:
spec['X_RPM_CLEAN'] = '[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"'
str = str + SimpleTagCompiler(optional_sections, mandatory=0).compile( spec )
@@ -254,7 +252,7 @@ def build_specfile_header(spec):
# if not s.has_key('x_rpm_BuildRequires'):
# s['x_rpm_BuildRequires'] = 'scons'
- if not spec.has_key('X_RPM_BUILDROOT'):
+ if 'X_RPM_BUILDROOT' not in spec:
spec['X_RPM_BUILDROOT'] = '%{_tmppath}/%{name}-%{version}-%{release}'
str = str + SimpleTagCompiler(optional_header_fields, mandatory=0).compile( spec )
@@ -268,7 +266,7 @@ def build_specfile_filesection(spec, files):
"""
str = '%files\n'
- if not spec.has_key('X_RPM_DEFATTR'):
+ if 'X_RPM_DEFATTR' not in spec:
spec['X_RPM_DEFATTR'] = '(-,root,root)'
str = str + '%%defattr %s\n' % spec['X_RPM_DEFATTR']
@@ -302,7 +300,7 @@ def build_specfile_filesection(spec, files):
return str
-class SimpleTagCompiler:
+class SimpleTagCompiler(object):
""" This class is a simple string substition utility:
the replacement specfication is stored in the tagset dictionary, something
like:
@@ -333,11 +331,11 @@ class SimpleTagCompiler:
def strip_country_code(tag):
return tag[:-2]
- replacements = self.tagset.items()
+ replacements = list(self.tagset.items())
str = ""
#domestic = [ (k,v) for k,v in replacements if not is_international(k) ]
- domestic = filter(lambda t, i=is_international: not i(t[0]), replacements)
+ domestic = [t for t in replacements if not is_international(t[0])]
for key, replacement in domestic:
try:
str = str + replacement % values[key]
@@ -346,12 +344,12 @@ class SimpleTagCompiler:
raise e
#international = [ (k,v) for k,v in replacements if is_international(k) ]
- international = filter(lambda t, i=is_international: i(t[0]), replacements)
+ international = [t for t in replacements if is_international(t[0])]
for key, replacement in international:
try:
#int_values_for_key = [ (get_country_code(k),v) for k,v in values.items() if strip_country_code(k) == key ]
- x = filter(lambda t,key=key,s=strip_country_code: s(t[0]) == key, values.items())
- int_values_for_key = map(lambda t,g=get_country_code: (g(t[0]),t[1]), x)
+ x = [t for t in values.items() if strip_country_code(t[0]) == key]
+ int_values_for_key = [(get_country_code(t[0]),t[1]) for t in x]
for v in int_values_for_key:
str = str + replacement % v
except KeyError, e:
diff --git a/src/engine/SCons/Tool/packaging/src_tarbz2.py b/src/engine/SCons/Tool/packaging/src_tarbz2.py
index def9fcc..7ff3bed 100644
--- a/src/engine/SCons/Tool/packaging/src_tarbz2.py
+++ b/src/engine/SCons/Tool/packaging/src_tarbz2.py
@@ -26,7 +26,7 @@ The tarbz2 SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/src_tarbz2.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/src_tarbz2.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import putintopackageroot
diff --git a/src/engine/SCons/Tool/packaging/src_targz.py b/src/engine/SCons/Tool/packaging/src_targz.py
index 0550a45..a493cde 100644
--- a/src/engine/SCons/Tool/packaging/src_targz.py
+++ b/src/engine/SCons/Tool/packaging/src_targz.py
@@ -26,7 +26,7 @@ The targz SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/src_targz.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/src_targz.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import putintopackageroot
diff --git a/src/engine/SCons/Tool/packaging/src_zip.py b/src/engine/SCons/Tool/packaging/src_zip.py
index 3d7dc3f..0d89b36 100644
--- a/src/engine/SCons/Tool/packaging/src_zip.py
+++ b/src/engine/SCons/Tool/packaging/src_zip.py
@@ -26,7 +26,7 @@ The zip SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/src_zip.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/src_zip.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import putintopackageroot
diff --git a/src/engine/SCons/Tool/packaging/tarbz2.py b/src/engine/SCons/Tool/packaging/tarbz2.py
index d1b9dc8..a1d6da8 100644
--- a/src/engine/SCons/Tool/packaging/tarbz2.py
+++ b/src/engine/SCons/Tool/packaging/tarbz2.py
@@ -26,7 +26,7 @@ The tarbz2 SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/tarbz2.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/tarbz2.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
diff --git a/src/engine/SCons/Tool/packaging/targz.py b/src/engine/SCons/Tool/packaging/targz.py
index e0770f3..f2a3d49 100644
--- a/src/engine/SCons/Tool/packaging/targz.py
+++ b/src/engine/SCons/Tool/packaging/targz.py
@@ -26,7 +26,7 @@ The targz SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/targz.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/targz.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
diff --git a/src/engine/SCons/Tool/packaging/zip.py b/src/engine/SCons/Tool/packaging/zip.py
index 7b79103..359de97 100644
--- a/src/engine/SCons/Tool/packaging/zip.py
+++ b/src/engine/SCons/Tool/packaging/zip.py
@@ -26,7 +26,7 @@ The zip SRC packager.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/packaging/zip.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/packaging/zip.py 5023 2010/06/14 22:05:46 scons"
from SCons.Tool.packaging import stripinstallbuilder, putintopackageroot
diff --git a/src/engine/SCons/Tool/pdf.py b/src/engine/SCons/Tool/pdf.py
index c83a377..9d8aaab 100644
--- a/src/engine/SCons/Tool/pdf.py
+++ b/src/engine/SCons/Tool/pdf.py
@@ -28,7 +28,7 @@ Add an explicit action to run epstopdf to convert .eps files to .pdf
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/pdf.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/pdf.py 5023 2010/06/14 22:05:46 scons"
import SCons.Builder
import SCons.Tool
diff --git a/src/engine/SCons/Tool/pdflatex.py b/src/engine/SCons/Tool/pdflatex.py
index 757f47c..368c795 100644
--- a/src/engine/SCons/Tool/pdflatex.py
+++ b/src/engine/SCons/Tool/pdflatex.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/pdflatex.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/pdflatex.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Util
@@ -44,7 +44,7 @@ PDFLaTeXAction = None
def PDFLaTeXAuxFunction(target = None, source= None, env=None):
result = SCons.Tool.tex.InternalLaTeXAuxAction( PDFLaTeXAction, target, source, env )
if result != 0:
- print env['PDFLATEX']," returned an error, check the log file"
+ SCons.Tool.tex.check_file_error_message(env['PDFLATEX'])
return result
PDFLaTeXAuxAction = None
diff --git a/src/engine/SCons/Tool/pdftex.py b/src/engine/SCons/Tool/pdftex.py
index 90bc687..6296f7a 100644
--- a/src/engine/SCons/Tool/pdftex.py
+++ b/src/engine/SCons/Tool/pdftex.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/pdftex.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/pdftex.py 5023 2010/06/14 22:05:46 scons"
import os
import SCons.Action
@@ -59,11 +59,11 @@ def PDFTeXLaTeXFunction(target = None, source= None, env=None):
if SCons.Tool.tex.is_LaTeX(source,env,abspath):
result = PDFLaTeXAuxAction(target,source,env)
if result != 0:
- print env['PDFLATEX']," returned an error, check the log file"
+ SCons.Tool.tex.check_file_error_message(env['PDFLATEX'])
else:
result = PDFTeXAction(target,source,env)
if result != 0:
- print env['PDFTEX']," returned an error, check the log file"
+ SCons.Tool.tex.check_file_error_message(env['PDFTEX'])
return result
PDFTeXLaTeXAction = None
diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py
index d63b586..90331aa 100644
--- a/src/engine/SCons/Tool/qt.py
+++ b/src/engine/SCons/Tool/qt.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/qt.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/qt.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
@@ -81,7 +81,7 @@ def find_file(filename, paths, node_factory):
return node
return None
-class _Automoc:
+class _Automoc(object):
"""
Callable class, which works as an emitter for Programs, SharedLibraries and
StaticLibraries.
diff --git a/src/engine/SCons/Tool/rmic.py b/src/engine/SCons/Tool/rmic.py
index 71deadf..d35ea54 100644
--- a/src/engine/SCons/Tool/rmic.py
+++ b/src/engine/SCons/Tool/rmic.py
@@ -31,10 +31,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/rmic.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/rmic.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import SCons.Action
import SCons.Builder
@@ -86,7 +85,7 @@ def emit_rmic_classes(target, source, env):
tlist = []
for s in source:
for suff in stub_suffixes:
- fname = string.replace(s.attributes.java_classname, '.', os.sep) + \
+ fname = s.attributes.java_classname.replace('.', os.sep) + \
suff + class_suffix
t = target[0].File(fname)
t.attributes.java_lookupdir = target[0]
diff --git a/src/engine/SCons/Tool/rpcgen.py b/src/engine/SCons/Tool/rpcgen.py
index 22f54a9..40b6ed0 100644
--- a/src/engine/SCons/Tool/rpcgen.py
+++ b/src/engine/SCons/Tool/rpcgen.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/rpcgen.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/rpcgen.py 5023 2010/06/14 22:05:46 scons"
from SCons.Builder import Builder
import SCons.Util
diff --git a/src/engine/SCons/Tool/rpm.py b/src/engine/SCons/Tool/rpm.py
index 47b7c6f..f5c41a1 100644
--- a/src/engine/SCons/Tool/rpm.py
+++ b/src/engine/SCons/Tool/rpm.py
@@ -33,7 +33,7 @@ tar.gz consisting of the source file and a specfile.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/rpm.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/rpm.py 5023 2010/06/14 22:05:46 scons"
import os
import re
diff --git a/src/engine/SCons/Tool/sgiar.py b/src/engine/SCons/Tool/sgiar.py
index 56b2f7e..aa5d451 100644
--- a/src/engine/SCons/Tool/sgiar.py
+++ b/src/engine/SCons/Tool/sgiar.py
@@ -33,7 +33,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sgiar.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sgiar.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/sgic++.py b/src/engine/SCons/Tool/sgic++.py
index 5d38d50..ae6460a 100644
--- a/src/engine/SCons/Tool/sgic++.py
+++ b/src/engine/SCons/Tool/sgic++.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sgic++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sgic++.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sgicc.py b/src/engine/SCons/Tool/sgicc.py
index 8115452..08f42fa 100644
--- a/src/engine/SCons/Tool/sgicc.py
+++ b/src/engine/SCons/Tool/sgicc.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sgicc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sgicc.py 5023 2010/06/14 22:05:46 scons"
import cc
diff --git a/src/engine/SCons/Tool/sgilink.py b/src/engine/SCons/Tool/sgilink.py
index fd0e270..0f1060f 100644
--- a/src/engine/SCons/Tool/sgilink.py
+++ b/src/engine/SCons/Tool/sgilink.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sgilink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sgilink.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sunar.py b/src/engine/SCons/Tool/sunar.py
index b673db2..0fe3820 100644
--- a/src/engine/SCons/Tool/sunar.py
+++ b/src/engine/SCons/Tool/sunar.py
@@ -32,7 +32,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunar.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunar.py 5023 2010/06/14 22:05:46 scons"
import SCons.Defaults
import SCons.Tool
diff --git a/src/engine/SCons/Tool/sunc++.py b/src/engine/SCons/Tool/sunc++.py
index cde72cb..14ae59f 100644
--- a/src/engine/SCons/Tool/sunc++.py
+++ b/src/engine/SCons/Tool/sunc++.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunc++.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunc++.py 5023 2010/06/14 22:05:46 scons"
import SCons
diff --git a/src/engine/SCons/Tool/suncc.py b/src/engine/SCons/Tool/suncc.py
index 8b4b338..4848766 100644
--- a/src/engine/SCons/Tool/suncc.py
+++ b/src/engine/SCons/Tool/suncc.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/suncc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/suncc.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sunf77.py b/src/engine/SCons/Tool/sunf77.py
index ddc30c3..34dea3e 100644
--- a/src/engine/SCons/Tool/sunf77.py
+++ b/src/engine/SCons/Tool/sunf77.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunf77.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunf77.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sunf90.py b/src/engine/SCons/Tool/sunf90.py
index 78e756b..74a3856 100644
--- a/src/engine/SCons/Tool/sunf90.py
+++ b/src/engine/SCons/Tool/sunf90.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunf90.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunf90.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sunf95.py b/src/engine/SCons/Tool/sunf95.py
index 12190c4..e825f61 100644
--- a/src/engine/SCons/Tool/sunf95.py
+++ b/src/engine/SCons/Tool/sunf95.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunf95.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunf95.py 5023 2010/06/14 22:05:46 scons"
import SCons.Util
diff --git a/src/engine/SCons/Tool/sunlink.py b/src/engine/SCons/Tool/sunlink.py
index 4fb8625..5af2256 100644
--- a/src/engine/SCons/Tool/sunlink.py
+++ b/src/engine/SCons/Tool/sunlink.py
@@ -30,7 +30,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/sunlink.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/sunlink.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
diff --git a/src/engine/SCons/Tool/swig.py b/src/engine/SCons/Tool/swig.py
index 8ad4596..85aab70 100644
--- a/src/engine/SCons/Tool/swig.py
+++ b/src/engine/SCons/Tool/swig.py
@@ -31,11 +31,10 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/swig.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/swig.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
-import string
import subprocess
import SCons.Action
@@ -72,7 +71,7 @@ def _find_modules(src):
for m in matches:
mnames.append(m[2])
- directors = directors or string.find(m[0], 'directors') >= 0
+ directors = directors or m[0].find('directors') >= 0
return mnames, directors
def _add_director_header_targets(target, env):
@@ -97,29 +96,26 @@ def _swigEmitter(target, source, env):
mnames, directors = _find_modules(src)
if directors:
_add_director_header_targets(target, env)
- python_files = map(lambda m: m + ".py", mnames)
+ python_files = [m + ".py" for m in mnames]
outdir = env.subst('$SWIGOUTDIR', target=target, source=source)
# .py files should be generated in SWIGOUTDIR if specified,
# otherwise in the same directory as the target
if outdir:
- python_files = map(lambda j, o=outdir, e=env:
- e.fs.File(os.path.join(o, j)),
- python_files)
+ python_files = [env.fs.File(os.path.join(outdir, j)) for j in python_files]
else:
- python_files = map(lambda m, d=target[0].dir:
- d.File(m), python_files)
+ python_files = [target[0].dir.File(m) for m in python_files]
target.extend(python_files)
if "-java" in flags:
if mnames is None:
mnames, directors = _find_modules(src)
if directors:
_add_director_header_targets(target, env)
- java_files = map(lambda m: [m + ".java", m + "JNI.java"], mnames)
+ java_files = [[m + ".java", m + "JNI.java"] for m in mnames]
java_files = SCons.Util.flatten(java_files)
outdir = env.subst('$SWIGOUTDIR', target=target, source=source)
if outdir:
- java_files = map(lambda j, o=outdir: os.path.join(o, j), java_files)
- java_files = map(env.fs.File, java_files)
+ java_files = [os.path.join(outdir, j) for j in java_files]
+ java_files = list(map(env.fs.File, java_files))
for jf in java_files:
t_from_s = lambda t, p, s, x: t.dir
SCons.Util.AddMethod(jf, t_from_s, 'target_from_source')
diff --git a/src/engine/SCons/Tool/tar.py b/src/engine/SCons/Tool/tar.py
index 65a16b3..0005ef7 100644
--- a/src/engine/SCons/Tool/tar.py
+++ b/src/engine/SCons/Tool/tar.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/tar.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/tar.py 5023 2010/06/14 22:05:46 scons"
import SCons.Action
import SCons.Builder
diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py
index 3f9dee3..b4b2819 100644
--- a/src/engine/SCons/Tool/tex.py
+++ b/src/engine/SCons/Tool/tex.py
@@ -32,12 +32,12 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/tex.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/tex.py 5023 2010/06/14 22:05:46 scons"
import os.path
import re
-import string
import shutil
+import sys
import SCons.Action
import SCons.Node
@@ -133,6 +133,10 @@ _null = SCons.Scanner.LaTeX._null
modify_env_var = SCons.Scanner.LaTeX.modify_env_var
+def check_file_error_message(utility, filename='log'):
+ msg = '%s returned an error, check the %s file\n' % (utility, filename)
+ sys.stdout.write(msg)
+
def FindFile(name,suffixes,paths,env,requireExt=False):
if requireExt:
name,ext = SCons.Util.splitext(name)
@@ -232,8 +236,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
#
# routine to update MD5 hash and compare
#
- # TODO(1.5): nested scopes
- def check_MD5(filenode, suffix, saved_hashes=saved_hashes, targetbase=targetbase):
+ def check_MD5(filenode, suffix):
global must_rerun_latex
# two calls to clear old csig
filenode.clear_memoized_values()
@@ -292,13 +295,13 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
target_aux = os.path.join(targetdir, auxfilename)
if os.path.exists(target_aux):
content = open(target_aux, "rb").read()
- if string.find(content, "bibdata") != -1:
+ if content.find("bibdata") != -1:
if Verbose:
print "Need to run bibtex"
bibfile = env.fs.File(targetbase)
result = BibTeXAction(bibfile, bibfile, env)
if result != 0:
- print env['BIBTEX']," returned an error, check the blg file"
+ check_file_error_message(env['BIBTEX'], 'blg')
return result
must_rerun_latex = check_MD5(suffix_nodes['.bbl'],'.bbl')
break
@@ -311,7 +314,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
idxfile = suffix_nodes['.idx']
result = MakeIndexAction(idxfile, idxfile, env)
if result != 0:
- print env['MAKEINDEX']," returned an error, check the ilg file"
+ check_file_error_message(env['MAKEINDEX'], 'ilg')
return result
# TO-DO: need to add a way for the user to extend this list for whatever
@@ -329,7 +332,8 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
nclfile = suffix_nodes['.nlo']
result = MakeNclAction(nclfile, nclfile, env)
if result != 0:
- print env['MAKENCL']," (nomenclature) returned an error, check the nlg file"
+ check_file_error_message('%s (nomenclature)' % env['MAKENCL'],
+ 'nlg')
#return result
# Now decide if latex will need to be run again due to glossary.
@@ -340,7 +344,8 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
glofile = suffix_nodes['.glo']
result = MakeGlossaryAction(glofile, glofile, env)
if result != 0:
- print env['MAKEGLOSSARY']," (glossary) returned an error, check the glg file"
+ check_file_error_message('%s (glossary)' % env['MAKEGLOSSARY'],
+ 'glg')
#return result
# Now decide if latex will need to be run again due to acronyms.
@@ -351,7 +356,8 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None
acrfile = suffix_nodes['.acn']
result = MakeAcronymsAction(acrfile, acrfile, env)
if result != 0:
- print env['MAKEACRONYMS']," (acronymns) returned an error, check the alg file"
+ check_file_error_message('%s (acronyms)' % env['MAKEACRONYMS'],
+ 'alg')
return result
# Now decide if latex needs to be run yet again to resolve warnings.
@@ -420,9 +426,7 @@ def is_LaTeX(flist,env,abspath):
pass
else:
# Split at os.pathsep to convert into absolute path
- # TODO(1.5)
- #paths = paths.split(os.pathsep)
- paths = string.split(paths, os.pathsep)
+ paths = paths.split(os.pathsep)
# now that we have the path list restore the env
if savedpath is _null:
@@ -488,11 +492,11 @@ def TeXLaTeXFunction(target = None, source= None, env=None):
if is_LaTeX(source,env,abspath):
result = LaTeXAuxAction(target,source,env)
if result != 0:
- print env['LATEX']," returned an error, check the log file"
+ check_file_error_message(env['LATEX'])
else:
result = TeXAction(target,source,env)
if result != 0:
- print env['TEX']," returned an error, check the log file"
+ check_file_error_message(env['TEX'])
return result
def TeXLaTeXStrFunction(target = None, source= None, env=None):
@@ -646,9 +650,7 @@ def tex_emitter_core(target, source, env, graphics_extensions):
pass
else:
# Split at os.pathsep to convert into absolute path
- # TODO(1.5)
- #paths = paths.split(os.pathsep)
- paths = string.split(paths, os.pathsep)
+ paths = paths.split(os.pathsep)
# now that we have the path list restore the env
if savedpath is _null:
diff --git a/src/engine/SCons/Tool/textfile.py b/src/engine/SCons/Tool/textfile.py
index 5d1611b..0293bb9 100644
--- a/src/engine/SCons/Tool/textfile.py
+++ b/src/engine/SCons/Tool/textfile.py
@@ -44,7 +44,7 @@ Textfile/Substfile builder for SCons.
is unpredictible whether the expansion will occur.
"""
-__revision__ = "src/engine/SCons/Tool/textfile.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/textfile.py 5023 2010/06/14 22:05:46 scons"
import SCons
@@ -84,12 +84,12 @@ def _action(target, source, env):
% repr(linesep), None)
# create a dictionary to use for the substitutions
- if not env.has_key('SUBST_DICT'):
+ if 'SUBST_DICT' not in env:
subs = None # no substitutions
else:
d = env['SUBST_DICT']
if is_Dict(d):
- d = d.items()
+ d = list(d.items())
elif is_Sequence(d):
pass
else:
diff --git a/src/engine/SCons/Tool/tlib.py b/src/engine/SCons/Tool/tlib.py
index 7b03638..6344e71 100644
--- a/src/engine/SCons/Tool/tlib.py
+++ b/src/engine/SCons/Tool/tlib.py
@@ -27,7 +27,7 @@ XXX
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/tlib.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/tlib.py 5023 2010/06/14 22:05:46 scons"
import SCons.Tool
import SCons.Tool.bcc32
diff --git a/src/engine/SCons/Tool/wix.py b/src/engine/SCons/Tool/wix.py
index 603092c..1a95e22 100644
--- a/src/engine/SCons/Tool/wix.py
+++ b/src/engine/SCons/Tool/wix.py
@@ -30,12 +30,11 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/wix.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/wix.py 5023 2010/06/14 22:05:46 scons"
import SCons.Builder
import SCons.Action
import os
-import string
def generate(env):
"""Add Builders and construction variables for WiX to an Environment."""
@@ -68,7 +67,7 @@ def exists(env):
# try to find the candle.exe and light.exe tools and
# add the install directory to light libpath.
#for path in os.environ['PATH'].split(os.pathsep):
- for path in string.split(os.environ['PATH'], os.pathsep):
+ for path in os.environ['PATH'].split(os.pathsep):
if not path:
continue
diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py
index 6b5ad3f..0f8744f 100644
--- a/src/engine/SCons/Tool/yacc.py
+++ b/src/engine/SCons/Tool/yacc.py
@@ -31,10 +31,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/yacc.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/yacc.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import SCons.Defaults
import SCons.Tool
@@ -71,7 +70,7 @@ def _yaccEmitter(target, source, env, ysuf, hsuf):
if option[:l] == fileGenOption:
# A file generating option is present, so add the file
# name to the list of targets.
- fileName = string.strip(option[l:])
+ fileName = option[l:].strip()
target.append(fileName)
return (target, source)
diff --git a/src/engine/SCons/Tool/zip.py b/src/engine/SCons/Tool/zip.py
index 42f23a2..36fd436 100644
--- a/src/engine/SCons/Tool/zip.py
+++ b/src/engine/SCons/Tool/zip.py
@@ -31,7 +31,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Tool/zip.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Tool/zip.py 5023 2010/06/14 22:05:46 scons"
import os.path
@@ -49,16 +49,15 @@ except ImportError:
if internal_zip:
zipcompression = zipfile.ZIP_DEFLATED
def zip(target, source, env):
- def visit(arg, dirname, names):
- for name in names:
- path = os.path.join(dirname, name)
- if os.path.isfile(path):
- arg.write(path)
compression = env.get('ZIPCOMPRESSION', 0)
zf = zipfile.ZipFile(str(target[0]), 'w', compression)
for s in source:
if s.isdir():
- os.path.walk(str(s), visit, zf)
+ for dirpath, dirnames, filenames in os.walk(str(s)):
+ for fname in filenames:
+ path = os.path.join(dirpath, fname)
+ if os.path.isfile(path):
+ zf.write(path)
else:
zf.write(str(s))
zf.close()
diff --git a/src/engine/SCons/Tool/zip.xml b/src/engine/SCons/Tool/zip.xml
index db2fc9f..51a8194 100644
--- a/src/engine/SCons/Tool/zip.xml
+++ b/src/engine/SCons/Tool/zip.xml
@@ -90,10 +90,9 @@ is compressed or not.
The default value is
<literal>zipfile.ZIP_DEFLATED</literal>,
which creates a compressed zip archive.
-This value has no effect when using Python 1.5.2
-or if the
+This value has no effect if the
<literal>zipfile</literal>
-module is otherwise unavailable.
+module is unavailable.
</summary>
</cvar>
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 220eb41..a9b3421 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -1,9 +1,7 @@
"""SCons.Util
Various utility functions go here.
-
"""
-
#
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
#
@@ -25,29 +23,25 @@ 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.
-#
-__revision__ = "src/engine/SCons/Util.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Util.py 5023 2010/06/14 22:05:46 scons"
-import copy
import os
-import os.path
-import re
-import string
import sys
+import copy
+import re
import types
-from UserDict import UserDict
-from UserList import UserList
-from UserString import UserString
+from collections import UserDict, UserList, UserString
# Don't "from types import ..." these because we need to get at the
# types module later to look for UnicodeType.
-DictType = types.DictType
InstanceType = types.InstanceType
-ListType = types.ListType
-StringType = types.StringType
-TupleType = types.TupleType
+MethodType = types.MethodType
+FunctionType = types.FunctionType
+try: unicode
+except NameError: UnicodeType = None
+else: UnicodeType = unicode
def dictify(keys, values, result={}):
for k, v in zip(keys, values):
@@ -59,11 +53,11 @@ if _altsep is None and sys.platform == 'win32':
# My ActivePython 2.0.1 doesn't set os.altsep! What gives?
_altsep = '/'
if _altsep:
- def rightmost_separator(path, sep, _altsep=_altsep):
- rfind = string.rfind
- return max(rfind(path, sep), rfind(path, _altsep))
+ def rightmost_separator(path, sep):
+ return max(path.rfind(sep), path.rfind(_altsep))
else:
- rightmost_separator = string.rfind
+ def rightmost_separator(path, sep):
+ return path.rfind(sep)
# First two from the Python Cookbook, just for completeness.
# (Yeah, yeah, YAGNI...)
@@ -88,7 +82,7 @@ def containsOnly(str, set):
def splitext(path):
"Same as os.path.splitext() but faster."
sep = rightmost_separator(path, os.sep)
- dot = string.rfind(path, '.')
+ dot = path.rfind('.')
# An ext is only real if it has at least one non-digit char
if dot > sep and not containsOnly(path[dot:], "0123456789."):
return path[:dot],path[dot:]
@@ -104,7 +98,7 @@ def updrive(path):
"""
drive, rest = os.path.splitdrive(path)
if drive:
- path = string.upper(drive) + rest
+ path = drive.upper() + rest
return path
class NodeList(UserList):
@@ -121,20 +115,17 @@ class NodeList(UserList):
return len(self.data) != 0
def __str__(self):
- return string.join(map(str, self.data))
+ return ' '.join(map(str, self.data))
def __iter__(self):
return iter(self.data)
def __call__(self, *args, **kwargs):
- result = map(lambda x, args=args, kwargs=kwargs: apply(x,
- args,
- kwargs),
- self.data)
+ result = [x(*args, **kwargs) for x in self.data]
return self.__class__(result)
def __getattr__(self, name):
- result = map(lambda x, n=name: getattr(x, n), self.data)
+ result = [getattr(x, name) for x in self.data]
return self.__class__(result)
@@ -155,14 +146,14 @@ def get_environment_var(varstr):
else:
return None
-class DisplayEngine:
- def __init__(self):
- self.__call__ = self.print_it
-
- def print_it(self, text, append_newline=1):
+class DisplayEngine(object):
+ print_it = True
+ def __call__(self, text, append_newline=1):
+ if not self.print_it:
+ return
if append_newline: text = text + '\n'
try:
- sys.stdout.write(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
@@ -173,14 +164,8 @@ class DisplayEngine:
# before SCons exits.
pass
- def dont_print(self, text, append_newline=1):
- pass
-
def set_mode(self, mode):
- if mode:
- self.__call__ = self.print_it
- else:
- self.__call__ = self.dont_print
+ self.print_it = mode
def render_tree(root, child_func, prune=0, margin=[0], visited={}):
"""
@@ -204,7 +189,7 @@ def render_tree(root, child_func, prune=0, margin=[0], visited={}):
else:
retval = retval + " "
- if visited.has_key(rname):
+ if rname in visited:
return retval + "+-[" + rname + "]\n"
retval = retval + "+-" + rname + "\n"
@@ -243,17 +228,18 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}):
if showtags:
if showtags == 2:
- print ' E = exists'
- print ' R = exists in repository only'
- print ' b = implicit builder'
- print ' B = explicit builder'
- print ' S = side effect'
- print ' P = precious'
- print ' A = always build'
- print ' C = current'
- print ' N = no clean'
- print ' H = no cache'
- print ''
+ legend = (' E = exists\n' +
+ ' R = exists in repository only\n' +
+ ' b = implicit builder\n' +
+ ' B = explicit builder\n' +
+ ' S = side effect\n' +
+ ' P = precious\n' +
+ ' A = always build\n' +
+ ' C = current\n' +
+ ' N = no clean\n' +
+ ' H = no cache\n' +
+ '\n')
+ sys.stdout.write(unicode(legend))
tags = ['[']
tags.append(' E'[IDX(root.exists())])
@@ -273,15 +259,15 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}):
def MMM(m):
return [" ","| "][m]
- margins = map(MMM, margin[:-1])
+ margins = list(map(MMM, margin[:-1]))
children = child_func(root)
- if prune and visited.has_key(rname) and children:
- print string.join(tags + margins + ['+-[', rname, ']'], '')
+ if prune and rname in visited and children:
+ sys.stdout.write(''.join(tags + margins + ['+-[', rname, ']']) + u'\n')
return
- print string.join(tags + margins + ['+-', rname], '')
+ sys.stdout.write(''.join(tags + margins + ['+-', rname]) + u'\n')
visited[rname] = 1
@@ -304,273 +290,137 @@ def print_tree(root, child_func, prune=0, showtags=0, margin=[0], visited={}):
# exception, but handling the exception when it's not the right type is
# often too slow.
-try:
- class mystr(str):
- pass
-except TypeError:
- # An older Python version without new-style classes.
- #
- # The actual implementations here have been selected after timings
- # coded up in in bench/is_types.py (from the SCons source tree,
- # see the scons-src distribution), mostly against Python 1.5.2.
- # Key results from those timings:
- #
- # -- Storing the type of the object in a variable (t = type(obj))
- # slows down the case where it's a native type and the first
- # comparison will match, but nicely speeds up the case where
- # it's a different native type. Since that's going to be
- # common, it's a good tradeoff.
- #
- # -- The data show that calling isinstance() on an object that's
- # a native type (dict, list or string) is expensive enough
- # that checking up front for whether the object is of type
- # InstanceType is a pretty big win, even though it does slow
- # down the case where it really *is* an object instance a
- # little bit.
- def is_Dict(obj):
- t = type(obj)
- return t is DictType or \
- (t is InstanceType and isinstance(obj, UserDict))
-
- def is_List(obj):
- t = type(obj)
- return t is ListType \
- or (t is InstanceType and isinstance(obj, UserList))
-
- def is_Sequence(obj):
- t = type(obj)
- return t is ListType \
- or t is TupleType \
- or (t is InstanceType and isinstance(obj, UserList))
-
- def is_Tuple(obj):
- t = type(obj)
- return t is TupleType
-
- if hasattr(types, 'UnicodeType'):
- def is_String(obj):
- t = type(obj)
- return t is StringType \
- or t is UnicodeType \
- or (t is InstanceType and isinstance(obj, UserString))
- else:
- def is_String(obj):
- t = type(obj)
- return t is StringType \
- or (t is InstanceType and isinstance(obj, UserString))
-
- def is_Scalar(obj):
- return is_String(obj) or not is_Sequence(obj)
-
- def flatten(obj, result=None):
- """Flatten a sequence to a non-nested list.
-
- Flatten() converts either a single scalar or a nested sequence
- to a non-nested list. Note that flatten() considers strings
- to be scalars instead of sequences like Python would.
- """
- if is_Scalar(obj):
- return [obj]
- if result is None:
- result = []
- for item in obj:
- if is_Scalar(item):
- result.append(item)
- else:
- flatten_sequence(item, result)
- return result
-
- def flatten_sequence(sequence, result=None):
- """Flatten a sequence to a non-nested list.
-
- Same as flatten(), but it does not handle the single scalar
- case. This is slightly more efficient when one knows that
- the sequence to flatten can not be a scalar.
- """
- if result is None:
- result = []
- for item in sequence:
- if is_Scalar(item):
- result.append(item)
- else:
- flatten_sequence(item, result)
- return result
-
- #
- # Generic convert-to-string functions that abstract away whether or
- # not the Python we're executing has Unicode support. The wrapper
- # to_String_for_signature() will use a for_signature() method if the
- # specified object has one.
- #
- if hasattr(types, 'UnicodeType'):
- UnicodeType = types.UnicodeType
- def to_String(s):
- if isinstance(s, UserString):
- t = type(s.data)
- else:
- t = type(s)
- if t is UnicodeType:
- return unicode(s)
- else:
- return str(s)
- else:
- to_String = str
-
- def to_String_for_signature(obj):
- try:
- f = obj.for_signature
- except AttributeError:
- return to_String_for_subst(obj)
+# We are using the following trick to speed up these
+# functions. Default arguments are used to take a snapshot of the
+# the global functions and constants used by these functions. This
+# transforms accesses to global variable into local variables
+# accesses (i.e. LOAD_FAST instead of LOAD_GLOBAL).
+
+DictTypes = (dict, UserDict)
+ListTypes = (list, UserList)
+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)
+
+# Empirically, it is faster to check explicitely for str and
+# unicode than for basestring.
+BaseStringTypes = (str, unicode)
+
+def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes):
+ return isinstance(obj, DictTypes)
+
+def is_List(obj, isinstance=isinstance, ListTypes=ListTypes):
+ return isinstance(obj, ListTypes)
+
+def is_Sequence(obj, isinstance=isinstance, SequenceTypes=SequenceTypes):
+ return isinstance(obj, SequenceTypes)
+
+def is_Tuple(obj, isinstance=isinstance, tuple=tuple):
+ return isinstance(obj, tuple)
+
+def is_String(obj, isinstance=isinstance, StringTypes=StringTypes):
+ return isinstance(obj, StringTypes)
+
+def is_Scalar(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes):
+ # Profiling shows that there is an impressive speed-up of 2x
+ # when explicitely checking for strings instead of just not
+ # sequence when the argument (i.e. obj) is already a string.
+ # But, if obj is a not string then it is twice as fast to
+ # check only for 'not sequence'. The following code therefore
+ # 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,
+ StringTypes=StringTypes, SequenceTypes=SequenceTypes):
+ for item in sequence:
+ if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
+ result.append(item)
else:
- return f()
-
- def to_String_for_subst(s):
- if is_Sequence( s ):
- return string.join( map(to_String_for_subst, s) )
-
- return to_String( s )
-
-else:
- # A modern Python version with new-style classes, so we can just use
- # isinstance().
- #
- # We are using the following trick to speed-up these
- # functions. Default arguments are used to take a snapshot of the
- # the global functions and constants used by these functions. This
- # transforms accesses to global variable into local variables
- # accesses (i.e. LOAD_FAST instead of LOAD_GLOBAL).
-
- DictTypes = (dict, UserDict)
- ListTypes = (list, UserList)
- SequenceTypes = (list, tuple, UserList)
-
- # Empirically, Python versions with new-style classes all have
- # unicode.
- #
- # 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)
-
- # Empirically, it is faster to check explicitely for str and
- # unicode than for basestring.
- BaseStringTypes = (str, unicode)
-
- def is_Dict(obj, isinstance=isinstance, DictTypes=DictTypes):
- return isinstance(obj, DictTypes)
-
- def is_List(obj, isinstance=isinstance, ListTypes=ListTypes):
- return isinstance(obj, ListTypes)
-
- def is_Sequence(obj, isinstance=isinstance, SequenceTypes=SequenceTypes):
- return isinstance(obj, SequenceTypes)
-
- def is_Tuple(obj, isinstance=isinstance, tuple=tuple):
- return isinstance(obj, tuple)
-
- def is_String(obj, isinstance=isinstance, StringTypes=StringTypes):
- return isinstance(obj, StringTypes)
-
- def is_Scalar(obj, isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes):
- # Profiling shows that there is an impressive speed-up of 2x
- # when explicitely checking for strings instead of just not
- # sequence when the argument (i.e. obj) is already a string.
- # But, if obj is a not string than it is twice as fast to
- # check only for 'not sequence'. The following code therefore
- # 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,
- StringTypes=StringTypes, SequenceTypes=SequenceTypes):
- for item in sequence:
- if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
- result.append(item)
- else:
- do_flatten(item, result)
-
- def flatten(obj, isinstance=isinstance, StringTypes=StringTypes,
- SequenceTypes=SequenceTypes, do_flatten=do_flatten):
- """Flatten a sequence to a non-nested list.
-
- Flatten() converts either a single scalar or a nested sequence
- to a non-nested list. Note that flatten() considers strings
- to be scalars instead of sequences like Python would.
- """
- if isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes):
- return [obj]
- result = []
- for item in obj:
- if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
- result.append(item)
- else:
- do_flatten(item, result)
- return result
+ do_flatten(item, result)
- def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes,
- SequenceTypes=SequenceTypes, do_flatten=do_flatten):
- """Flatten a sequence to a non-nested list.
+def flatten(obj, isinstance=isinstance, StringTypes=StringTypes,
+ SequenceTypes=SequenceTypes, do_flatten=do_flatten):
+ """Flatten a sequence to a non-nested list.
- Same as flatten(), but it does not handle the single scalar
- case. This is slightly more efficient when one knows that
- the sequence to flatten can not be a scalar.
- """
- result = []
- for item in sequence:
- if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
- result.append(item)
- else:
- do_flatten(item, result)
- return result
+ Flatten() converts either a single scalar or a nested sequence
+ to a non-nested list. Note that flatten() considers strings
+ to be scalars instead of sequences like Python would.
+ """
+ if isinstance(obj, StringTypes) or not isinstance(obj, SequenceTypes):
+ return [obj]
+ result = []
+ for item in obj:
+ if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
+ result.append(item)
+ else:
+ do_flatten(item, result)
+ return result
+def flatten_sequence(sequence, isinstance=isinstance, StringTypes=StringTypes,
+ SequenceTypes=SequenceTypes, do_flatten=do_flatten):
+ """Flatten a sequence to a non-nested list.
- #
- # Generic convert-to-string functions that abstract away whether or
- # not the Python we're executing has Unicode support. The wrapper
- # to_String_for_signature() will use a for_signature() method if the
- # specified object has one.
- #
- def to_String(s,
- isinstance=isinstance, str=str,
- UserString=UserString, BaseStringTypes=BaseStringTypes):
- if isinstance(s,BaseStringTypes):
- # Early out when already a string!
- return s
- elif isinstance(s, UserString):
- # s.data can only be either a unicode or a regular
- # string. Please see the UserString initializer.
- return s.data
- else:
- return str(s)
-
- def to_String_for_subst(s,
- isinstance=isinstance, join=string.join, 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
- elif isinstance(s, SequenceTypes):
- l = []
- for e in s:
- l.append(to_String_for_subst(e))
- return join( s )
- elif isinstance(s, UserString):
- # s.data can only be either a unicode or a regular
- # string. Please see the UserString initializer.
- return s.data
+ Same as flatten(), but it does not handle the single scalar
+ case. This is slightly more efficient when one knows that
+ the sequence to flatten can not be a scalar.
+ """
+ result = []
+ for item in sequence:
+ if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes):
+ result.append(item)
else:
- return str(s)
+ do_flatten(item, result)
+ return result
- def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst,
- AttributeError=AttributeError):
- try:
- f = obj.for_signature
- except AttributeError:
- return to_String_for_subst(obj)
- else:
- return f()
+# Generic convert-to-string functions that abstract away whether or
+# not the Python we're executing has Unicode support. The wrapper
+# to_String_for_signature() will use a for_signature() method if the
+# specified object has one.
+#
+def to_String(s,
+ isinstance=isinstance, str=str,
+ UserString=UserString, BaseStringTypes=BaseStringTypes):
+ if isinstance(s,BaseStringTypes):
+ # Early out when already a string!
+ return s
+ elif isinstance(s, UserString):
+ # s.data can only be either a unicode or a regular
+ # string. Please see the UserString initializer.
+ return s.data
+ else:
+ return str(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
+ elif isinstance(s, SequenceTypes):
+ l = []
+ for e in s:
+ l.append(to_String_for_subst(e))
+ return ' '.join( s )
+ elif isinstance(s, UserString):
+ # s.data can only be either a unicode or a regular
+ # string. Please see the UserString initializer.
+ return s.data
+ else:
+ return str(s)
+def to_String_for_signature(obj, to_String_for_subst=to_String_for_subst,
+ AttributeError=AttributeError):
+ try:
+ f = obj.for_signature
+ except AttributeError:
+ return to_String_for_subst(obj)
+ else:
+ return f()
# The SCons "semi-deep" copy.
@@ -599,15 +449,15 @@ def _semi_deepcopy_dict(x):
# Doesn't seem like we need to, but we'll comment it just in case.
copy[key] = semi_deepcopy(val)
return copy
-d[types.DictionaryType] = _semi_deepcopy_dict
+d[dict] = _semi_deepcopy_dict
def _semi_deepcopy_list(x):
- return map(semi_deepcopy, x)
-d[types.ListType] = _semi_deepcopy_list
+ return list(map(semi_deepcopy, x))
+d[list] = _semi_deepcopy_list
def _semi_deepcopy_tuple(x):
return tuple(map(semi_deepcopy, x))
-d[types.TupleType] = _semi_deepcopy_tuple
+d[tuple] = _semi_deepcopy_tuple
def _semi_deepcopy_inst(x):
if hasattr(x, '__semi_deepcopy__'):
@@ -618,7 +468,7 @@ def _semi_deepcopy_inst(x):
return x.__class__(_semi_deepcopy_list(x))
else:
return x
-d[types.InstanceType] = _semi_deepcopy_inst
+d[InstanceType] = _semi_deepcopy_inst
def semi_deepcopy(x):
copier = _semi_deepcopy_dispatch.get(type(x))
@@ -629,7 +479,7 @@ def semi_deepcopy(x):
-class Proxy:
+class Proxy(object):
"""A simple generic Proxy class, forwarding all calls to
subject. So, for the benefit of the python newbie, what does
this really mean? Well, it means that you can take an object, let's
@@ -647,39 +497,65 @@ class Proxy:
x = objA.var1
- Inherit from this class to create a Proxy."""
+ Inherit from this class to create a Proxy.
+
+ Note that, with new-style classes, this does *not* work transparently
+ for Proxy subclasses that use special .__*__() method names, because
+ those names are now bound to the class, not the individual instances.
+ You now need to know in advance which .__*__() method names you want
+ to pass on to the underlying Proxy object, and specifically delegate
+ their calls like this:
+
+ class Foo(Proxy):
+ __str__ = Delegate('__str__')
+ """
def __init__(self, subject):
"""Wrap an object as a Proxy object"""
- self.__subject = subject
+ self._subject = subject
def __getattr__(self, name):
"""Retrieve an attribute from the wrapped object. If the named
attribute doesn't exist, AttributeError is raised"""
- return getattr(self.__subject, name)
+ return getattr(self._subject, name)
def get(self):
"""Retrieve the entire wrapped object"""
- return self.__subject
+ return self._subject
def __cmp__(self, other):
- if issubclass(other.__class__, self.__subject.__class__):
- return cmp(self.__subject, other)
+ if issubclass(other.__class__, self._subject.__class__):
+ return cmp(self._subject, other)
return cmp(self.__dict__, other.__dict__)
+class Delegate(object):
+ """A Python Descriptor class that delegates attribute fetches
+ to an underlying wrapped subject of a Proxy. Typical use:
+
+ class Foo(Proxy):
+ __str__ = Delegate('__str__')
+ """
+ def __init__(self, attribute):
+ self.attribute = attribute
+ def __get__(self, obj, cls):
+ if isinstance(obj, cls):
+ return getattr(obj._subject, self.attribute)
+ else:
+ return self
+
# attempt to load the windows registry module:
can_read_reg = 0
try:
- import _winreg
+ import winreg
can_read_reg = 1
- hkey_mod = _winreg
+ hkey_mod = winreg
- RegOpenKeyEx = _winreg.OpenKeyEx
- RegEnumKey = _winreg.EnumKey
- RegEnumValue = _winreg.EnumValue
- RegQueryValueEx = _winreg.QueryValueEx
- RegError = _winreg.error
+ RegOpenKeyEx = winreg.OpenKeyEx
+ RegEnumKey = winreg.EnumKey
+ RegEnumValue = winreg.EnumValue
+ RegQueryValueEx = winreg.QueryValueEx
+ RegError = winreg.error
except ImportError:
try:
@@ -741,8 +617,8 @@ else:
# OSError subclass on Windows.)
class WindowsError(OSError):
pass
- import __builtin__
- __builtin__.WindowsError = WindowsError
+ import builtins
+ builtins.WindowsError = WindowsError
else:
del e
@@ -766,16 +642,16 @@ if sys.platform == 'win32':
except KeyError:
return None
if is_String(path):
- path = string.split(path, os.pathsep)
+ path = path.split(os.pathsep)
if pathext is None:
try:
pathext = os.environ['PATHEXT']
except KeyError:
pathext = '.COM;.EXE;.BAT;.CMD'
if is_String(pathext):
- pathext = string.split(pathext, os.pathsep)
+ pathext = pathext.split(os.pathsep)
for ext in pathext:
- if string.lower(ext) == string.lower(file[-len(ext):]):
+ if ext.lower() == file[-len(ext):].lower():
pathext = ['']
break
if not is_List(reject) and not is_Tuple(reject):
@@ -801,11 +677,11 @@ elif os.name == 'os2':
except KeyError:
return None
if is_String(path):
- path = string.split(path, os.pathsep)
+ path = path.split(os.pathsep)
if pathext is None:
pathext = ['.exe', '.cmd']
for ext in pathext:
- if string.lower(ext) == string.lower(file[-len(ext):]):
+ if ext.lower() == file[-len(ext):].lower():
pathext = ['']
break
if not is_List(reject) and not is_Tuple(reject):
@@ -832,7 +708,7 @@ else:
except KeyError:
return None
if is_String(path):
- path = string.split(path, os.pathsep)
+ path = path.split(os.pathsep)
if not is_List(reject) and not is_Tuple(reject):
reject = [reject]
for d in path:
@@ -881,18 +757,18 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
is_list = 1
paths = orig
if not is_List(orig) and not is_Tuple(orig):
- paths = string.split(paths, sep)
+ paths = paths.split(sep)
is_list = 0
if is_String(newpath):
- newpaths = string.split(newpath, sep)
+ newpaths = newpath.split(sep)
elif not is_List(newpath) and not is_Tuple(newpath):
newpaths = [ newpath ] # might be a Dir
else:
newpaths = newpath
if canonicalize:
- newpaths=map(canonicalize, newpaths)
+ newpaths=list(map(canonicalize, newpaths))
if not delete_existing:
# First uniquify the old paths, making sure to
@@ -934,7 +810,7 @@ def PrependPath(oldpath, newpath, sep = os.pathsep,
if is_list:
return paths
else:
- return string.join(paths, sep)
+ return sep.join(paths)
def AppendPath(oldpath, newpath, sep = os.pathsep,
delete_existing=1, canonicalize=None):
@@ -962,18 +838,18 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
is_list = 1
paths = orig
if not is_List(orig) and not is_Tuple(orig):
- paths = string.split(paths, sep)
+ paths = paths.split(sep)
is_list = 0
if is_String(newpath):
- newpaths = string.split(newpath, sep)
+ newpaths = newpath.split(sep)
elif not is_List(newpath) and not is_Tuple(newpath):
newpaths = [ newpath ] # might be a Dir
else:
newpaths = newpath
if canonicalize:
- newpaths=map(canonicalize, newpaths)
+ newpaths=list(map(canonicalize, newpaths))
if not delete_existing:
# add old paths to result, then
@@ -1015,13 +891,13 @@ def AppendPath(oldpath, newpath, sep = os.pathsep,
if is_list:
return paths
else:
- return string.join(paths, sep)
+ return sep.join(paths)
if sys.platform == 'cygwin':
def get_native_path(path):
"""Transforms an absolute path into a native path for the system. In
Cygwin, this converts from a Cygwin path to a Windows one."""
- return string.replace(os.popen('cygpath -w ' + path).read(), '\n', '')
+ return os.popen('cygpath -w ' + path).read().replace('\n', '')
else:
def get_native_path(path):
"""Transforms an absolute path into a native path for the system.
@@ -1034,7 +910,7 @@ def Split(arg):
if is_List(arg) or is_Tuple(arg):
return arg
elif is_String(arg):
- return string.split(arg)
+ return arg.split()
else:
return [arg]
@@ -1057,7 +933,7 @@ class CLVar(UserList):
def __coerce__(self, other):
return (self, CLVar(other))
def __str__(self):
- return string.join(self.data)
+ return ' '.join(self.data)
# A dictionary that preserves the order in which items are added.
# Submitted by David Benjamin to ActiveState's Python Cookbook web site:
@@ -1086,7 +962,7 @@ class OrderedDict(UserDict):
return dict
def items(self):
- return zip(self._keys, self.values())
+ return list(zip(self._keys, list(self.values())))
def keys(self):
return self._keys[:]
@@ -1111,7 +987,7 @@ class OrderedDict(UserDict):
self.__setitem__(key, val)
def values(self):
- return map(self.get, self._keys)
+ return list(map(self.get, self._keys))
class Selector(OrderedDict):
"""A callable ordered dictionary that maps file suffixes to
@@ -1132,12 +1008,12 @@ class Selector(OrderedDict):
for (k,v) in self.items():
if k is not None:
s_k = env.subst(k)
- if s_dict.has_key(s_k):
+ if s_k in s_dict:
# We only raise an error when variables point
# to the same suffix. If one suffix is literal
# and a variable suffix contains this literal,
# the literal wins and we don't raise an error.
- raise KeyError, (s_dict[s_k][0], k, s_k)
+ raise KeyError(s_dict[s_k][0], k, s_k)
s_dict[s_k] = (k,v)
try:
return s_dict[ext][1]
@@ -1213,7 +1089,7 @@ def unique(s):
except TypeError:
pass # move on to the next method
else:
- return u.keys()
+ return list(u.keys())
del u
# We can't hash all the elements. Second fastest is to sort,
@@ -1224,8 +1100,7 @@ def unique(s):
# sort functions in all languages or libraries, so this approach
# is more effective in Python than it may be elsewhere.
try:
- t = list(s)
- t.sort()
+ t = sorted(s)
except TypeError:
pass # move on to the next method
else:
@@ -1279,7 +1154,7 @@ def uniquer_hashables(seq):
result = []
for item in seq:
#if not item in seen:
- if not seen.has_key(item):
+ if item not in seen:
seen[item] = 1
result.append(item)
return result
@@ -1288,14 +1163,14 @@ def uniquer_hashables(seq):
# Much of the logic here was originally based on recipe 4.9 from the
# Python CookBook, but we had to dumb it way down for Python 1.5.2.
-class LogicalLines:
+class LogicalLines(object):
def __init__(self, fileobj):
self.fileobj = fileobj
def readline(self):
result = []
- while 1:
+ while True:
line = self.fileobj.readline()
if not line:
break
@@ -1304,11 +1179,11 @@ class LogicalLines:
else:
result.append(line)
break
- return string.join(result, '')
+ return ''.join(result)
def readlines(self):
result = []
- while 1:
+ while True:
line = self.readline()
if not line:
break
@@ -1402,21 +1277,20 @@ class UniqueList(UserList):
UserList.reverse(self)
def sort(self, *args, **kwds):
self.__make_unique()
- #return UserList.sort(self, *args, **kwds)
- return apply(UserList.sort, (self,)+args, kwds)
+ return UserList.sort(self, *args, **kwds)
def extend(self, other):
UserList.extend(self, other)
self.unique = False
-
-class Unbuffered:
+class Unbuffered(object):
"""
A proxy class that wraps a file object, flushing after every write,
and delegating everything else to the wrapped object.
"""
def __init__(self, file):
self.file = file
+ self.softspace = 0 ## backward compatibility; not supported in Py3k
def write(self, arg):
try:
self.file.write(arg)
@@ -1474,7 +1348,7 @@ def make_path_relative(path):
# ASPN: Python Cookbook : Dynamically added methods to a class
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/81732
-def AddMethod(object, function, name = None):
+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
@@ -1489,40 +1363,27 @@ def AddMethod(object, function, name = None):
AddMethod(lambda self, i: self.l[i], a, "listIndex")
print a.listIndex(5)
"""
- import new
-
if name is None:
name = function.func_name
else:
function = RenameFunction(function, name)
- try:
- klass = object.__class__
- except AttributeError:
- # "object" is really a class, so it gets an unbound method.
- object.__dict__[name] = new.instancemethod(function, None, object)
+ 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__))
else:
- # "object" is really an instance, so it gets a bound method.
- object.__dict__[name] = new.instancemethod(function, object, klass)
+ # "obj" is a class, so it gets an unbound method.
+ setattr(obj, name, MethodType(function, None, obj))
def RenameFunction(function, name):
"""
Returns a function identical to the specified function, but with
the specified name.
"""
- import new
-
- # Compatibility for Python 1.5 and 2.1. Can be removed in favor of
- # passing function.func_defaults directly to new.function() once
- # we base on Python 2.2 or later.
- func_defaults = function.func_defaults
- if func_defaults is None:
- func_defaults = ()
-
- return new.function(function.func_code,
+ return FunctionType(function.func_code,
function.func_globals,
name,
- func_defaults)
+ function.func_defaults)
md5 = False
@@ -1550,7 +1411,7 @@ else:
def MD5filesignature(fname, chunksize=65536):
m = hashlib.md5()
f = open(fname, "rb")
- while 1:
+ while True:
blck = f.read(chunksize)
if not blck:
break
@@ -1568,26 +1429,18 @@ def MD5collect(signatures):
if len(signatures) == 1:
return signatures[0]
else:
- return MD5signature(string.join(signatures, ', '))
+ return MD5signature(', '.join(signatures))
-# Wrap the intern() function so it doesn't throw exceptions if ineligible
-# arguments are passed. The intern() function was moved into the sys module in
-# Python 3.
-try:
- intern
-except NameError:
- from sys import intern
-
def silent_intern(x):
"""
- Perform intern() on the passed argument and return the result.
+ Perform sys.intern() on the passed argument and return the result.
If the input is ineligible (e.g. a unicode string) the original argument is
returned and no exception is thrown.
"""
try:
- return intern(x)
+ return sys.intern(x)
except TypeError:
return x
@@ -1599,15 +1452,13 @@ def silent_intern(x):
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68205
# ASPN: Python Cookbook: Null Object Design Pattern
-# TODO(1.5):
-#class Null(object):
-class Null:
+#TODO??? class Null(object):
+class Null(object):
""" Null objects always and reliably "do nothing." """
def __new__(cls, *args, **kwargs):
- if not '_inst' in vars(cls):
- #cls._inst = type.__new__(cls, *args, **kwargs)
- cls._inst = apply(type.__new__, (cls,) + args, kwargs)
- return cls._inst
+ if not '_instance' in vars(cls):
+ cls._instance = super(Null, cls).__new__(cls, *args, **kwargs)
+ return cls._instance
def __init__(self, *args, **kwargs):
pass
def __call__(self, *args, **kwargs):
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
index ec29064..4896114 100644
--- a/src/engine/SCons/UtilTests.py
+++ b/src/engine/SCons/UtilTests.py
@@ -21,17 +21,15 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/UtilTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/UtilTests.py 5023 2010/06/14 22:05:46 scons"
+import SCons.compat
+
+import io
import os
-import os.path
-import string
-import StringIO
import sys
-import types
import unittest
-
-from UserDict import UserDict
+from collections import UserDict, UserList, UserString
import TestCmd
@@ -39,7 +37,11 @@ import SCons.Errors
from SCons.Util import *
-class OutBuffer:
+try: eval('unicode')
+except NameError: HasUnicode = False
+else: HasUnicode = True
+
+class OutBuffer(object):
def __init__(self):
self.buffer = ""
@@ -64,7 +66,7 @@ class UtilTestCase(unittest.TestCase):
assert splitext('foo.bar') == ('foo','.bar')
assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'')
- class Node:
+ class Node(object):
def __init__(self, name, children=[]):
self.children = children
self.name = name
@@ -112,9 +114,9 @@ class UtilTestCase(unittest.TestCase):
+-windows.h
"""
- lines = string.split(expect, '\n')[:-1]
- lines = map(lambda l: '[E BSPACN ]'+l, lines)
- withtags = string.join(lines, '\n') + '\n'
+ lines = expect.split('\n')[:-1]
+ lines = ['[E BSPACN ]'+l for l in lines]
+ withtags = '\n'.join(lines) + '\n'
return foo, expect, withtags
@@ -137,12 +139,12 @@ class UtilTestCase(unittest.TestCase):
"""
if not prune:
- expect = string.replace(expect, '[', '')
- expect = string.replace(expect, ']', '')
+ expect = expect.replace('[', '')
+ expect = expect.replace(']', '')
- lines = string.split(expect, '\n')[:-1]
- lines = map(lambda l: '[E BSPACN ]'+l, lines)
- withtags = string.join(lines, '\n') + '\n'
+ lines = expect.split('\n')[:-1]
+ lines = ['[E BSPACN ]'+l for l in lines]
+ withtags = '\n'.join(lines) + '\n'
return blat_o, expect, withtags
@@ -169,24 +171,24 @@ class UtilTestCase(unittest.TestCase):
try:
node, expect, withtags = self.tree_case_1()
- sys.stdout = StringIO.StringIO()
+ sys.stdout = io.StringIO()
print_tree(node, get_children)
actual = sys.stdout.getvalue()
assert expect == actual, (expect, actual)
- sys.stdout = StringIO.StringIO()
+ sys.stdout = io.StringIO()
print_tree(node, get_children, showtags=1)
actual = sys.stdout.getvalue()
assert withtags == actual, (withtags, actual)
node, expect, withtags = self.tree_case_2(prune=0)
- sys.stdout = StringIO.StringIO()
+ sys.stdout = io.StringIO()
print_tree(node, get_children, 1)
actual = sys.stdout.getvalue()
assert expect == actual, (expect, actual)
- sys.stdout = StringIO.StringIO()
+ sys.stdout = io.StringIO()
# The following call should work here:
# print_tree(node, get_children, 1, showtags=1)
# For some reason I don't understand, though, *this*
@@ -205,6 +207,7 @@ class UtilTestCase(unittest.TestCase):
def test_is_Dict(self):
assert is_Dict({})
assert is_Dict(UserDict())
+ assert is_Dict(os.environ)
try:
class mydict(dict):
pass
@@ -215,13 +218,12 @@ class UtilTestCase(unittest.TestCase):
assert not is_Dict([])
assert not is_Dict(())
assert not is_Dict("")
- if hasattr(types, 'UnicodeType'):
+ if HasUnicode:
exec "assert not is_Dict(u'')"
def test_is_List(self):
assert is_List([])
- import UserList
- assert is_List(UserList.UserList())
+ assert is_List(UserList())
try:
class mylist(list):
pass
@@ -232,19 +234,14 @@ class UtilTestCase(unittest.TestCase):
assert not is_List(())
assert not is_List({})
assert not is_List("")
- if hasattr(types, 'UnicodeType'):
+ if HasUnicode:
exec "assert not is_List(u'')"
def test_is_String(self):
assert is_String("")
- if hasattr(types, 'UnicodeType'):
+ if HasUnicode:
exec "assert is_String(u'')"
- try:
- import UserString
- except:
- pass
- else:
- assert is_String(UserString.UserString(''))
+ assert is_String(UserString(''))
try:
class mystr(str):
pass
@@ -268,7 +265,7 @@ class UtilTestCase(unittest.TestCase):
assert not is_Tuple([])
assert not is_Tuple({})
assert not is_Tuple("")
- if hasattr(types, 'UnicodeType'):
+ if HasUnicode:
exec "assert not is_Tuple(u'')"
def test_to_String(self):
@@ -277,32 +274,27 @@ class UtilTestCase(unittest.TestCase):
assert to_String([ 1, 2, 3]) == str([1, 2, 3]), to_String([1,2,3])
assert to_String("foo") == "foo", to_String("foo")
- try:
- import UserString
-
- s1=UserString.UserString('blah')
- assert to_String(s1) == s1, s1
- assert to_String(s1) == 'blah', s1
+ s1=UserString('blah')
+ assert to_String(s1) == s1, s1
+ assert to_String(s1) == 'blah', s1
- class Derived(UserString.UserString):
- pass
- s2 = Derived('foo')
- assert to_String(s2) == s2, s2
- assert to_String(s2) == 'foo', s2
-
- if hasattr(types, 'UnicodeType'):
- s3=UserString.UserString(unicode('bar'))
- assert to_String(s3) == s3, s3
- assert to_String(s3) == unicode('bar'), s3
- assert type(to_String(s3)) is types.UnicodeType, \
- type(to_String(s3))
- except ImportError:
+ class Derived(UserString):
pass
-
- if hasattr(types, 'UnicodeType'):
+ s2 = Derived('foo')
+ assert to_String(s2) == s2, s2
+ assert to_String(s2) == 'foo', s2
+
+ if HasUnicode:
+ s3=UserString(unicode('bar'))
+ assert to_String(s3) == s3, s3
+ assert to_String(s3) == unicode('bar'), s3
+ assert isinstance(to_String(s3), unicode), \
+ type(to_String(s3))
+
+ if HasUnicode:
s4 = unicode('baz')
assert to_String(s4) == unicode('baz'), to_String(s4)
- assert type(to_String(s4)) is types.UnicodeType, \
+ assert isinstance(to_String(s4), unicode), \
type(to_String(s4))
def test_WhereIs(self):
@@ -333,20 +325,20 @@ class UtilTestCase(unittest.TestCase):
test.workpath('sub2'),
test.workpath('sub3'),
test.workpath('sub4'),
- ] + string.split(env_path, os.pathsep)
+ ] + env_path.split(os.pathsep)
pathdirs_1243 = [ test.workpath('sub1'),
test.workpath('sub2'),
test.workpath('sub4'),
test.workpath('sub3'),
- ] + string.split(env_path, os.pathsep)
+ ] + env_path.split(os.pathsep)
- os.environ['PATH'] = string.join(pathdirs_1234, os.pathsep)
+ os.environ['PATH'] = os.pathsep.join(pathdirs_1234)
wi = WhereIs('xxx.exe')
assert wi == test.workpath(sub3_xxx_exe), wi
wi = WhereIs('xxx.exe', pathdirs_1243)
assert wi == test.workpath(sub4_xxx_exe), wi
- wi = WhereIs('xxx.exe', string.join(pathdirs_1243, os.pathsep))
+ wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1243))
assert wi == test.workpath(sub4_xxx_exe), wi
wi = WhereIs('xxx.exe',reject = sub3_xxx_exe)
@@ -354,12 +346,12 @@ class UtilTestCase(unittest.TestCase):
wi = WhereIs('xxx.exe', pathdirs_1243, reject = sub3_xxx_exe)
assert wi == test.workpath(sub4_xxx_exe), wi
- os.environ['PATH'] = string.join(pathdirs_1243, os.pathsep)
+ os.environ['PATH'] = os.pathsep.join(pathdirs_1243)
wi = WhereIs('xxx.exe')
assert wi == test.workpath(sub4_xxx_exe), wi
wi = WhereIs('xxx.exe', pathdirs_1234)
assert wi == test.workpath(sub3_xxx_exe), wi
- wi = WhereIs('xxx.exe', string.join(pathdirs_1234, os.pathsep))
+ wi = WhereIs('xxx.exe', os.pathsep.join(pathdirs_1234))
assert wi == test.workpath(sub3_xxx_exe), wi
if sys.platform == 'win32':
@@ -370,13 +362,13 @@ class UtilTestCase(unittest.TestCase):
assert wi == test.workpath(sub4_xxx_exe), wi
wi = WhereIs('xxx', path = pathdirs_1234, pathext = '.BAT;.EXE')
- assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+ assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
# Test that we return a normalized path even when
# the path contains forward slashes.
forward_slash = test.workpath('') + '/sub3'
wi = WhereIs('xxx', path = forward_slash, pathext = '.EXE')
- assert string.lower(wi) == string.lower(test.workpath(sub3_xxx_exe)), wi
+ assert wi.lower() == test.workpath(sub3_xxx_exe).lower(), wi
del os.environ['PATH']
wi = WhereIs('xxx.exe')
@@ -399,7 +391,7 @@ class UtilTestCase(unittest.TestCase):
def test_Proxy(self):
"""Test generic Proxy class."""
- class Subject:
+ class Subject(object):
def foo(self):
return 1
def bar(self):
@@ -595,7 +587,7 @@ class UtilTestCase(unittest.TestCase):
def test_Selector(self):
"""Test the Selector class"""
- class MyNode:
+ class MyNode(object):
def __init__(self, name):
self.name = name
self.suffix = os.path.splitext(name)[1]
@@ -676,7 +668,7 @@ class UtilTestCase(unittest.TestCase):
def test_LogicalLines(self):
"""Test the LogicalLines class"""
- fobj = StringIO.StringIO(r"""
+ fobj = io.StringIO(r"""
foo \
bar \
baz
@@ -697,7 +689,7 @@ bling
def test_intern(self):
s1 = silent_intern("spam")
- # Python 1.5 and 3.x do not have a unicode() built-in
+ # Python 3.x does not have a unicode() global function
if sys.version[0] == '2':
s2 = silent_intern(unicode("unicode spam"))
s3 = silent_intern(42)
@@ -710,7 +702,7 @@ class MD5TestCase(unittest.TestCase):
def test_collect(self):
"""Test collecting a list of signatures into a new signature value
"""
- s = map(MD5signature, ('111', '222', '333'))
+ s = list(map(MD5signature, ('111', '222', '333')))
assert '698d51a19d8a121ce581499d7b701668' == MD5collect(s[0:1])
assert '8980c988edc2c78cc43ccb718c06efd5' == MD5collect(s[0:2])
@@ -727,7 +719,7 @@ class MD5TestCase(unittest.TestCase):
class NodeListTestCase(unittest.TestCase):
def test_simple_attributes(self):
"""Test simple attributes of a NodeList class"""
- class TestClass:
+ class TestClass(object):
def __init__(self, name, child=None):
self.child = child
self.bar = name
@@ -743,7 +735,7 @@ class NodeListTestCase(unittest.TestCase):
def test_callable_attributes(self):
"""Test callable attributes of a NodeList class"""
- class TestClass:
+ class TestClass(object):
def __init__(self, name, child=None):
self.child = child
self.bar = name
@@ -771,7 +763,7 @@ class NodeListTestCase(unittest.TestCase):
r = str(nl)
assert r == '', r
for node in nl:
- raise Exception, "should not enter this loop"
+ raise Exception("should not enter this loop")
class flattenTestCase(unittest.TestCase):
@@ -791,7 +783,7 @@ if __name__ == "__main__":
]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Variables/BoolVariable.py b/src/engine/SCons/Variables/BoolVariable.py
index c002fb9..2eeda77 100644
--- a/src/engine/SCons/Variables/BoolVariable.py
+++ b/src/engine/SCons/Variables/BoolVariable.py
@@ -34,12 +34,10 @@ Usage example:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/BoolVariable.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/BoolVariable.py 5023 2010/06/14 22:05:46 scons"
__all__ = ['BoolVariable',]
-import string
-
import SCons.Errors
__true_strings = ('y', 'yes', 'true', 't', '1', 'on' , 'all' )
@@ -57,7 +55,7 @@ def _text2bool(val):
This is usable as 'converter' for SCons' Variables.
"""
- lval = string.lower(val)
+ lval = val.lower()
if lval in __true_strings: return True
if lval in __false_strings: return False
raise ValueError("Invalid value for boolean option: %s" % val)
diff --git a/src/engine/SCons/Variables/BoolVariableTests.py b/src/engine/SCons/Variables/BoolVariableTests.py
index b11bf27..c2785ef 100644
--- a/src/engine/SCons/Variables/BoolVariableTests.py
+++ b/src/engine/SCons/Variables/BoolVariableTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/BoolVariableTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/BoolVariableTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
diff --git a/src/engine/SCons/Variables/EnumVariable.py b/src/engine/SCons/Variables/EnumVariable.py
index 2051bf1..9ae93fb 100644
--- a/src/engine/SCons/Variables/EnumVariable.py
+++ b/src/engine/SCons/Variables/EnumVariable.py
@@ -37,11 +37,10 @@ Usage example:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/EnumVariable.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/EnumVariable.py 5023 2010/06/14 22:05:46 scons"
__all__ = ['EnumVariable',]
-import string
import SCons.Errors
@@ -80,24 +79,21 @@ def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0):
given 'map'-dictionary (unmapped input values are returned
unchanged).
"""
- help = '%s (%s)' % (help, string.join(allowed_values, '|'))
+ help = '%s (%s)' % (help, '|'.join(allowed_values))
# define validator
if ignorecase >= 1:
- validator = lambda key, val, env, vals=allowed_values: \
- _validator(key, string.lower(val), env, vals)
+ validator = lambda key, val, env: \
+ _validator(key, val.lower(), env, allowed_values)
else:
- validator = lambda key, val, env, vals=allowed_values: \
- _validator(key, val, env, vals)
+ validator = lambda key, val, env: \
+ _validator(key, val, env, allowed_values)
# define converter
if ignorecase == 2:
- converter = lambda val, map=map: \
- string.lower(map.get(string.lower(val), val))
+ converter = lambda val: map.get(val.lower(), val).lower()
elif ignorecase == 1:
- converter = lambda val, map=map: \
- map.get(string.lower(val), val)
+ converter = lambda val: map.get(val.lower(), val)
else:
- converter = lambda val, map=map: \
- map.get(val, val)
+ converter = lambda val: map.get(val, val)
return (key, help, default, validator, converter)
# Local Variables:
diff --git a/src/engine/SCons/Variables/EnumVariableTests.py b/src/engine/SCons/Variables/EnumVariableTests.py
index 5262906..5297ed5 100644
--- a/src/engine/SCons/Variables/EnumVariableTests.py
+++ b/src/engine/SCons/Variables/EnumVariableTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/EnumVariableTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/EnumVariableTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
diff --git a/src/engine/SCons/Variables/ListVariable.py b/src/engine/SCons/Variables/ListVariable.py
index 3ed755f..dbd5f4b 100644
--- a/src/engine/SCons/Variables/ListVariable.py
+++ b/src/engine/SCons/Variables/ListVariable.py
@@ -45,26 +45,23 @@ Usage example:
# 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__ = "src/engine/SCons/Variables/ListVariable.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/ListVariable.py 5023 2010/06/14 22:05:46 scons"
# Know Bug: This should behave like a Set-Type, but does not really,
# since elements can occur twice.
__all__ = ['ListVariable',]
-import string
-import UserList
+import collections
import SCons.Util
-class _ListVariable(UserList.UserList):
+class _ListVariable(collections.UserList):
def __init__(self, initlist=[], allowedElems=[]):
- UserList.UserList.__init__(self, filter(None, initlist))
- self.allowedElems = allowedElems[:]
- self.allowedElems.sort()
+ collections.UserList.__init__(self, [_f for _f in initlist if _f])
+ self.allowedElems = sorted(allowedElems)
def __cmp__(self, other):
raise NotImplementedError
@@ -85,7 +82,7 @@ class _ListVariable(UserList.UserList):
if self.data == self.allowedElems:
return 'all'
else:
- return string.join(self, ',')
+ return ','.join(self)
def prepare_to_store(self):
return self.__str__()
@@ -97,12 +94,12 @@ def _converter(val, allowedElems, mapdict):
elif val == 'all':
val = allowedElems
else:
- val = filter(None, string.split(val, ','))
- val = map(lambda v, m=mapdict: m.get(v, v), val)
- notAllowed = filter(lambda v, aE=allowedElems: not v in aE, val)
+ val = [_f for _f in val.split(',') if _f]
+ val = [mapdict.get(v, v) for v in val]
+ notAllowed = [v for v in val if not v in allowedElems]
if notAllowed:
raise ValueError("Invalid value(s) for option: %s" %
- string.join(notAllowed, ','))
+ ','.join(notAllowed))
return _ListVariable(val, allowedElems)
@@ -122,15 +119,14 @@ def ListVariable(key, help, default, names, map={}):
A 'package list' option may either be 'all', 'none' or a list of
package names (separated by space).
"""
- names_str = 'allowed names: %s' % string.join(names, ' ')
+ names_str = 'allowed names: %s' % ' '.join(names)
if SCons.Util.is_List(default):
- default = string.join(default, ',')
- help = string.join(
- (help, '(all|none|comma-separated list of names)', names_str),
- '\n ')
+ default = ','.join(default)
+ help = '\n '.join(
+ (help, '(all|none|comma-separated list of names)', names_str))
return (key, help, default,
None, #_validator,
- lambda val, elems=names, m=map: _converter(val, elems, m))
+ lambda val: _converter(val, names, map))
# Local Variables:
# tab-width:4
diff --git a/src/engine/SCons/Variables/ListVariableTests.py b/src/engine/SCons/Variables/ListVariableTests.py
index 3d96cd0..3096e7e 100644
--- a/src/engine/SCons/Variables/ListVariableTests.py
+++ b/src/engine/SCons/Variables/ListVariableTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/ListVariableTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/ListVariableTests.py 5023 2010/06/14 22:05:46 scons"
import copy
import sys
diff --git a/src/engine/SCons/Variables/PackageVariable.py b/src/engine/SCons/Variables/PackageVariable.py
index 362f67e..d9ce2a6 100644
--- a/src/engine/SCons/Variables/PackageVariable.py
+++ b/src/engine/SCons/Variables/PackageVariable.py
@@ -50,12 +50,10 @@ Usage example:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/PackageVariable.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/PackageVariable.py 5023 2010/06/14 22:05:46 scons"
__all__ = ['PackageVariable',]
-import string
-
import SCons.Errors
__enable_strings = ('1', 'yes', 'true', 'on', 'enable', 'search')
@@ -64,7 +62,7 @@ __disable_strings = ('0', 'no', 'false', 'off', 'disable')
def _converter(val):
"""
"""
- lval = string.lower(val)
+ lval = val.lower()
if lval in __enable_strings: return True
if lval in __disable_strings: return False
#raise ValueError("Invalid value for boolean option: %s" % val)
@@ -95,11 +93,10 @@ def PackageVariable(key, help, default, searchfunc=None):
A 'package list' option may either be 'all', 'none' or a list of
package names (seperated by space).
"""
- help = string.join(
- (help, '( yes | no | /path/to/%s )' % key),
- '\n ')
+ help = '\n '.join(
+ (help, '( yes | no | /path/to/%s )' % key))
return (key, help, default,
- lambda k, v, e, f=searchfunc: _validator(k,v,e,f),
+ lambda k, v, e: _validator(k,v,e,searchfunc),
_converter)
# Local Variables:
diff --git a/src/engine/SCons/Variables/PackageVariableTests.py b/src/engine/SCons/Variables/PackageVariableTests.py
index 4a5b0ee..097ffc6 100644
--- a/src/engine/SCons/Variables/PackageVariableTests.py
+++ b/src/engine/SCons/Variables/PackageVariableTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/PackageVariableTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/PackageVariableTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
diff --git a/src/engine/SCons/Variables/PathVariable.py b/src/engine/SCons/Variables/PathVariable.py
index 4af9fc3..445cfe2 100644
--- a/src/engine/SCons/Variables/PathVariable.py
+++ b/src/engine/SCons/Variables/PathVariable.py
@@ -68,7 +68,7 @@ Usage example:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/PathVariable.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/PathVariable.py 5023 2010/06/14 22:05:46 scons"
__all__ = ['PathVariable',]
@@ -77,7 +77,7 @@ import os.path
import SCons.Errors
-class _PathVariableClass:
+class _PathVariableClass(object):
def PathAccept(self, key, val, env):
"""Accepts any path, no checking done."""
diff --git a/src/engine/SCons/Variables/PathVariableTests.py b/src/engine/SCons/Variables/PathVariableTests.py
index 93f2b17..c55a6ed 100644
--- a/src/engine/SCons/Variables/PathVariableTests.py
+++ b/src/engine/SCons/Variables/PathVariableTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/PathVariableTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/PathVariableTests.py 5023 2010/06/14 22:05:46 scons"
import os.path
import sys
@@ -68,7 +68,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'Path for option X does not exist: %s' % dne, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def test_PathIsDir(self):
"""Test the PathIsDir validator"""
@@ -92,7 +92,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'Directory path for option X is a file: %s' % f, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
dne = test.workpath('does_not_exist')
try:
@@ -100,7 +100,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'Directory path for option X does not exist: %s' % dne, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def test_PathIsDirCreate(self):
"""Test the PathIsDirCreate validator"""
@@ -125,7 +125,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'Path for option X is a file, not a directory: %s' % f, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def test_PathIsFile(self):
"""Test the PathIsFile validator"""
@@ -149,7 +149,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'File path for option X does not exist: %s' % d, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
dne = test.workpath('does_not_exist')
try:
@@ -157,7 +157,7 @@ class PathVariableTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert str(e) == 'File path for option X does not exist: %s' % dne, e
except:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def test_PathAccept(self):
"""Test the PathAccept validator"""
@@ -202,10 +202,10 @@ class PathVariableTestCase(unittest.TestCase):
expect = 'Path for option X does not exist: %s' % dne
assert str(e) == expect, e
else:
- raise "did not catch expected UserError"
+ raise Exception("did not catch expected UserError")
def my_validator(key, val, env):
- raise Exception, "my_validator() got called for %s, %s!" % (key, val)
+ raise Exception("my_validator() got called for %s, %s!" % (key, val))
opts = SCons.Variables.Variables()
opts.Add(SCons.Variables.PathVariable('test2',
@@ -220,7 +220,7 @@ class PathVariableTestCase(unittest.TestCase):
except Exception, e:
assert str(e) == 'my_validator() got called for Y, value!', e
else:
- raise "did not catch expected exception from my_validator()"
+ 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 617cf8f..7ecbc0d 100644
--- a/src/engine/SCons/Variables/VariablesTests.py
+++ b/src/engine/SCons/Variables/VariablesTests.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/Variables/VariablesTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/VariablesTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
@@ -32,7 +32,7 @@ import SCons.Subst
import SCons.Warnings
-class Environment:
+class Environment(object):
def __init__(self):
self.dict = {}
def subst(self, x):
@@ -41,8 +41,10 @@ class Environment:
self.dict[key] = value
def __getitem__(self, key):
return self.dict[key]
+ def __contains__(self, key):
+ return self.dict.__contains__(key)
def has_key(self, key):
- return self.dict.has_key(key)
+ return key in self.dict
def check(key, value, env):
@@ -68,7 +70,7 @@ class VariablesTestCase(unittest.TestCase):
"42",
check,
lambda x: int(x) + 12)
- keys = opts.keys()
+ keys = list(opts.keys())
assert keys == ['VAR1', 'VAR2'], keys
def test_Add(self):
@@ -253,7 +255,7 @@ class VariablesTestCase(unittest.TestCase):
env = Environment()
opts.Update(env, {})
- assert not env.has_key('ANSWER')
+ assert 'ANSWER' not in env
# Test that a default value of None is all right.
test = TestSCons.TestSCons()
@@ -267,7 +269,7 @@ class VariablesTestCase(unittest.TestCase):
env = Environment()
opts.Update(env, {})
- assert not env.has_key('ANSWER')
+ assert 'ANSWER' not in env
def test_args(self):
"""Test updating an Environment with arguments overridden"""
@@ -378,7 +380,7 @@ class VariablesTestCase(unittest.TestCase):
'OPT_BOOL_2' : 2})
# Test against some old bugs
- class Foo:
+ class Foo(object):
def __init__(self, x):
self.x = x
def __str__(self):
@@ -527,12 +529,12 @@ B 42 54 b - alpha test ['B']
env = Environment()
opts.Update(env, {'ANSWER' : 'answer'})
- assert env.has_key('ANSWER')
+ assert 'ANSWER' in env
env = Environment()
opts.Update(env, {'ANSWERALIAS' : 'answer'})
- assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS')
+ assert 'ANSWER' in env and 'ANSWERALIAS' not in env
# test alias as a list
opts = SCons.Variables.Variables()
@@ -545,12 +547,12 @@ B 42 54 b - alpha test ['B']
env = Environment()
opts.Update(env, {'ANSWER' : 'answer'})
- assert env.has_key('ANSWER')
+ assert 'ANSWER' in env
env = Environment()
opts.Update(env, {'ANSWERALIAS' : 'answer'})
- assert env.has_key('ANSWER') and not env.has_key('ANSWERALIAS')
+ assert 'ANSWER' in env and 'ANSWERALIAS' not in env
@@ -652,7 +654,7 @@ if __name__ == "__main__":
UnknownVariablesTestCase ]
for tclass in tclasses:
names = unittest.getTestCaseNames(tclass, 'test_')
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/Variables/__init__.py b/src/engine/SCons/Variables/__init__.py
index 8840b97..d8562b0 100644
--- a/src/engine/SCons/Variables/__init__.py
+++ b/src/engine/SCons/Variables/__init__.py
@@ -25,12 +25,10 @@ customizable variables to an SCons build.
# 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__ = "src/engine/SCons/Variables/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Variables/__init__.py 5023 2010/06/14 22:05:46 scons"
import os.path
-import string
import sys
import SCons.Environment
@@ -45,7 +43,7 @@ from PackageVariable import PackageVariable # naja
from PathVariable import PathVariable # okay
-class Variables:
+class Variables(object):
instance=None
"""
@@ -76,7 +74,7 @@ class Variables:
Variables.instance=self
def _do_add(self, key, help="", default=None, validator=None, converter=None):
- class Variable:
+ class Variable(object):
pass
option = Variable()
@@ -84,11 +82,11 @@ class Variables:
# if we get a list or a tuple, we take the first element as the
# option key and store the remaining in aliases.
if SCons.Util.is_List(key) or SCons.Util.is_Tuple(key):
- option.key = key[0]
- option.aliases = key[1:]
+ option.key = key[0]
+ option.aliases = key[1:]
else:
- option.key = key
- option.aliases = [ key ]
+ option.key = key
+ option.aliases = [ key ]
option.help = help
option.default = default
option.validator = validator
@@ -99,16 +97,14 @@ class Variables:
# options might be added after the 'unknown' dict has been set up,
# so we remove the key and all its aliases from that dict
for alias in list(option.aliases) + [ option.key ]:
- # TODO(1.5)
- #if alias in self.unknown:
- if alias in self.unknown.keys():
- del self.unknown[alias]
+ if alias in self.unknown:
+ del self.unknown[alias]
def keys(self):
"""
Returns the keywords for the options
"""
- return map(lambda o: o.key, self.options)
+ return [o.key for o in self.options]
def Add(self, key, help="", default=None, validator=None, converter=None, **kw):
"""
@@ -123,13 +119,13 @@ class Variables:
putting it in the environment.
"""
- if SCons.Util.is_List(key) or type(key) == type(()):
- apply(self._do_add, key)
+ if SCons.Util.is_List(key) or isinstance(key, tuple):
+ self._do_add(*key)
return
if not SCons.Util.is_String(key) or \
- not SCons.Environment.is_valid_construction_var(key):
- raise SCons.Errors.UserError, "Illegal Variables.Add() key `%s'" % str(key)
+ not SCons.Environment.is_valid_construction_var(key):
+ raise SCons.Errors.UserError("Illegal Variables.Add() key `%s'" % str(key))
self._do_add(key, help, default, validator, converter)
@@ -149,7 +145,7 @@ class Variables:
)
"""
for o in optlist:
- apply(self._do_add, o)
+ self._do_add(*o)
def Update(self, env, args=None):
@@ -203,7 +199,7 @@ class Variables:
# Call the convert functions:
for option in self.options:
- if option.converter and values.has_key(option.key):
+ if option.converter and option.key in values:
value = env.subst('${%s}'%option.key)
try:
try:
@@ -211,12 +207,12 @@ class Variables:
except TypeError:
env[option.key] = option.converter(value, env)
except ValueError, x:
- raise SCons.Errors.UserError, 'Error converting option: %s\n%s'%(option.key, x)
+ raise SCons.Errors.UserError('Error converting option: %s\n%s'%(option.key, x))
# Finally validate the values:
for option in self.options:
- if option.validator and values.has_key(option.key):
+ if option.validator and option.key in values:
option.validator(option.key, env.subst('${%s}'%option.key), env)
def UnknownVariables(self):
@@ -273,7 +269,7 @@ class Variables:
fh.close()
except IOError, x:
- raise SCons.Errors.UserError, 'Error writing options to file: %s\n%s' % (filename, x)
+ raise SCons.Errors.UserError('Error writing options to file: %s\n%s' % (filename, x))
def GenerateHelpText(self, env, sort=None):
"""
@@ -284,27 +280,26 @@ class Variables:
"""
if sort:
- options = self.options[:]
- options.sort(lambda x,y,func=sort: func(x.key,y.key))
+ options = sorted(self.options, key=lambda x: x.key)
else:
options = self.options
def format(opt, self=self, env=env):
- if env.has_key(opt.key):
+ if opt.key in env:
actual = env.subst('${%s}' % opt.key)
else:
actual = None
return self.FormatVariableHelpText(env, opt.key, opt.help, opt.default, actual, opt.aliases)
- lines = filter(None, map(format, options))
+ lines = [_f for _f in map(format, options) if _f]
- return string.join(lines, '')
+ return ''.join(lines)
format = '\n%s: %s\n default: %s\n actual: %s\n'
format_ = '\n%s: %s\n default: %s\n actual: %s\n aliases: %s\n'
def FormatVariableHelpText(self, env, key, help, default, actual, aliases=[]):
# Don't display the key name itself as an alias.
- aliases = filter(lambda a, k=key: a != k, aliases)
+ aliases = [a for a in aliases if a != key]
if len(aliases)==0:
return self.format % (key, help, default, actual)
else:
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index 9f072bf..aa6074c 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -27,9 +27,8 @@ This file implements the warnings framework for SCons.
"""
-__revision__ = "src/engine/SCons/Warnings.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/Warnings.py 5023 2010/06/14 22:05:46 scons"
-import string
import sys
import SCons.Errors
@@ -37,104 +36,124 @@ import SCons.Errors
class Warning(SCons.Errors.UserError):
pass
-class MandatoryWarning(Warning):
+class WarningOnByDefault(Warning):
pass
+# NOTE: If you add a new warning class, add it to the man page, too!
-class FutureDeprecatedWarning(Warning):
+class CacheWriteErrorWarning(Warning):
pass
-class DeprecatedWarning(Warning):
+class CorruptSConsignWarning(WarningOnByDefault):
pass
-class MandatoryDeprecatedWarning(MandatoryWarning):
+class DependencyWarning(Warning):
pass
+class DuplicateEnvironmentWarning(WarningOnByDefault):
+ pass
+class FutureReservedVariableWarning(WarningOnByDefault):
+ pass
-# NOTE: If you add a new warning class, add it to the man page, too!
-
-class CacheWriteErrorWarning(Warning):
+class LinkWarning(WarningOnByDefault):
pass
-class CorruptSConsignWarning(Warning):
+class MisleadingKeywordsWarning(WarningOnByDefault):
pass
-class DependencyWarning(Warning):
+class MissingSConscriptWarning(WarningOnByDefault):
pass
-class DeprecatedCopyWarning(DeprecatedWarning):
+class NoMD5ModuleWarning(WarningOnByDefault):
pass
-class DeprecatedOptionsWarning(DeprecatedWarning):
+class NoMetaclassSupportWarning(WarningOnByDefault):
pass
-class DeprecatedSourceSignaturesWarning(DeprecatedWarning):
+class NoObjectCountWarning(WarningOnByDefault):
pass
-class DeprecatedTargetSignaturesWarning(DeprecatedWarning):
+class NoParallelSupportWarning(WarningOnByDefault):
pass
-class DuplicateEnvironmentWarning(Warning):
+class ReservedVariableWarning(WarningOnByDefault):
pass
-class FutureReservedVariableWarning(Warning):
+class StackSizeWarning(WarningOnByDefault):
pass
-class LinkWarning(Warning):
+class VisualCMissingWarning(WarningOnByDefault):
pass
-class MisleadingKeywordsWarning(Warning):
+# Used when MSVC_VERSION and MSVS_VERSION do not point to the
+# same version (MSVS_VERSION is deprecated)
+class VisualVersionMismatch(WarningOnByDefault):
pass
-class MissingSConscriptWarning(Warning):
+class VisualStudioMissingWarning(Warning):
pass
-class NoMD5ModuleWarning(Warning):
+class FortranCxxMixWarning(LinkWarning):
pass
-class NoMetaclassSupportWarning(Warning):
+
+# Deprecation warnings
+
+class FutureDeprecatedWarning(Warning):
pass
-class NoObjectCountWarning(Warning):
+class DeprecatedWarning(Warning):
pass
-class NoParallelSupportWarning(Warning):
+class MandatoryDeprecatedWarning(DeprecatedWarning):
pass
+
+# Special case; base always stays DeprecatedWarning
class PythonVersionWarning(DeprecatedWarning):
pass
-class ReservedVariableWarning(Warning):
+class DeprecatedSourceCodeWarning(FutureDeprecatedWarning):
pass
-class StackSizeWarning(Warning):
+class DeprecatedBuildDirWarning(DeprecatedWarning):
pass
-class TaskmasterNeedsExecuteWarning(FutureDeprecatedWarning):
+class TaskmasterNeedsExecuteWarning(DeprecatedWarning):
pass
-class VisualCMissingWarning(Warning):
+class DeprecatedCopyWarning(MandatoryDeprecatedWarning):
pass
-# Used when MSVC_VERSION and MSVS_VERSION do not point to the
-# same version (MSVS_VERSION is deprecated)
-class VisualVersionMismatch(Warning):
+class DeprecatedOptionsWarning(MandatoryDeprecatedWarning):
pass
-class VisualStudioMissingWarning(Warning):
+class DeprecatedSourceSignaturesWarning(MandatoryDeprecatedWarning):
pass
-class FortranCxxMixWarning(LinkWarning):
+class DeprecatedTargetSignaturesWarning(MandatoryDeprecatedWarning):
+ pass
+
+class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning):
+ pass
+
+class DeprecatedSigModuleWarning(MandatoryDeprecatedWarning):
+ pass
+
+class DeprecatedBuilderKeywordsWarning(MandatoryDeprecatedWarning):
pass
-_warningAsException = 0
# The below is a list of 2-tuples. The first element is a class object.
# The second element is true if that class is enabled, false if it is disabled.
_enabled = []
+# If set, raise the warning as an exception
+_warningAsException = 0
+
+# If not None, a function to call with the warning
_warningOut = None
def suppressWarningClass(clazz):
@@ -143,7 +162,7 @@ def suppressWarningClass(clazz):
_enabled.insert(0, (clazz, 0))
def enableWarningClass(clazz):
- """Suppresses all warnings that are of type clazz or
+ """Enables all warnings that are of type clazz or
derived from clazz."""
_enabled.insert(0, (clazz, 1))
@@ -182,8 +201,7 @@ def process_warn_strings(arguments):
"Warning" is appended to get the class name.
For example, 'deprecated' will enable the DeprecatedWarning
- class. 'no-dependency' will disable the .DependencyWarning
- class.
+ class. 'no-dependency' will disable the DependencyWarning class.
As a special case, --warn=all and --warn=no-all will enable or
disable (respectively) the base Warning class of all warnings.
@@ -194,11 +212,11 @@ def process_warn_strings(arguments):
if s[:5] == "scons":
return "SCons" + s[5:]
else:
- return string.capitalize(s)
+ return s.capitalize()
for arg in arguments:
- elems = string.split(string.lower(arg), '-')
+ elems = arg.lower().split('-')
enable = 1
if elems[0] == 'no':
enable = 0
@@ -207,7 +225,7 @@ def process_warn_strings(arguments):
if len(elems) == 1 and elems[0] == 'all':
class_name = "Warning"
else:
- class_name = string.join(map(_capitalize, elems), '') + "Warning"
+ class_name = ''.join(map(_capitalize, elems)) + "Warning"
try:
clazz = globals()[class_name]
except KeyError:
diff --git a/src/engine/SCons/WarningsTests.py b/src/engine/SCons/WarningsTests.py
index 2a6e0b0..39a1602 100644
--- a/src/engine/SCons/WarningsTests.py
+++ b/src/engine/SCons/WarningsTests.py
@@ -21,15 +21,15 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/WarningsTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/WarningsTests.py 5023 2010/06/14 22:05:46 scons"
import sys
import unittest
import SCons.Warnings
-class TestOutput:
+class TestOutput(object):
def __call__(self, x):
- args = x[0]
+ args = x.args[0]
if len(args) == 1:
args = args[0]
self.out = str(args)
@@ -94,10 +94,6 @@ class WarningsTestCase(unittest.TestCase):
"Foo")
assert to.out is None, to.out
- SCons.Warnings.warn(SCons.Warnings.MandatoryWarning,
- "Foo")
- assert to.out is None, to.out
-
SCons.Warnings.enableWarningClass(SCons.Warnings.Warning)
SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
"Foo")
@@ -109,6 +105,10 @@ class WarningsTestCase(unittest.TestCase):
"Foo")
assert to.out is None, to.out
+ SCons.Warnings.warn(SCons.Warnings.MandatoryDeprecatedWarning,
+ "Foo")
+ assert to.out is None, to.out
+
# Dependency warnings should still be enabled though
SCons.Warnings.enableWarningClass(SCons.Warnings.Warning)
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
diff --git a/src/engine/SCons/__init__.py b/src/engine/SCons/__init__.py
index 5abe730..5ffbf8a 100644
--- a/src/engine/SCons/__init__.py
+++ b/src/engine/SCons/__init__.py
@@ -27,17 +27,17 @@ The main package for the SCons software construction utility.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/__init__.py 5023 2010/06/14 22:05:46 scons"
-__version__ = "1.3.0"
+__version__ = "2.0.0.final.0"
-__build__ = "r4720"
+__build__ = "r5023"
-__buildsys__ = "jars-desktop"
+__buildsys__ = "scons-dev"
-__date__ = "2010/03/24 03:14:11"
+__date__ = "2010/06/14 22:05:46"
-__developer__ = "jars"
+__developer__ = "scons"
# make sure compatibility is always in place
import SCons.compat
diff --git a/src/engine/SCons/compat/__init__.py b/src/engine/SCons/compat/__init__.py
index 165dddf..cba69ef 100644
--- a/src/engine/SCons/compat/__init__.py
+++ b/src/engine/SCons/compat/__init__.py
@@ -31,12 +31,12 @@ we still support.
Other code will not generally reference things in this package through
the SCons.compat namespace. The modules included here add things to
-the __builtin__ namespace or the global module list so that the rest
+the builtins namespace or the global module list so that the rest
of our code can use the objects and names imported here regardless of
Python version.
-Simply enough, things that go in the __builtin__ name space come from
-our builtins module.
+Simply enough, things that go in the builtins name space come from
+our _scons_builtins module.
The rest of the things here will be in individual compatibility modules
that are either: 1) suitably modified copies of the future modules that
@@ -60,20 +60,35 @@ function defined below loads the module as the "real" name (without the
rest of our code will find our pre-loaded compatibility module.
"""
-__revision__ = "src/engine/SCons/compat/__init__.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/compat/__init__.py 5023 2010/06/14 22:05:46 scons"
+
+import os
+import sys
+import imp # Use the "imp" module to protect imports from fixers.
def import_as(module, name):
"""
Imports the specified module (from our local directory) as the
- specified name.
+ specified name, returning the loaded module object.
"""
- import imp
- import os.path
dir = os.path.split(__file__)[0]
- file, filename, suffix_mode_type = imp.find_module(module, [dir])
- imp.load_module(name, file, filename, suffix_mode_type)
+ return imp.load_module(name, *imp.find_module(module, [dir]))
+
+def rename_module(new, old):
+ """
+ Attempts to import the old module and load it under the new name.
+ Used for purely cosmetic name changes in Python 3.x.
+ """
+ try:
+ sys.modules[new] = imp.load_module(old, *imp.find_module(old))
+ return True
+ except ImportError:
+ return False
+
+
+rename_module('builtins', '__builtin__')
+import _scons_builtins
-import builtins
try:
import hashlib
@@ -92,75 +107,48 @@ try:
set
except NameError:
# Pre-2.4 Python has no native set type
- try:
- # Python 2.2 and 2.3 can use the copy of the 2.[45] sets module
- # that we grabbed.
- import_as('_scons_sets', 'sets')
- except (ImportError, SyntaxError):
- # Python 1.5 (ImportError, no __future_ module) and 2.1
- # (SyntaxError, no generators in __future__) will blow up
- # trying to import the 2.[45] sets module, so back off to a
- # custom sets module that can be discarded easily when we
- # stop supporting those versions.
- import_as('_scons_sets15', 'sets')
- import __builtin__
- import sets
- __builtin__.set = sets.Set
-
-import fnmatch
-try:
- fnmatch.filter
-except AttributeError:
- # Pre-2.2 Python has no fnmatch.filter() function.
- def filter(names, pat):
- """Return the subset of the list NAMES that match PAT"""
- import os,posixpath
- result=[]
- pat = os.path.normcase(pat)
- if not fnmatch._cache.has_key(pat):
- import re
- res = fnmatch.translate(pat)
- fnmatch._cache[pat] = re.compile(res)
- match = fnmatch._cache[pat].match
- if os.path is posixpath:
- # normcase on posix is NOP. Optimize it away from the loop.
- for name in names:
- if match(name):
- result.append(name)
- else:
- for name in names:
- if match(os.path.normcase(name)):
- result.append(name)
- return result
- fnmatch.filter = filter
- del filter
+ import_as('_scons_sets', 'sets')
+ import builtins, sets
+ builtins.set = sets.Set
-try:
- import itertools
-except ImportError:
- # Pre-2.3 Python has no itertools module.
- import_as('_scons_itertools', 'itertools')
-# If we need the compatibility version of textwrap, it must be imported
-# before optparse, which uses it.
try:
- import textwrap
+ import collections
except ImportError:
- # Pre-2.3 Python has no textwrap module.
- import_as('_scons_textwrap', 'textwrap')
+ # Pre-2.4 Python has no collections module.
+ import_as('_scons_collections', 'collections')
+else:
+ try:
+ collections.UserDict
+ except AttributeError:
+ exec('from UserDict import UserDict as _UserDict')
+ collections.UserDict = _UserDict
+ del _UserDict
+ try:
+ collections.UserList
+ except AttributeError:
+ exec('from UserList import UserList as _UserList')
+ collections.UserList = _UserList
+ del _UserList
+ try:
+ collections.UserString
+ except AttributeError:
+ exec('from UserString import UserString as _UserString')
+ collections.UserString = _UserString
+ del _UserString
+
try:
- import optparse
+ import io
except ImportError:
- # Pre-2.3 Python has no optparse module.
- import_as('_scons_optparse', 'optparse')
+ # Pre-2.6 Python has no io module.
+ import_as('_scons_io', 'io')
+
-import os
try:
os.devnull
except AttributeError:
# Pre-2.4 Python has no os.devnull attribute
- import sys
_names = sys.builtin_module_names
if 'posix' in _names:
os.devnull = '/dev/null'
@@ -176,64 +164,25 @@ except AttributeError:
os.path.lexists = lexists
-try:
- import platform
-except ImportError:
- # Pre-2.3 Python has no platform module.
- import_as('_scons_platform', 'platform')
+# When we're using the '-3' option during regression tests, importing
+# cPickle gives a warning no matter how it's done, so always use the
+# real profile module, whether it's fast or not.
+if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is None:
+ # Not a regression test with '-3', so try to use faster version.
+ # In 3.x, 'pickle' automatically loads the fast version if available.
+ rename_module('pickle', 'cPickle')
-import shlex
-try:
- shlex.split
-except AttributeError:
- # Pre-2.3 Python has no shlex.split() function.
- #
- # The full white-space splitting semantics of shlex.split() are
- # complicated to reproduce by hand, so just use a compatibility
- # version of the shlex module cribbed from Python 2.5 with some
- # minor modifications for older Python versions.
- del shlex
- import_as('_scons_shlex', 'shlex')
+# In 3.x, 'profile' automatically loads the fast version if available.
+rename_module('profile', 'cProfile')
-import shutil
-try:
- shutil.move
-except AttributeError:
- # Pre-2.3 Python has no shutil.move() function.
- #
- # Cribbed from Python 2.5.
- import os
-
- def move(src, dst):
- """Recursively move a file or directory to another location.
-
- If the destination is on our current filesystem, then simply use
- rename. Otherwise, copy src to the dst and then remove src.
- A lot more could be done here... A look at a mv.c shows a lot of
- the issues this implementation glosses over.
-
- """
- try:
- os.rename(src, dst)
- except OSError:
- if os.path.isdir(src):
- if shutil.destinsrc(src, dst):
- raise Error, "Cannot move a directory '%s' into itself '%s'." % (src, dst)
- shutil.copytree(src, dst, symlinks=True)
- shutil.rmtree(src)
- else:
- shutil.copy2(src,dst)
- os.unlink(src)
- shutil.move = move
- del move
-
- def destinsrc(src, dst):
- src = os.path.abspath(src)
- return os.path.abspath(dst)[:len(src)] == src
- shutil.destinsrc = destinsrc
- del destinsrc
+# Before Python 3.0, the 'queue' module was named 'Queue'.
+rename_module('queue', 'Queue')
+
+
+# Before Python 3.0, the 'winreg' module was named '_winreg'
+rename_module('winreg', '_winreg')
try:
@@ -242,57 +191,43 @@ except ImportError:
# Pre-2.4 Python has no subprocess module.
import_as('_scons_subprocess', 'subprocess')
-import sys
try:
- sys.version_info
+ sys.intern
except AttributeError:
- # Pre-1.6 Python has no sys.version_info
- import string
- version_string = string.split(sys.version)[0]
- version_ints = map(int, string.split(version_string, '.'))
- sys.version_info = tuple(version_ints + ['final', 0])
-
-try:
- import UserString
-except ImportError:
- # Pre-1.6 Python has no UserString module.
- import_as('_scons_UserString', 'UserString')
-
-import tempfile
+ # Pre-2.6 Python has no sys.intern() function.
+ import builtins
+ try:
+ sys.intern = builtins.intern
+ except AttributeError:
+ # Pre-2.x Python has no builtin intern() function.
+ def intern(x):
+ return x
+ sys.intern = intern
+ del intern
try:
- tempfile.mkstemp
+ sys.maxsize
except AttributeError:
- # Pre-2.3 Python has no tempfile.mkstemp function, so try to simulate it.
- # adapted from the mkstemp implementation in python 3.
- import os
- import errno
- def mkstemp(*args, **kw):
- text = False
- # TODO (1.5)
- #if 'text' in kw :
- if 'text' in kw.keys() :
- text = kw['text']
- del kw['text']
- elif len( args ) == 4 :
- text = args[3]
- args = args[:3]
- flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
- if not text and hasattr( os, 'O_BINARY' ) :
- flags = flags | os.O_BINARY
- while True:
- try :
- name = apply(tempfile.mktemp, args, kw)
- fd = os.open( name, flags, 0600 )
- return (fd, os.path.abspath(name))
- except OSError, e:
- if e.errno == errno.EEXIST:
- continue
- raise
-
- tempfile.mkstemp = mkstemp
- del mkstemp
-
-
+ # Pre-2.6 Python has no sys.maxsize attribute
+ # Wrapping sys in () is silly, but protects it from 2to3 renames fixer
+ sys.maxsize = (sys).maxint
+
+
+if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None:
+ # We can't apply the 'callable' fixer until the floor is 2.6, but the
+ # '-3' option to Python 2.6 and 2.7 generates almost ten thousand
+ # warnings. This hack allows us to run regression tests with the '-3'
+ # option by replacing the callable() built-in function with a hack
+ # that performs the same function but doesn't generate the warning.
+ # Note that this hack is ONLY intended to be used for regression
+ # testing, and should NEVER be used for real runs.
+ from types import ClassType
+ def callable(obj):
+ if hasattr(obj, '__call__'): return True
+ if isinstance(obj, (ClassType, type)): return True
+ return False
+ import builtins
+ builtins.callable = callable
+ del callable
# Local Variables:
diff --git a/src/engine/SCons/compat/_scons_UserString.py b/src/engine/SCons/compat/_scons_UserString.py
deleted file mode 100644
index f8c462e..0000000
--- a/src/engine/SCons/compat/_scons_UserString.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
-# 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__ = "src/engine/SCons/compat/_scons_UserString.py 4720 2010/03/24 03:14:11 jars"
-
-__doc__ = """
-A user-defined wrapper around string objects
-
-This class is "borrowed" from the Python 2.2 UserString and modified
-slightly for use with SCons. It is *NOT* guaranteed to be fully compliant
-with the standard UserString class from all later versions of Python.
-In particular, it does not necessarily contain all of the methods found
-in later versions.
-"""
-
-import types
-
-StringType = types.StringType
-
-if hasattr(types, 'UnicodeType'):
- UnicodeType = types.UnicodeType
- def is_String(obj):
- return type(obj) in (StringType, UnicodeType)
-else:
- def is_String(obj):
- return type(obj) is StringType
-
-class UserString:
- def __init__(self, seq):
- if is_String(seq):
- self.data = seq
- elif isinstance(seq, UserString):
- self.data = seq.data[:]
- else:
- self.data = str(seq)
- def __str__(self): return str(self.data)
- def __repr__(self): return repr(self.data)
- def __int__(self): return int(self.data)
- def __long__(self): return long(self.data)
- def __float__(self): return float(self.data)
- def __complex__(self): return complex(self.data)
- def __hash__(self): return hash(self.data)
-
- def __cmp__(self, string):
- if isinstance(string, UserString):
- return cmp(self.data, string.data)
- else:
- return cmp(self.data, string)
- def __contains__(self, char):
- return char in self.data
-
- def __len__(self): return len(self.data)
- def __getitem__(self, index): return self.__class__(self.data[index])
- def __getslice__(self, start, end):
- start = max(start, 0); end = max(end, 0)
- return self.__class__(self.data[start:end])
-
- def __add__(self, other):
- if isinstance(other, UserString):
- return self.__class__(self.data + other.data)
- elif is_String(other):
- return self.__class__(self.data + other)
- else:
- return self.__class__(self.data + str(other))
- def __radd__(self, other):
- if is_String(other):
- return self.__class__(other + self.data)
- else:
- return self.__class__(str(other) + self.data)
- def __mul__(self, n):
- return self.__class__(self.data*n)
- __rmul__ = __mul__
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/builtins.py b/src/engine/SCons/compat/_scons_builtins.py
index e687885..234d380 100644
--- a/src/engine/SCons/compat/builtins.py
+++ b/src/engine/SCons/compat/_scons_builtins.py
@@ -27,21 +27,18 @@
# Copyright (c) 2001-2004 Twisted Matrix Laboratories
__doc__ = """
-Compatibility idioms for __builtin__ names
+Compatibility idioms for builtins names
-This module adds names to the __builtin__ module for things that we want
+This module adds names to the builtins module for things that we want
to use in SCons but which don't show up until later Python versions than
the earliest ones we support.
-This module checks for the following __builtin__ names:
+This module checks for the following builtins names:
all()
any()
- bool()
- dict()
- True
- False
- zip()
+ sorted()
+ memoryview()
Implementations of functions are *NOT* guaranteed to be fully compliant
with these functions in later versions of Python. We are only concerned
@@ -55,9 +52,9 @@ the FUNCTIONS or DATA output, that means those names are already built in
to this version of Python and we don't need to add them from this module.
"""
-__revision__ = "src/engine/SCons/compat/builtins.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/compat/_scons_builtins.py 5023 2010/06/14 22:05:46 scons"
-import __builtin__
+import builtins
try:
all
@@ -71,7 +68,7 @@ except NameError:
if not element:
return False
return True
- __builtin__.all = all
+ builtins.all = all
all = all
try:
@@ -86,83 +83,49 @@ except NameError:
if element:
return True
return False
- __builtin__.any = any
+ builtins.any = any
any = any
try:
- bool
+ memoryview
except NameError:
- # Pre-2.2 Python has no bool() function.
- def bool(value):
- """Demote a value to 0 or 1, depending on its truth value.
+ # Pre-2.7 doesn't have the memoryview() built-in.
+ class memoryview(object):
+ def __init__(self, obj):
+ # wrapping buffer in () keeps the fixer from changing it
+ self.obj = (buffer)(obj)
+ def __getitem__(self, indx):
+ if isinstance(indx, slice):
+ return self.obj[indx.start:indx.stop]
+ else:
+ return self.obj[indx]
+ builtins.memoryview = memoryview
- This is not to be confused with types.BooleanType, which is
- way too hard to duplicate in early Python versions to be
- worth the trouble.
- """
- return not not value
- __builtin__.bool = bool
- bool = bool
-
-try:
- dict
-except NameError:
- # Pre-2.2 Python has no dict() keyword.
- def dict(seq=[], **kwargs):
- """
- New dictionary initialization.
- """
- d = {}
- for k, v in seq:
- d[k] = v
- d.update(kwargs)
- return d
- __builtin__.dict = dict
-
-try:
- False
-except NameError:
- # Pre-2.2 Python has no False keyword.
- __builtin__.False = not 1
- # Assign to False in this module namespace so it shows up in pydoc output.
- False = False
-
-try:
- True
-except NameError:
- # Pre-2.2 Python has no True keyword.
- __builtin__.True = not 0
- # Assign to True in this module namespace so it shows up in pydoc output.
- True = True
-
-try:
- file
-except NameError:
- # Pre-2.2 Python has no file() function.
- __builtin__.file = open
-
-#
try:
- zip
+ sorted
except NameError:
- # Pre-2.2 Python has no zip() function.
- def zip(*lists):
- """
- Emulates the behavior we need from the built-in zip() function
- added in Python 2.2.
-
- Returns a list of tuples, where each tuple contains the i-th
- element rom each of the argument sequences. The returned
- list is truncated in length to the length of the shortest
- argument sequence.
- """
- result = []
- for i in xrange(min(map(len, lists))):
- result.append(tuple(map(lambda l, i=i: l[i], lists)))
+ # Pre-2.4 Python has no sorted() function.
+ #
+ # The pre-2.4 Python list.sort() method does not support
+ # list.sort(key=) nor list.sort(reverse=) keyword arguments, so
+ # we must implement the functionality of those keyword arguments
+ # by hand instead of passing them to list.sort().
+ def sorted(iterable, cmp=None, key=None, reverse=False):
+ if key is not None:
+ result = [(key(x), x) for x in iterable]
+ else:
+ result = iterable[:]
+ if cmp is None:
+ # Pre-2.3 Python does not support list.sort(None).
+ result.sort()
+ else:
+ result.sort(cmp)
+ if key is not None:
+ result = [t1 for t0,t1 in result]
+ if reverse:
+ result.reverse()
return result
- __builtin__.zip = zip
-
-
+ builtins.sorted = sorted
#if sys.version_info[:3] in ((2, 2, 0), (2, 2, 1)):
# def lstrip(s, c=string.whitespace):
diff --git a/src/engine/SCons/compat/_scons_collections.py b/src/engine/SCons/compat/_scons_collections.py
new file mode 100644
index 0000000..b44319c
--- /dev/null
+++ b/src/engine/SCons/compat/_scons_collections.py
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
+# 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.
+#
+
+__doc__ = """
+collections compatibility module for older (pre-2.4) Python versions
+
+This does not not NOT (repeat, *NOT*) provide complete collections
+functionality. It only wraps the portions of collections functionality
+used by SCons, in an interface that looks enough like collections for
+our purposes.
+"""
+
+__revision__ = "src/engine/SCons/compat/_scons_collections.py 5023 2010/06/14 22:05:46 scons"
+
+# Use exec to hide old names from fixers.
+exec("""if True:
+ from UserDict import UserDict
+ from UserList import UserList
+ from UserString import UserString""")
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_dbm.py b/src/engine/SCons/compat/_scons_dbm.py
new file mode 100644
index 0000000..6228aee
--- /dev/null
+++ b/src/engine/SCons/compat/_scons_dbm.py
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
+# 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.
+#
+
+__doc__ = """
+dbm compatibility module for Python versions that don't have dbm.
+
+This does not not NOT (repeat, *NOT*) provide complete dbm functionality.
+It's just a stub on which to hang just enough pieces of dbm functionality
+that the whichdb.whichdb() implementstation in the various 2.X versions of
+Python won't blow up even if dbm wasn't compiled in.
+"""
+
+__revision__ = "src/engine/SCons/compat/_scons_dbm.py 5023 2010/06/14 22:05:46 scons"
+
+class error(Exception):
+ pass
+
+def open(*args, **kw):
+ raise error()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_hashlib.py b/src/engine/SCons/compat/_scons_hashlib.py
index b325e33..1c93787 100644
--- a/src/engine/SCons/compat/_scons_hashlib.py
+++ b/src/engine/SCons/compat/_scons_hashlib.py
@@ -31,18 +31,18 @@ purposes, anyway). In fact, this module will raise an ImportError if
the underlying md5 module isn't available.
"""
-__revision__ = "src/engine/SCons/compat/_scons_hashlib.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/compat/_scons_hashlib.py 5023 2010/06/14 22:05:46 scons"
import md5
-import string
+from string import hexdigits
-class md5obj:
+class md5obj(object):
md5_module = md5
def __init__(self, name, string=''):
if not name in ('MD5', 'md5'):
- raise ValueError, "unsupported hash type"
+ raise ValueError("unsupported hash type")
self.name = 'md5'
self.m = self.md5_module.md5()
@@ -61,23 +61,8 @@ class md5obj:
def update(self, arg):
return self.m.update(arg)
- if hasattr(md5.md5(), 'hexdigest'):
-
- def hexdigest(self):
- return self.m.hexdigest()
-
- else:
-
- # Objects created by the underlying md5 module have no native
- # hexdigest() method (*cough* 1.5.2 *cough*), so provide an
- # equivalent lifted from elsewhere.
- def hexdigest(self):
- h = string.hexdigits
- r = ''
- for c in self.digest():
- i = ord(c)
- r = r + h[(i >> 4) & 0xF] + h[i & 0xF]
- return r
+ def hexdigest(self):
+ return self.m.hexdigest()
new = md5obj
diff --git a/src/engine/SCons/compat/_scons_io.py b/src/engine/SCons/compat/_scons_io.py
new file mode 100644
index 0000000..3dc6ffd
--- /dev/null
+++ b/src/engine/SCons/compat/_scons_io.py
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
+# 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.
+#
+
+__doc__ = """
+io compatibility module for older (pre-2.6) Python versions
+
+This does not not NOT (repeat, *NOT*) provide complete io
+functionality. It only wraps the portions of io functionality used
+by SCons, in an interface that looks enough like io for our purposes.
+"""
+
+__revision__ = "src/engine/SCons/compat/_scons_io.py 5023 2010/06/14 22:05:46 scons"
+
+# Use the "imp" module to protect the imports below from fixers.
+import imp
+
+_cStringIO = imp.load_module('cStringIO', *imp.find_module('cStringIO'))
+StringIO = _cStringIO.StringIO
+del _cStringIO
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_itertools.py b/src/engine/SCons/compat/_scons_itertools.py
deleted file mode 100644
index 44add7c..0000000
--- a/src/engine/SCons/compat/_scons_itertools.py
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
-# 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__ = "src/engine/SCons/compat/_scons_itertools.py 4720 2010/03/24 03:14:11 jars"
-
-__doc__ = """
-Implementations of itertools functions for Python versions that don't
-have iterators.
-
-These implement the functions by creating the entire list, not returning
-it element-by-element as the real itertools functions do. This means
-that early Python versions won't get the performance benefit of using
-the itertools, but we can still use them so the later Python versions
-do get the advantages of using iterators.
-
-Because we return the entire list, we intentionally do not implement the
-itertools functions that "return" infinitely-long lists: the count(),
-cycle() and repeat() functions. Other functions below have remained
-unimplemented simply because they aren't being used (yet) and it wasn't
-obvious how to do it. Or, conversely, we only implemented those functions
-that *were* easy to implement (mostly because the Python documentation
-contained examples of equivalent code).
-
-Note that these do not have independent unit tests, so it's possible
-that there are bugs.
-"""
-
-def chain(*iterables):
- result = []
- for x in iterables:
- result.extend(list(x))
- return result
-
-def count(n=0):
- # returns infinite length, should not be supported
- raise NotImplementedError
-
-def cycle(iterable):
- # returns infinite length, should not be supported
- raise NotImplementedError
-
-def dropwhile(predicate, iterable):
- result = []
- for x in iterable:
- if not predicate(x):
- result.append(x)
- break
- result.extend(iterable)
- return result
-
-def groupby(iterable, *args):
- raise NotImplementedError
-
-def ifilter(predicate, iterable):
- result = []
- if predicate is None:
- predicate = bool
- for x in iterable:
- if predicate(x):
- result.append(x)
- return result
-
-def ifilterfalse(predicate, iterable):
- result = []
- if predicate is None:
- predicate = bool
- for x in iterable:
- if not predicate(x):
- result.append(x)
- return result
-
-def imap(function, *iterables):
- return apply(map, (function,) + tuple(iterables))
-
-def islice(*args, **kw):
- raise NotImplementedError
-
-def izip(*iterables):
- return apply(zip, iterables)
-
-def repeat(*args, **kw):
- # returns infinite length, should not be supported
- raise NotImplementedError
-
-def starmap(*args, **kw):
- raise NotImplementedError
-
-def takewhile(predicate, iterable):
- result = []
- for x in iterable:
- if predicate(x):
- result.append(x)
- else:
- break
- return result
-
-def tee(*args, **kw):
- raise NotImplementedError
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_optparse.py b/src/engine/SCons/compat/_scons_optparse.py
deleted file mode 100644
index 219adba..0000000
--- a/src/engine/SCons/compat/_scons_optparse.py
+++ /dev/null
@@ -1,1725 +0,0 @@
-"""optparse - a powerful, extensible, and easy-to-use option parser.
-
-By Greg Ward <gward@python.net>
-
-Originally distributed as Optik; see http://optik.sourceforge.net/ .
-
-If you have problems with this module, please do not file bugs,
-patches, or feature requests with Python; instead, use Optik's
-SourceForge project page:
- http://sourceforge.net/projects/optik
-
-For support, use the optik-users@lists.sourceforge.net mailing list
-(http://lists.sourceforge.net/lists/listinfo/optik-users).
-"""
-
-# Python developers: please do not make changes to this file, since
-# it is automatically generated from the Optik source code.
-
-__version__ = "1.5.3"
-
-__all__ = ['Option',
- 'SUPPRESS_HELP',
- 'SUPPRESS_USAGE',
- 'Values',
- 'OptionContainer',
- 'OptionGroup',
- 'OptionParser',
- 'HelpFormatter',
- 'IndentedHelpFormatter',
- 'TitledHelpFormatter',
- 'OptParseError',
- 'OptionError',
- 'OptionConflictError',
- 'OptionValueError',
- 'BadOptionError']
-
-__copyright__ = """
-Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved.
-Copyright (c) 2002-2006 Python Software Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the author nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-"""
-
-import string
-import sys, os
-import types
-import textwrap
-
-def _repr(self):
- return "<%s at 0x%x: %s>" % (self.__class__.__name__, id(self), self)
-
-
-try:
- sys.getdefaultencoding
-except AttributeError:
- def fake_getdefaultencoding():
- return None
- sys.getdefaultencoding = fake_getdefaultencoding
-
-try:
- ''.encode
-except AttributeError:
- def encode_wrapper(s, encoding, replacement):
- return s
-else:
- def encode_wrapper(s, encoding, replacement):
- return s.encode(encoding, replacement)
-
-
-# This file was generated from:
-# Id: option_parser.py 527 2006-07-23 15:21:30Z greg
-# Id: option.py 522 2006-06-11 16:22:03Z gward
-# Id: help.py 527 2006-07-23 15:21:30Z greg
-# Id: errors.py 509 2006-04-20 00:58:24Z gward
-
-try:
- from gettext import gettext
-except ImportError:
- def gettext(message):
- return message
-_ = gettext
-
-
-class OptParseError (Exception):
- def __init__(self, msg):
- self.msg = msg
-
- def __str__(self):
- return self.msg
-
-
-class OptionError (OptParseError):
- """
- Raised if an Option instance is created with invalid or
- inconsistent arguments.
- """
-
- def __init__(self, msg, option):
- self.msg = msg
- self.option_id = str(option)
-
- def __str__(self):
- if self.option_id:
- return "option %s: %s" % (self.option_id, self.msg)
- else:
- return self.msg
-
-class OptionConflictError (OptionError):
- """
- Raised if conflicting options are added to an OptionParser.
- """
-
-class OptionValueError (OptParseError):
- """
- Raised if an invalid option value is encountered on the command
- line.
- """
-
-class BadOptionError (OptParseError):
- """
- Raised if an invalid option is seen on the command line.
- """
- def __init__(self, opt_str):
- self.opt_str = opt_str
-
- def __str__(self):
- return _("no such option: %s") % self.opt_str
-
-class AmbiguousOptionError (BadOptionError):
- """
- Raised if an ambiguous option is seen on the command line.
- """
- def __init__(self, opt_str, possibilities):
- BadOptionError.__init__(self, opt_str)
- self.possibilities = possibilities
-
- def __str__(self):
- return (_("ambiguous option: %s (%s?)")
- % (self.opt_str, string.join(self.possibilities, ", ")))
-
-
-class HelpFormatter:
-
- """
- Abstract base class for formatting option help. OptionParser
- instances should use one of the HelpFormatter subclasses for
- formatting help; by default IndentedHelpFormatter is used.
-
- Instance attributes:
- parser : OptionParser
- the controlling OptionParser instance
- indent_increment : int
- the number of columns to indent per nesting level
- max_help_position : int
- the maximum starting column for option help text
- help_position : int
- the calculated starting column for option help text;
- initially the same as the maximum
- width : int
- total number of columns for output (pass None to constructor for
- this value to be taken from the $COLUMNS environment variable)
- level : int
- current indentation level
- current_indent : int
- current indentation level (in columns)
- help_width : int
- number of columns available for option help text (calculated)
- default_tag : str
- text to replace with each option's default value, "%default"
- by default. Set to false value to disable default value expansion.
- option_strings : { Option : str }
- maps Option instances to the snippet of help text explaining
- the syntax of that option, e.g. "-h, --help" or
- "-fFILE, --file=FILE"
- _short_opt_fmt : str
- format string controlling how short options with values are
- printed in help text. Must be either "%s%s" ("-fFILE") or
- "%s %s" ("-f FILE"), because those are the two syntaxes that
- Optik supports.
- _long_opt_fmt : str
- similar but for long options; must be either "%s %s" ("--file FILE")
- or "%s=%s" ("--file=FILE").
- """
-
- NO_DEFAULT_VALUE = "none"
-
- def __init__(self,
- indent_increment,
- max_help_position,
- width,
- short_first):
- self.parser = None
- self.indent_increment = indent_increment
- self.help_position = self.max_help_position = max_help_position
- if width is None:
- try:
- width = int(os.environ['COLUMNS'])
- except (KeyError, ValueError):
- width = 80
- width = width - 2
- self.width = width
- self.current_indent = 0
- self.level = 0
- self.help_width = None # computed later
- self.short_first = short_first
- self.default_tag = "%default"
- self.option_strings = {}
- self._short_opt_fmt = "%s %s"
- self._long_opt_fmt = "%s=%s"
-
- def set_parser(self, parser):
- self.parser = parser
-
- def set_short_opt_delimiter(self, delim):
- if delim not in ("", " "):
- raise ValueError(
- "invalid metavar delimiter for short options: %r" % delim)
- self._short_opt_fmt = "%s" + delim + "%s"
-
- def set_long_opt_delimiter(self, delim):
- if delim not in ("=", " "):
- raise ValueError(
- "invalid metavar delimiter for long options: %r" % delim)
- self._long_opt_fmt = "%s" + delim + "%s"
-
- def indent(self):
- self.current_indent = self.current_indent + self.indent_increment
- self.level = self.level + 1
-
- def dedent(self):
- self.current_indent = self.current_indent - self.indent_increment
- assert self.current_indent >= 0, "Indent decreased below 0."
- self.level = self.level - 1
-
- def format_usage(self, usage):
- raise NotImplementedError, "subclasses must implement"
-
- def format_heading(self, heading):
- raise NotImplementedError, "subclasses must implement"
-
- def _format_text(self, text):
- """
- Format a paragraph of free-form text for inclusion in the
- help output at the current indentation level.
- """
- text_width = self.width - self.current_indent
- indent = " "*self.current_indent
- return textwrap.fill(text,
- text_width,
- initial_indent=indent,
- subsequent_indent=indent)
-
- def format_description(self, description):
- if description:
- return self._format_text(description) + "\n"
- else:
- return ""
-
- def format_epilog(self, epilog):
- if epilog:
- return "\n" + self._format_text(epilog) + "\n"
- else:
- return ""
-
-
- def expand_default(self, option):
- if self.parser is None or not self.default_tag:
- return option.help
-
- default_value = self.parser.defaults.get(option.dest)
- if default_value is NO_DEFAULT or default_value is None:
- default_value = self.NO_DEFAULT_VALUE
-
- return string.replace(option.help, self.default_tag, str(default_value))
-
- def format_option(self, option):
- # The help for each option consists of two parts:
- # * the opt strings and metavars
- # eg. ("-x", or "-fFILENAME, --file=FILENAME")
- # * the user-supplied help string
- # eg. ("turn on expert mode", "read data from FILENAME")
- #
- # If possible, we write both of these on the same line:
- # -x turn on expert mode
- #
- # But if the opt string list is too long, we put the help
- # string on a second line, indented to the same column it would
- # start in if it fit on the first line.
- # -fFILENAME, --file=FILENAME
- # read data from FILENAME
- result = []
- opts = self.option_strings[option]
- opt_width = self.help_position - self.current_indent - 2
- if len(opts) > opt_width:
- opts = "%*s%s\n" % (self.current_indent, "", opts)
- indent_first = self.help_position
- else: # start help on same line as opts
- opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
- indent_first = 0
- result.append(opts)
- if option.help:
- help_text = self.expand_default(option)
- help_lines = textwrap.wrap(help_text, self.help_width)
- result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
- for line in help_lines[1:]:
- result.append("%*s%s\n" % (self.help_position, "", line))
- elif opts[-1] != "\n":
- result.append("\n")
- return string.join(result, "")
-
- def store_option_strings(self, parser):
- self.indent()
- max_len = 0
- for opt in parser.option_list:
- strings = self.format_option_strings(opt)
- self.option_strings[opt] = strings
- max_len = max(max_len, len(strings) + self.current_indent)
- self.indent()
- for group in parser.option_groups:
- for opt in group.option_list:
- strings = self.format_option_strings(opt)
- self.option_strings[opt] = strings
- max_len = max(max_len, len(strings) + self.current_indent)
- self.dedent()
- self.dedent()
- self.help_position = min(max_len + 2, self.max_help_position)
- self.help_width = self.width - self.help_position
-
- def format_option_strings(self, option):
- """Return a comma-separated list of option strings & metavariables."""
- if option.takes_value():
- metavar = option.metavar or string.upper(option.dest)
- short_opts = []
- for sopt in option._short_opts:
- short_opts.append(self._short_opt_fmt % (sopt, metavar))
- long_opts = []
- for lopt in option._long_opts:
- long_opts.append(self._long_opt_fmt % (lopt, metavar))
- else:
- short_opts = option._short_opts
- long_opts = option._long_opts
-
- if self.short_first:
- opts = short_opts + long_opts
- else:
- opts = long_opts + short_opts
-
- return string.join(opts, ", ")
-
-class IndentedHelpFormatter (HelpFormatter):
- """Format help with indented section bodies.
- """
-
- def __init__(self,
- indent_increment=2,
- max_help_position=24,
- width=None,
- short_first=1):
- HelpFormatter.__init__(
- self, indent_increment, max_help_position, width, short_first)
-
- def format_usage(self, usage):
- return _("Usage: %s\n") % usage
-
- def format_heading(self, heading):
- return "%*s%s:\n" % (self.current_indent, "", heading)
-
-
-class TitledHelpFormatter (HelpFormatter):
- """Format help with underlined section headers.
- """
-
- def __init__(self,
- indent_increment=0,
- max_help_position=24,
- width=None,
- short_first=0):
- HelpFormatter.__init__ (
- self, indent_increment, max_help_position, width, short_first)
-
- def format_usage(self, usage):
- return "%s %s\n" % (self.format_heading(_("Usage")), usage)
-
- def format_heading(self, heading):
- return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
-
-
-def _parse_num(val, type):
- if string.lower(val[:2]) == "0x": # hexadecimal
- radix = 16
- elif string.lower(val[:2]) == "0b": # binary
- radix = 2
- val = val[2:] or "0" # have to remove "0b" prefix
- elif val[:1] == "0": # octal
- radix = 8
- else: # decimal
- radix = 10
-
- return type(val, radix)
-
-def _parse_int(val):
- return _parse_num(val, int)
-
-def _parse_long(val):
- return _parse_num(val, long)
-
-try:
- int('0', 10)
-except TypeError:
- # Python 1.5.2 doesn't allow a radix value to be passed to int().
- _parse_int = int
-
-try:
- long('0', 10)
-except TypeError:
- # Python 1.5.2 doesn't allow a radix value to be passed to long().
- _parse_long = long
-
-_builtin_cvt = { "int" : (_parse_int, _("integer")),
- "long" : (_parse_long, _("long integer")),
- "float" : (float, _("floating-point")),
- "complex" : (complex, _("complex")) }
-
-def check_builtin(option, opt, value):
- (cvt, what) = _builtin_cvt[option.type]
- try:
- return cvt(value)
- except ValueError:
- raise OptionValueError(
- _("option %s: invalid %s value: %r") % (opt, what, value))
-
-def check_choice(option, opt, value):
- if value in option.choices:
- return value
- else:
- choices = string.join(map(repr, option.choices), ", ")
- raise OptionValueError(
- _("option %s: invalid choice: %r (choose from %s)")
- % (opt, value, choices))
-
-# Not supplying a default is different from a default of None,
-# so we need an explicit "not supplied" value.
-NO_DEFAULT = ("NO", "DEFAULT")
-
-
-class Option:
- """
- Instance attributes:
- _short_opts : [string]
- _long_opts : [string]
-
- action : string
- type : string
- dest : string
- default : any
- nargs : int
- const : any
- choices : [string]
- callback : function
- callback_args : (any*)
- callback_kwargs : { string : any }
- help : string
- metavar : string
- """
-
- # The list of instance attributes that may be set through
- # keyword args to the constructor.
- ATTRS = ['action',
- 'type',
- 'dest',
- 'default',
- 'nargs',
- 'const',
- 'choices',
- 'callback',
- 'callback_args',
- 'callback_kwargs',
- 'help',
- 'metavar']
-
- # The set of actions allowed by option parsers. Explicitly listed
- # here so the constructor can validate its arguments.
- ACTIONS = ("store",
- "store_const",
- "store_true",
- "store_false",
- "append",
- "append_const",
- "count",
- "callback",
- "help",
- "version")
-
- # The set of actions that involve storing a value somewhere;
- # also listed just for constructor argument validation. (If
- # the action is one of these, there must be a destination.)
- STORE_ACTIONS = ("store",
- "store_const",
- "store_true",
- "store_false",
- "append",
- "append_const",
- "count")
-
- # The set of actions for which it makes sense to supply a value
- # type, ie. which may consume an argument from the command line.
- TYPED_ACTIONS = ("store",
- "append",
- "callback")
-
- # The set of actions which *require* a value type, ie. that
- # always consume an argument from the command line.
- ALWAYS_TYPED_ACTIONS = ("store",
- "append")
-
- # The set of actions which take a 'const' attribute.
- CONST_ACTIONS = ("store_const",
- "append_const")
-
- # The set of known types for option parsers. Again, listed here for
- # constructor argument validation.
- TYPES = ("string", "int", "long", "float", "complex", "choice")
-
- # Dictionary of argument checking functions, which convert and
- # validate option arguments according to the option type.
- #
- # Signature of checking functions is:
- # check(option : Option, opt : string, value : string) -> any
- # where
- # option is the Option instance calling the checker
- # opt is the actual option seen on the command-line
- # (eg. "-a", "--file")
- # value is the option argument seen on the command-line
- #
- # The return value should be in the appropriate Python type
- # for option.type -- eg. an integer if option.type == "int".
- #
- # If no checker is defined for a type, arguments will be
- # unchecked and remain strings.
- TYPE_CHECKER = { "int" : check_builtin,
- "long" : check_builtin,
- "float" : check_builtin,
- "complex": check_builtin,
- "choice" : check_choice,
- }
-
-
- # CHECK_METHODS is a list of unbound method objects; they are called
- # by the constructor, in order, after all attributes are
- # initialized. The list is created and filled in later, after all
- # the methods are actually defined. (I just put it here because I
- # like to define and document all class attributes in the same
- # place.) Subclasses that add another _check_*() method should
- # define their own CHECK_METHODS list that adds their check method
- # to those from this class.
- CHECK_METHODS = None
-
-
- # -- Constructor/initialization methods ----------------------------
-
- def __init__(self, *opts, **attrs):
- # Set _short_opts, _long_opts attrs from 'opts' tuple.
- # Have to be set now, in case no option strings are supplied.
- self._short_opts = []
- self._long_opts = []
- opts = self._check_opt_strings(opts)
- self._set_opt_strings(opts)
-
- # Set all other attrs (action, type, etc.) from 'attrs' dict
- self._set_attrs(attrs)
-
- # Check all the attributes we just set. There are lots of
- # complicated interdependencies, but luckily they can be farmed
- # out to the _check_*() methods listed in CHECK_METHODS -- which
- # could be handy for subclasses! The one thing these all share
- # is that they raise OptionError if they discover a problem.
- for checker in self.CHECK_METHODS:
- checker(self)
-
- def _check_opt_strings(self, opts):
- # Filter out None because early versions of Optik had exactly
- # one short option and one long option, either of which
- # could be None.
- opts = filter(None, opts)
- if not opts:
- raise TypeError("at least one option string must be supplied")
- return opts
-
- def _set_opt_strings(self, opts):
- for opt in opts:
- if len(opt) < 2:
- raise OptionError(
- "invalid option string %r: "
- "must be at least two characters long" % opt, self)
- elif len(opt) == 2:
- if not (opt[0] == "-" and opt[1] != "-"):
- raise OptionError(
- "invalid short option string %r: "
- "must be of the form -x, (x any non-dash char)" % opt,
- self)
- self._short_opts.append(opt)
- else:
- if not (opt[0:2] == "--" and opt[2] != "-"):
- raise OptionError(
- "invalid long option string %r: "
- "must start with --, followed by non-dash" % opt,
- self)
- self._long_opts.append(opt)
-
- def _set_attrs(self, attrs):
- for attr in self.ATTRS:
- if attrs.has_key(attr):
- setattr(self, attr, attrs[attr])
- del attrs[attr]
- else:
- if attr == 'default':
- setattr(self, attr, NO_DEFAULT)
- else:
- setattr(self, attr, None)
- if attrs:
- attrs = attrs.keys()
- attrs.sort()
- raise OptionError(
- "invalid keyword arguments: %s" % string.join(attrs, ", "),
- self)
-
-
- # -- Constructor validation methods --------------------------------
-
- def _check_action(self):
- if self.action is None:
- self.action = "store"
- elif self.action not in self.ACTIONS:
- raise OptionError("invalid action: %r" % self.action, self)
-
- def _check_type(self):
- if self.type is None:
- if self.action in self.ALWAYS_TYPED_ACTIONS:
- if self.choices is not None:
- # The "choices" attribute implies "choice" type.
- self.type = "choice"
- else:
- # No type given? "string" is the most sensible default.
- self.type = "string"
- else:
- # Allow type objects or builtin type conversion functions
- # (int, str, etc.) as an alternative to their names. (The
- # complicated check of __builtin__ is only necessary for
- # Python 2.1 and earlier, and is short-circuited by the
- # first check on modern Pythons.)
- import __builtin__
- if ( type(self.type) is types.TypeType or
- (hasattr(self.type, "__name__") and
- getattr(__builtin__, self.type.__name__, None) is self.type) ):
- self.type = self.type.__name__
-
- if self.type == "str":
- self.type = "string"
-
- if self.type not in self.TYPES:
- raise OptionError("invalid option type: %r" % self.type, self)
- if self.action not in self.TYPED_ACTIONS:
- raise OptionError(
- "must not supply a type for action %r" % self.action, self)
-
- def _check_choice(self):
- if self.type == "choice":
- if self.choices is None:
- raise OptionError(
- "must supply a list of choices for type 'choice'", self)
- elif type(self.choices) not in (types.TupleType, types.ListType):
- raise OptionError(
- "choices must be a list of strings ('%s' supplied)"
- % string.split(str(type(self.choices)), "'")[1], self)
- elif self.choices is not None:
- raise OptionError(
- "must not supply choices for type %r" % self.type, self)
-
- def _check_dest(self):
- # No destination given, and we need one for this action. The
- # self.type check is for callbacks that take a value.
- takes_value = (self.action in self.STORE_ACTIONS or
- self.type is not None)
- if self.dest is None and takes_value:
-
- # Glean a destination from the first long option string,
- # or from the first short option string if no long options.
- if self._long_opts:
- # eg. "--foo-bar" -> "foo_bar"
- self.dest = string.replace(self._long_opts[0][2:], '-', '_')
- else:
- self.dest = self._short_opts[0][1]
-
- def _check_const(self):
- if self.action not in self.CONST_ACTIONS and self.const is not None:
- raise OptionError(
- "'const' must not be supplied for action %r" % self.action,
- self)
-
- def _check_nargs(self):
- if self.action in self.TYPED_ACTIONS:
- if self.nargs is None:
- self.nargs = 1
- elif self.nargs is not None:
- raise OptionError(
- "'nargs' must not be supplied for action %r" % self.action,
- self)
-
- def _check_callback(self):
- if self.action == "callback":
- if not callable(self.callback):
- raise OptionError(
- "callback not callable: %r" % self.callback, self)
- if (self.callback_args is not None and
- type(self.callback_args) is not types.TupleType):
- raise OptionError(
- "callback_args, if supplied, must be a tuple: not %r"
- % self.callback_args, self)
- if (self.callback_kwargs is not None and
- type(self.callback_kwargs) is not types.DictType):
- raise OptionError(
- "callback_kwargs, if supplied, must be a dict: not %r"
- % self.callback_kwargs, self)
- else:
- if self.callback is not None:
- raise OptionError(
- "callback supplied (%r) for non-callback option"
- % self.callback, self)
- if self.callback_args is not None:
- raise OptionError(
- "callback_args supplied for non-callback option", self)
- if self.callback_kwargs is not None:
- raise OptionError(
- "callback_kwargs supplied for non-callback option", self)
-
-
- CHECK_METHODS = [_check_action,
- _check_type,
- _check_choice,
- _check_dest,
- _check_const,
- _check_nargs,
- _check_callback]
-
-
- # -- Miscellaneous methods -----------------------------------------
-
- def __str__(self):
- return string.join(self._short_opts + self._long_opts, "/")
-
- __repr__ = _repr
-
- def takes_value(self):
- return self.type is not None
-
- def get_opt_string(self):
- if self._long_opts:
- return self._long_opts[0]
- else:
- return self._short_opts[0]
-
-
- # -- Processing methods --------------------------------------------
-
- def check_value(self, opt, value):
- checker = self.TYPE_CHECKER.get(self.type)
- if checker is None:
- return value
- else:
- return checker(self, opt, value)
-
- def convert_value(self, opt, value):
- if value is not None:
- if self.nargs == 1:
- return self.check_value(opt, value)
- else:
- return tuple(map(lambda v, o=opt, s=self: s.check_value(o, v), value))
-
- def process(self, opt, value, values, parser):
-
- # First, convert the value(s) to the right type. Howl if any
- # value(s) are bogus.
- value = self.convert_value(opt, value)
-
- # And then take whatever action is expected of us.
- # This is a separate method to make life easier for
- # subclasses to add new actions.
- return self.take_action(
- self.action, self.dest, opt, value, values, parser)
-
- def take_action(self, action, dest, opt, value, values, parser):
- if action == "store":
- setattr(values, dest, value)
- elif action == "store_const":
- setattr(values, dest, self.const)
- elif action == "store_true":
- setattr(values, dest, True)
- elif action == "store_false":
- setattr(values, dest, False)
- elif action == "append":
- values.ensure_value(dest, []).append(value)
- elif action == "append_const":
- values.ensure_value(dest, []).append(self.const)
- elif action == "count":
- setattr(values, dest, values.ensure_value(dest, 0) + 1)
- elif action == "callback":
- args = self.callback_args or ()
- kwargs = self.callback_kwargs or {}
- apply(self.callback, (self, opt, value, parser,) + args, kwargs)
- elif action == "help":
- parser.print_help()
- parser.exit()
- elif action == "version":
- parser.print_version()
- parser.exit()
- else:
- raise RuntimeError, "unknown action %r" % self.action
-
- return 1
-
-# class Option
-
-
-SUPPRESS_HELP = "SUPPRESS"+"HELP"
-SUPPRESS_USAGE = "SUPPRESS"+"USAGE"
-
-# For compatibility with Python 2.2
-try:
- True, False
-except NameError:
- (True, False) = (1, 0)
-
-try:
- types.UnicodeType
-except AttributeError:
- def isbasestring(x):
- return isinstance(x, types.StringType)
-else:
- def isbasestring(x):
- return isinstance(x, types.StringType) or isinstance(x, types.UnicodeType)
-
-class Values:
-
- def __init__(self, defaults=None):
- if defaults:
- for (attr, val) in defaults.items():
- setattr(self, attr, val)
-
- def __str__(self):
- return str(self.__dict__)
-
- __repr__ = _repr
-
- def __cmp__(self, other):
- if isinstance(other, Values):
- return cmp(self.__dict__, other.__dict__)
- elif isinstance(other, types.DictType):
- return cmp(self.__dict__, other)
- else:
- return -1
-
- def _update_careful(self, dict):
- """
- Update the option values from an arbitrary dictionary, but only
- use keys from dict that already have a corresponding attribute
- in self. Any keys in dict without a corresponding attribute
- are silently ignored.
- """
- for attr in dir(self):
- if dict.has_key(attr):
- dval = dict[attr]
- if dval is not None:
- setattr(self, attr, dval)
-
- def _update_loose(self, dict):
- """
- Update the option values from an arbitrary dictionary,
- using all keys from the dictionary regardless of whether
- they have a corresponding attribute in self or not.
- """
- self.__dict__.update(dict)
-
- def _update(self, dict, mode):
- if mode == "careful":
- self._update_careful(dict)
- elif mode == "loose":
- self._update_loose(dict)
- else:
- raise ValueError, "invalid update mode: %r" % mode
-
- def read_module(self, modname, mode="careful"):
- __import__(modname)
- mod = sys.modules[modname]
- self._update(vars(mod), mode)
-
- def read_file(self, filename, mode="careful"):
- vars = {}
- exec open(filename, 'rU').read() in vars
- self._update(vars, mode)
-
- def ensure_value(self, attr, value):
- if not hasattr(self, attr) or getattr(self, attr) is None:
- setattr(self, attr, value)
- return getattr(self, attr)
-
-
-class OptionContainer:
-
- """
- Abstract base class.
-
- Class attributes:
- standard_option_list : [Option]
- list of standard options that will be accepted by all instances
- of this parser class (intended to be overridden by subclasses).
-
- Instance attributes:
- option_list : [Option]
- the list of Option objects contained by this OptionContainer
- _short_opt : { string : Option }
- dictionary mapping short option strings, eg. "-f" or "-X",
- to the Option instances that implement them. If an Option
- has multiple short option strings, it will appears in this
- dictionary multiple times. [1]
- _long_opt : { string : Option }
- dictionary mapping long option strings, eg. "--file" or
- "--exclude", to the Option instances that implement them.
- Again, a given Option can occur multiple times in this
- dictionary. [1]
- defaults : { string : any }
- dictionary mapping option destination names to default
- values for each destination [1]
-
- [1] These mappings are common to (shared by) all components of the
- controlling OptionParser, where they are initially created.
-
- """
-
- def __init__(self, option_class, conflict_handler, description):
- # Initialize the option list and related data structures.
- # This method must be provided by subclasses, and it must
- # initialize at least the following instance attributes:
- # option_list, _short_opt, _long_opt, defaults.
- self._create_option_list()
-
- self.option_class = option_class
- self.set_conflict_handler(conflict_handler)
- self.set_description(description)
-
- def _create_option_mappings(self):
- # For use by OptionParser constructor -- create the master
- # option mappings used by this OptionParser and all
- # OptionGroups that it owns.
- self._short_opt = {} # single letter -> Option instance
- self._long_opt = {} # long option -> Option instance
- self.defaults = {} # maps option dest -> default value
-
-
- def _share_option_mappings(self, parser):
- # For use by OptionGroup constructor -- use shared option
- # mappings from the OptionParser that owns this OptionGroup.
- self._short_opt = parser._short_opt
- self._long_opt = parser._long_opt
- self.defaults = parser.defaults
-
- def set_conflict_handler(self, handler):
- if handler not in ("error", "resolve"):
- raise ValueError, "invalid conflict_resolution value %r" % handler
- self.conflict_handler = handler
-
- def set_description(self, description):
- self.description = description
-
- def get_description(self):
- return self.description
-
-
- def destroy(self):
- """see OptionParser.destroy()."""
- del self._short_opt
- del self._long_opt
- del self.defaults
-
-
- # -- Option-adding methods -----------------------------------------
-
- def _check_conflict(self, option):
- conflict_opts = []
- for opt in option._short_opts:
- if self._short_opt.has_key(opt):
- conflict_opts.append((opt, self._short_opt[opt]))
- for opt in option._long_opts:
- if self._long_opt.has_key(opt):
- conflict_opts.append((opt, self._long_opt[opt]))
-
- if conflict_opts:
- handler = self.conflict_handler
- if handler == "error":
- raise OptionConflictError(
- "conflicting option string(s): %s"
- % string.join(map(lambda co: co[0], conflict_opts), ", "),
- option)
- elif handler == "resolve":
- for (opt, c_option) in conflict_opts:
- if opt[:2] == "--":
- c_option._long_opts.remove(opt)
- del self._long_opt[opt]
- else:
- c_option._short_opts.remove(opt)
- del self._short_opt[opt]
- if not (c_option._short_opts or c_option._long_opts):
- c_option.container.option_list.remove(c_option)
-
- def add_option(self, *args, **kwargs):
- """add_option(Option)
- add_option(opt_str, ..., kwarg=val, ...)
- """
- if type(args[0]) is types.StringType:
- option = apply(self.option_class, args, kwargs)
- elif len(args) == 1 and not kwargs:
- option = args[0]
- if not isinstance(option, Option):
- raise TypeError, "not an Option instance: %r" % option
- else:
- raise TypeError, "invalid arguments"
-
- self._check_conflict(option)
-
- self.option_list.append(option)
- option.container = self
- for opt in option._short_opts:
- self._short_opt[opt] = option
- for opt in option._long_opts:
- self._long_opt[opt] = option
-
- if option.dest is not None: # option has a dest, we need a default
- if option.default is not NO_DEFAULT:
- self.defaults[option.dest] = option.default
- elif not self.defaults.has_key(option.dest):
- self.defaults[option.dest] = None
-
- return option
-
- def add_options(self, option_list):
- for option in option_list:
- self.add_option(option)
-
- # -- Option query/removal methods ----------------------------------
-
- def get_option(self, opt_str):
- return (self._short_opt.get(opt_str) or
- self._long_opt.get(opt_str))
-
- def has_option(self, opt_str):
- return (self._short_opt.has_key(opt_str) or
- self._long_opt.has_key(opt_str))
-
- def remove_option(self, opt_str):
- option = self._short_opt.get(opt_str)
- if option is None:
- option = self._long_opt.get(opt_str)
- if option is None:
- raise ValueError("no such option %r" % opt_str)
-
- for opt in option._short_opts:
- del self._short_opt[opt]
- for opt in option._long_opts:
- del self._long_opt[opt]
- option.container.option_list.remove(option)
-
-
- # -- Help-formatting methods ---------------------------------------
-
- def format_option_help(self, formatter):
- if not self.option_list:
- return ""
- result = []
- for option in self.option_list:
- if not option.help is SUPPRESS_HELP:
- result.append(formatter.format_option(option))
- return string.join(result, "")
-
- def format_description(self, formatter):
- return formatter.format_description(self.get_description())
-
- def format_help(self, formatter):
- result = []
- if self.description:
- result.append(self.format_description(formatter))
- if self.option_list:
- result.append(self.format_option_help(formatter))
- return string.join(result, "\n")
-
-
-class OptionGroup (OptionContainer):
-
- def __init__(self, parser, title, description=None):
- self.parser = parser
- OptionContainer.__init__(
- self, parser.option_class, parser.conflict_handler, description)
- self.title = title
-
- def _create_option_list(self):
- self.option_list = []
- self._share_option_mappings(self.parser)
-
- def set_title(self, title):
- self.title = title
-
- def destroy(self):
- """see OptionParser.destroy()."""
- OptionContainer.destroy(self)
- del self.option_list
-
- # -- Help-formatting methods ---------------------------------------
-
- def format_help(self, formatter):
- result = formatter.format_heading(self.title)
- formatter.indent()
- result = result + OptionContainer.format_help(self, formatter)
- formatter.dedent()
- return result
-
-
-class OptionParser (OptionContainer):
-
- """
- Class attributes:
- standard_option_list : [Option]
- list of standard options that will be accepted by all instances
- of this parser class (intended to be overridden by subclasses).
-
- Instance attributes:
- usage : string
- a usage string for your program. Before it is displayed
- to the user, "%prog" will be expanded to the name of
- your program (self.prog or os.path.basename(sys.argv[0])).
- prog : string
- the name of the current program (to override
- os.path.basename(sys.argv[0])).
- epilog : string
- paragraph of help text to print after option help
-
- option_groups : [OptionGroup]
- list of option groups in this parser (option groups are
- irrelevant for parsing the command-line, but very useful
- for generating help)
-
- allow_interspersed_args : bool = true
- if true, positional arguments may be interspersed with options.
- Assuming -a and -b each take a single argument, the command-line
- -ablah foo bar -bboo baz
- will be interpreted the same as
- -ablah -bboo -- foo bar baz
- If this flag were false, that command line would be interpreted as
- -ablah -- foo bar -bboo baz
- -- ie. we stop processing options as soon as we see the first
- non-option argument. (This is the tradition followed by
- Python's getopt module, Perl's Getopt::Std, and other argument-
- parsing libraries, but it is generally annoying to users.)
-
- process_default_values : bool = true
- if true, option default values are processed similarly to option
- values from the command line: that is, they are passed to the
- type-checking function for the option's type (as long as the
- default value is a string). (This really only matters if you
- have defined custom types; see SF bug #955889.) Set it to false
- to restore the behaviour of Optik 1.4.1 and earlier.
-
- rargs : [string]
- the argument list currently being parsed. Only set when
- parse_args() is active, and continually trimmed down as
- we consume arguments. Mainly there for the benefit of
- callback options.
- largs : [string]
- the list of leftover arguments that we have skipped while
- parsing options. If allow_interspersed_args is false, this
- list is always empty.
- values : Values
- the set of option values currently being accumulated. Only
- set when parse_args() is active. Also mainly for callbacks.
-
- Because of the 'rargs', 'largs', and 'values' attributes,
- OptionParser is not thread-safe. If, for some perverse reason, you
- need to parse command-line arguments simultaneously in different
- threads, use different OptionParser instances.
-
- """
-
- standard_option_list = []
-
- def __init__(self,
- usage=None,
- option_list=None,
- option_class=Option,
- version=None,
- conflict_handler="error",
- description=None,
- formatter=None,
- add_help_option=True,
- prog=None,
- epilog=None):
- OptionContainer.__init__(
- self, option_class, conflict_handler, description)
- self.set_usage(usage)
- self.prog = prog
- self.version = version
- self.allow_interspersed_args = True
- self.process_default_values = True
- if formatter is None:
- formatter = IndentedHelpFormatter()
- self.formatter = formatter
- self.formatter.set_parser(self)
- self.epilog = epilog
-
- # Populate the option list; initial sources are the
- # standard_option_list class attribute, the 'option_list'
- # argument, and (if applicable) the _add_version_option() and
- # _add_help_option() methods.
- self._populate_option_list(option_list,
- add_help=add_help_option)
-
- self._init_parsing_state()
-
-
- def destroy(self):
- """
- Declare that you are done with this OptionParser. This cleans up
- reference cycles so the OptionParser (and all objects referenced by
- it) can be garbage-collected promptly. After calling destroy(), the
- OptionParser is unusable.
- """
- OptionContainer.destroy(self)
- for group in self.option_groups:
- group.destroy()
- del self.option_list
- del self.option_groups
- del self.formatter
-
-
- # -- Private methods -----------------------------------------------
- # (used by our or OptionContainer's constructor)
-
- def _create_option_list(self):
- self.option_list = []
- self.option_groups = []
- self._create_option_mappings()
-
- def _add_help_option(self):
- self.add_option("-h", "--help",
- action="help",
- help=_("show this help message and exit"))
-
- def _add_version_option(self):
- self.add_option("--version",
- action="version",
- help=_("show program's version number and exit"))
-
- def _populate_option_list(self, option_list, add_help=True):
- if self.standard_option_list:
- self.add_options(self.standard_option_list)
- if option_list:
- self.add_options(option_list)
- if self.version:
- self._add_version_option()
- if add_help:
- self._add_help_option()
-
- def _init_parsing_state(self):
- # These are set in parse_args() for the convenience of callbacks.
- self.rargs = None
- self.largs = None
- self.values = None
-
-
- # -- Simple modifier methods ---------------------------------------
-
- def set_usage(self, usage):
- if usage is None:
- self.usage = _("%prog [options]")
- elif usage is SUPPRESS_USAGE:
- self.usage = None
- # For backwards compatibility with Optik 1.3 and earlier.
- elif string.lower(usage)[:7] == "usage: ":
- self.usage = usage[7:]
- else:
- self.usage = usage
-
- def enable_interspersed_args(self):
- self.allow_interspersed_args = True
-
- def disable_interspersed_args(self):
- self.allow_interspersed_args = False
-
- def set_process_default_values(self, process):
- self.process_default_values = process
-
- def set_default(self, dest, value):
- self.defaults[dest] = value
-
- def set_defaults(self, **kwargs):
- self.defaults.update(kwargs)
-
- def _get_all_options(self):
- options = self.option_list[:]
- for group in self.option_groups:
- options.extend(group.option_list)
- return options
-
- def get_default_values(self):
- if not self.process_default_values:
- # Old, pre-Optik 1.5 behaviour.
- return Values(self.defaults)
-
- defaults = self.defaults.copy()
- for option in self._get_all_options():
- default = defaults.get(option.dest)
- if isbasestring(default):
- opt_str = option.get_opt_string()
- defaults[option.dest] = option.check_value(opt_str, default)
-
- return Values(defaults)
-
-
- # -- OptionGroup methods -------------------------------------------
-
- def add_option_group(self, *args, **kwargs):
- # XXX lots of overlap with OptionContainer.add_option()
- if type(args[0]) is types.StringType:
- group = apply(OptionGroup, (self,) + args, kwargs)
- elif len(args) == 1 and not kwargs:
- group = args[0]
- if not isinstance(group, OptionGroup):
- raise TypeError, "not an OptionGroup instance: %r" % group
- if group.parser is not self:
- raise ValueError, "invalid OptionGroup (wrong parser)"
- else:
- raise TypeError, "invalid arguments"
-
- self.option_groups.append(group)
- return group
-
- def get_option_group(self, opt_str):
- option = (self._short_opt.get(opt_str) or
- self._long_opt.get(opt_str))
- if option and option.container is not self:
- return option.container
- return None
-
-
- # -- Option-parsing methods ----------------------------------------
-
- def _get_args(self, args):
- if args is None:
- return sys.argv[1:]
- else:
- return args[:] # don't modify caller's list
-
- def parse_args(self, args=None, values=None):
- """
- parse_args(args : [string] = sys.argv[1:],
- values : Values = None)
- -> (values : Values, args : [string])
-
- Parse the command-line options found in 'args' (default:
- sys.argv[1:]). Any errors result in a call to 'error()', which
- by default prints the usage message to stderr and calls
- sys.exit() with an error message. On success returns a pair
- (values, args) where 'values' is an Values instance (with all
- your option values) and 'args' is the list of arguments left
- over after parsing options.
- """
- rargs = self._get_args(args)
- if values is None:
- values = self.get_default_values()
-
- # Store the halves of the argument list as attributes for the
- # convenience of callbacks:
- # rargs
- # the rest of the command-line (the "r" stands for
- # "remaining" or "right-hand")
- # largs
- # the leftover arguments -- ie. what's left after removing
- # options and their arguments (the "l" stands for "leftover"
- # or "left-hand")
- self.rargs = rargs
- self.largs = largs = []
- self.values = values
-
- try:
- stop = self._process_args(largs, rargs, values)
- except (BadOptionError, OptionValueError), err:
- self.error(str(err))
-
- args = largs + rargs
- return self.check_values(values, args)
-
- def check_values(self, values, args):
- """
- check_values(values : Values, args : [string])
- -> (values : Values, args : [string])
-
- Check that the supplied option values and leftover arguments are
- valid. Returns the option values and leftover arguments
- (possibly adjusted, possibly completely new -- whatever you
- like). Default implementation just returns the passed-in
- values; subclasses may override as desired.
- """
- return (values, args)
-
- def _process_args(self, largs, rargs, values):
- """_process_args(largs : [string],
- rargs : [string],
- values : Values)
-
- Process command-line arguments and populate 'values', consuming
- options and arguments from 'rargs'. If 'allow_interspersed_args' is
- false, stop at the first non-option argument. If true, accumulate any
- interspersed non-option arguments in 'largs'.
- """
- while rargs:
- arg = rargs[0]
- # We handle bare "--" explicitly, and bare "-" is handled by the
- # standard arg handler since the short arg case ensures that the
- # len of the opt string is greater than 1.
- if arg == "--":
- del rargs[0]
- return
- elif arg[0:2] == "--":
- # process a single long option (possibly with value(s))
- self._process_long_opt(rargs, values)
- elif arg[:1] == "-" and len(arg) > 1:
- # process a cluster of short options (possibly with
- # value(s) for the last one only)
- self._process_short_opts(rargs, values)
- elif self.allow_interspersed_args:
- largs.append(arg)
- del rargs[0]
- else:
- return # stop now, leave this arg in rargs
-
- # Say this is the original argument list:
- # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
- # ^
- # (we are about to process arg(i)).
- #
- # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
- # [arg0, ..., arg(i-1)] (any options and their arguments will have
- # been removed from largs).
- #
- # The while loop will usually consume 1 or more arguments per pass.
- # If it consumes 1 (eg. arg is an option that takes no arguments),
- # then after _process_arg() is done the situation is:
- #
- # largs = subset of [arg0, ..., arg(i)]
- # rargs = [arg(i+1), ..., arg(N-1)]
- #
- # If allow_interspersed_args is false, largs will always be
- # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
- # not a very interesting subset!
-
- def _match_long_opt(self, opt):
- """_match_long_opt(opt : string) -> string
-
- Determine which long option string 'opt' matches, ie. which one
- it is an unambiguous abbrevation for. Raises BadOptionError if
- 'opt' doesn't unambiguously match any long option string.
- """
- return _match_abbrev(opt, self._long_opt)
-
- def _process_long_opt(self, rargs, values):
- arg = rargs.pop(0)
-
- # Value explicitly attached to arg? Pretend it's the next
- # argument.
- if "=" in arg:
- (opt, next_arg) = string.split(arg, "=", 1)
- rargs.insert(0, next_arg)
- had_explicit_value = True
- else:
- opt = arg
- had_explicit_value = False
-
- opt = self._match_long_opt(opt)
- option = self._long_opt[opt]
- if option.takes_value():
- nargs = option.nargs
- if len(rargs) < nargs:
- if nargs == 1:
- self.error(_("%s option requires an argument") % opt)
- else:
- self.error(_("%s option requires %d arguments")
- % (opt, nargs))
- elif nargs == 1:
- value = rargs.pop(0)
- else:
- value = tuple(rargs[0:nargs])
- del rargs[0:nargs]
-
- elif had_explicit_value:
- self.error(_("%s option does not take a value") % opt)
-
- else:
- value = None
-
- option.process(opt, value, values, self)
-
- def _process_short_opts(self, rargs, values):
- arg = rargs.pop(0)
- stop = False
- i = 1
- for ch in arg[1:]:
- opt = "-" + ch
- option = self._short_opt.get(opt)
- i = i + 1 # we have consumed a character
-
- if not option:
- raise BadOptionError(opt)
- if option.takes_value():
- # Any characters left in arg? Pretend they're the
- # next arg, and stop consuming characters of arg.
- if i < len(arg):
- rargs.insert(0, arg[i:])
- stop = True
-
- nargs = option.nargs
- if len(rargs) < nargs:
- if nargs == 1:
- self.error(_("%s option requires an argument") % opt)
- else:
- self.error(_("%s option requires %d arguments")
- % (opt, nargs))
- elif nargs == 1:
- value = rargs.pop(0)
- else:
- value = tuple(rargs[0:nargs])
- del rargs[0:nargs]
-
- else: # option doesn't take a value
- value = None
-
- option.process(opt, value, values, self)
-
- if stop:
- break
-
-
- # -- Feedback methods ----------------------------------------------
-
- def get_prog_name(self):
- if self.prog is None:
- return os.path.basename(sys.argv[0])
- else:
- return self.prog
-
- def expand_prog_name(self, s):
- return string.replace(s, "%prog", self.get_prog_name())
-
- def get_description(self):
- return self.expand_prog_name(self.description)
-
- def exit(self, status=0, msg=None):
- if msg:
- sys.stderr.write(msg)
- sys.exit(status)
-
- def error(self, msg):
- """error(msg : string)
-
- Print a usage message incorporating 'msg' to stderr and exit.
- If you override this in a subclass, it should not return -- it
- should either exit or raise an exception.
- """
- self.print_usage(sys.stderr)
- self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
-
- def get_usage(self):
- if self.usage:
- return self.formatter.format_usage(
- self.expand_prog_name(self.usage))
- else:
- return ""
-
- def print_usage(self, file=None):
- """print_usage(file : file = stdout)
-
- Print the usage message for the current program (self.usage) to
- 'file' (default stdout). Any occurence of the string "%prog" in
- self.usage is replaced with the name of the current program
- (basename of sys.argv[0]). Does nothing if self.usage is empty
- or not defined.
- """
- if self.usage:
- file.write(self.get_usage() + '\n')
-
- def get_version(self):
- if self.version:
- return self.expand_prog_name(self.version)
- else:
- return ""
-
- def print_version(self, file=None):
- """print_version(file : file = stdout)
-
- Print the version message for this program (self.version) to
- 'file' (default stdout). As with print_usage(), any occurence
- of "%prog" in self.version is replaced by the current program's
- name. Does nothing if self.version is empty or undefined.
- """
- if self.version:
- file.write(self.get_version() + '\n')
-
- def format_option_help(self, formatter=None):
- if formatter is None:
- formatter = self.formatter
- formatter.store_option_strings(self)
- result = []
- result.append(formatter.format_heading(_("Options")))
- formatter.indent()
- if self.option_list:
- result.append(OptionContainer.format_option_help(self, formatter))
- result.append("\n")
- for group in self.option_groups:
- result.append(group.format_help(formatter))
- result.append("\n")
- formatter.dedent()
- # Drop the last "\n", or the header if no options or option groups:
- return string.join(result[:-1], "")
-
- def format_epilog(self, formatter):
- return formatter.format_epilog(self.epilog)
-
- def format_help(self, formatter=None):
- if formatter is None:
- formatter = self.formatter
- result = []
- if self.usage:
- result.append(self.get_usage() + "\n")
- if self.description:
- result.append(self.format_description(formatter) + "\n")
- result.append(self.format_option_help(formatter))
- result.append(self.format_epilog(formatter))
- return string.join(result, "")
-
- # used by test suite
- def _get_encoding(self, file):
- encoding = getattr(file, "encoding", None)
- if not encoding:
- encoding = sys.getdefaultencoding()
- return encoding
-
- def print_help(self, file=None):
- """print_help(file : file = stdout)
-
- Print an extended help message, listing all options and any
- help text provided with them, to 'file' (default stdout).
- """
- if file is None:
- file = sys.stdout
- encoding = self._get_encoding(file)
- file.write(encode_wrapper(self.format_help(), encoding, "replace"))
-
-# class OptionParser
-
-
-def _match_abbrev(s, wordmap):
- """_match_abbrev(s : string, wordmap : {string : Option}) -> string
-
- Return the string key in 'wordmap' for which 's' is an unambiguous
- abbreviation. If 's' is found to be ambiguous or doesn't match any of
- 'words', raise BadOptionError.
- """
- # Is there an exact match?
- if wordmap.has_key(s):
- return s
- else:
- # Isolate all words with s as a prefix.
- possibilities = filter(lambda w, s=s: w[:len(s)] == s, wordmap.keys())
- # No exact match, so there had better be just one possibility.
- if len(possibilities) == 1:
- return possibilities[0]
- elif not possibilities:
- raise BadOptionError(s)
- else:
- # More than one possible completion: ambiguous prefix.
- possibilities.sort()
- raise AmbiguousOptionError(s, possibilities)
-
-
-# Some day, there might be many Option classes. As of Optik 1.3, the
-# preferred way to instantiate Options is indirectly, via make_option(),
-# which will become a factory function when there are many Option
-# classes.
-make_option = Option
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_platform.py b/src/engine/SCons/compat/_scons_platform.py
deleted file mode 100644
index 6ac9b61..0000000
--- a/src/engine/SCons/compat/_scons_platform.py
+++ /dev/null
@@ -1,237 +0,0 @@
-#
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 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
-# 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.
-#
-
-__doc__ = """
-platform backwards-compatibility module for older (pre-2.3) Python versions
-
-This does not not NOT (repeat, *NOT*) provide complete platform
-functionality. It only wraps the portions of platform functionality used
-by SCons.
-"""
-
-__revision__ = "src/engine/SCons/compat/_scons_platform.py 4720 2010/03/24 03:14:11 jars"
-
-### Portable uname() interface
-
-_uname_cache = None
-
-def uname():
-
- """ Fairly portable uname interface. Returns a tuple
- of strings (system,node,release,version,machine,processor)
- identifying the underlying platform.
-
- Note that unlike the os.uname function this also returns
- possible processor information as an additional tuple entry.
-
- Entries which cannot be determined are set to ''.
-
- """
- global _uname_cache
- no_os_uname = 0
-
- if _uname_cache is not None:
- return _uname_cache
-
- processor = ''
-
- # Get some infos from the builtin os.uname API...
- try:
- system,node,release,version,machine = os.uname()
- except AttributeError:
- no_os_uname = 1
-
- if no_os_uname or not filter(None, (system, node, release, version, machine)):
- # Hmm, no there is either no uname or uname has returned
- #'unknowns'... we'll have to poke around the system then.
- if no_os_uname:
- system = sys.platform
- release = ''
- version = ''
- node = _node()
- machine = ''
-
- use_syscmd_ver = 01
-
- # Try win32_ver() on win32 platforms
- if system == 'win32':
- release,version,csd,ptype = win32_ver()
- if release and version:
- use_syscmd_ver = 0
- # Try to use the PROCESSOR_* environment variables
- # available on Win XP and later; see
- # http://support.microsoft.com/kb/888731 and
- # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM
- if not machine:
- machine = os.environ.get('PROCESSOR_ARCHITECTURE', '')
- if not processor:
- processor = os.environ.get('PROCESSOR_IDENTIFIER', machine)
-
- # Try the 'ver' system command available on some
- # platforms
- if use_syscmd_ver:
- system,release,version = _syscmd_ver(system)
- # Normalize system to what win32_ver() normally returns
- # (_syscmd_ver() tends to return the vendor name as well)
- if system == 'Microsoft Windows':
- system = 'Windows'
- elif system == 'Microsoft' and release == 'Windows':
- # Under Windows Vista and Windows Server 2008,
- # Microsoft changed the output of the ver command. The
- # release is no longer printed. This causes the
- # system and release to be misidentified.
- system = 'Windows'
- if '6.0' == version[:3]:
- release = 'Vista'
- else:
- release = ''
-
- # In case we still don't know anything useful, we'll try to
- # help ourselves
- if system in ('win32','win16'):
- if not version:
- if system == 'win32':
- version = '32bit'
- else:
- version = '16bit'
- system = 'Windows'
-
- elif system[:4] == 'java':
- release,vendor,vminfo,osinfo = java_ver()
- system = 'Java'
- version = string.join(vminfo,', ')
- if not version:
- version = vendor
-
- elif os.name == 'mac':
- release,(version,stage,nonrel),machine = mac_ver()
- system = 'MacOS'
-
- # System specific extensions
- if system == 'OpenVMS':
- # OpenVMS seems to have release and version mixed up
- if not release or release == '0':
- release = version
- version = ''
- # Get processor information
- try:
- import vms_lib
- except ImportError:
- pass
- else:
- csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0)
- if (cpu_number >= 128):
- processor = 'Alpha'
- else:
- processor = 'VAX'
- if not processor:
- # Get processor information from the uname system command
- processor = _syscmd_uname('-p','')
-
- #If any unknowns still exist, replace them with ''s, which are more portable
- if system == 'unknown':
- system = ''
- if node == 'unknown':
- node = ''
- if release == 'unknown':
- release = ''
- if version == 'unknown':
- version = ''
- if machine == 'unknown':
- machine = ''
- if processor == 'unknown':
- processor = ''
-
- # normalize name
- if system == 'Microsoft' and release == 'Windows':
- system = 'Windows'
- release = 'Vista'
-
- _uname_cache = system,node,release,version,machine,processor
- return _uname_cache
-
-### Direct interfaces to some of the uname() return values
-
-def system():
-
- """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'.
-
- An empty string is returned if the value cannot be determined.
-
- """
- return uname()[0]
-
-def node():
-
- """ Returns the computer's network name (which may not be fully
- qualified)
-
- An empty string is returned if the value cannot be determined.
-
- """
- return uname()[1]
-
-def release():
-
- """ Returns the system's release, e.g. '2.2.0' or 'NT'
-
- An empty string is returned if the value cannot be determined.
-
- """
- return uname()[2]
-
-def version():
-
- """ Returns the system's release version, e.g. '#3 on degas'
-
- An empty string is returned if the value cannot be determined.
-
- """
- return uname()[3]
-
-def machine():
-
- """ Returns the machine type, e.g. 'i386'
-
- An empty string is returned if the value cannot be determined.
-
- """
- return uname()[4]
-
-def processor():
-
- """ Returns the (true) processor name, e.g. 'amdk6'
-
- An empty string is returned if the value cannot be
- determined. Note that many platforms do not provide this
- information or simply return the same value as for machine(),
- e.g. NetBSD does this.
-
- """
- return uname()[5]
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_sets.py b/src/engine/SCons/compat/_scons_sets.py
index 12dbead..0fde994 100644
--- a/src/engine/SCons/compat/_scons_sets.py
+++ b/src/engine/SCons/compat/_scons_sets.py
@@ -54,29 +54,8 @@ what's tested is actually `z in y'.
# - Raymond Hettinger added a number of speedups and other
# improvements.
-from __future__ import generators
-try:
- from itertools import ifilter, ifilterfalse
-except ImportError:
- # Code to make the module run under Py2.2
- def ifilter(predicate, iterable):
- if predicate is None:
- def predicate(x):
- return x
- for x in iterable:
- if predicate(x):
- yield x
- def ifilterfalse(predicate, iterable):
- if predicate is None:
- def predicate(x):
- return x
- for x in iterable:
- if not predicate(x):
- yield x
- try:
- True, False
- except NameError:
- True, False = (0==0, 0!=0)
+# protect this import from the fixers...
+exec('from itertools import ifilterfalse as filterfalse')
__all__ = ['BaseSet', 'Set', 'ImmutableSet']
@@ -91,7 +70,7 @@ class BaseSet(object):
"""This is an abstract class."""
# Don't call this from a concrete subclass!
if self.__class__ is BaseSet:
- raise TypeError, ("BaseSet is an abstract class. "
+ raise TypeError("BaseSet is an abstract class. "
"Use Set or ImmutableSet.")
# Standard protocols: __len__, __repr__, __str__, __iter__
@@ -110,9 +89,9 @@ class BaseSet(object):
# __str__ is the same as __repr__
__str__ = __repr__
- def _repr(self, sorted=False):
- elements = self._data.keys()
- if sorted:
+ def _repr(self, sort_them=False):
+ elements = list(self._data.keys())
+ if sort_them:
elements.sort()
return '%s(%r)' % (self.__class__.__name__, elements)
@@ -121,7 +100,8 @@ class BaseSet(object):
This is the keys iterator for the underlying dict.
"""
- return self._data.iterkeys()
+ # Wrapping name in () prevents fixer from "fixing" this
+ return (self._data.iterkeys)()
# Three-way comparison is not supported. However, because __eq__ is
# tried before __cmp__, if Set x == Set y, x.__eq__(y) returns True and
@@ -129,7 +109,7 @@ class BaseSet(object):
# case).
def __cmp__(self, other):
- raise TypeError, "can't compare sets using cmp()"
+ raise TypeError("can't compare sets using cmp()")
# Equality comparisons using the underlying dicts. Mixed-type comparisons
# are allowed here, where Set == z for non-Set z always returns False,
@@ -231,7 +211,7 @@ class BaseSet(object):
little, big = self, other
else:
little, big = other, self
- common = ifilter(big._data.has_key, little)
+ common = iter(filter(big._data.has_key, little))
return self.__class__(common)
def __xor__(self, other):
@@ -256,9 +236,9 @@ class BaseSet(object):
otherdata = other._data
except AttributeError:
otherdata = Set(other)._data
- for elt in ifilterfalse(otherdata.has_key, selfdata):
+ for elt in filterfalse(otherdata.has_key, selfdata):
data[elt] = value
- for elt in ifilterfalse(selfdata.has_key, otherdata):
+ for elt in filterfalse(selfdata.has_key, otherdata):
data[elt] = value
return result
@@ -283,7 +263,7 @@ class BaseSet(object):
except AttributeError:
otherdata = Set(other)._data
value = True
- for elt in ifilterfalse(otherdata.has_key, self):
+ for elt in filterfalse(otherdata.has_key, self):
data[elt] = value
return result
@@ -309,7 +289,7 @@ class BaseSet(object):
self._binary_sanity_check(other)
if len(self) > len(other): # Fast check for obvious cases
return False
- for elt in ifilterfalse(other._data.has_key, self):
+ for elt in filterfalse(other._data.has_key, self):
return False
return True
@@ -318,7 +298,7 @@ class BaseSet(object):
self._binary_sanity_check(other)
if len(self) < len(other): # Fast check for obvious cases
return False
- for elt in ifilterfalse(self._data.has_key, other):
+ for elt in filterfalse(self._data.has_key, other):
return False
return True
@@ -340,7 +320,7 @@ class BaseSet(object):
# Check that the other argument to a binary operation is also
# a set, raising a TypeError otherwise.
if not isinstance(other, BaseSet):
- raise TypeError, "Binary operation only permitted between sets"
+ raise TypeError("Binary operation only permitted between sets")
def _compute_hash(self):
# Calculate hash code for a set by xor'ing the hash codes of
@@ -438,7 +418,7 @@ class Set(BaseSet):
def __hash__(self):
"""A Set cannot be hashed."""
# We inherit object.__hash__, so we must deny this explicitly
- raise TypeError, "Can't hash a Set, only an ImmutableSet."
+ raise TypeError("Can't hash a Set, only an ImmutableSet.")
# In-place union, intersection, differences.
# Subtle: The xyz_update() functions deliberately return None,
@@ -501,7 +481,7 @@ class Set(BaseSet):
other = Set(other)
if self is other:
self.clear()
- for elt in ifilter(data.has_key, other):
+ for elt in filter(data.has_key, other):
del data[elt]
# Python dict-like mass mutations: update, clear
diff --git a/src/engine/SCons/compat/_scons_sets15.py b/src/engine/SCons/compat/_scons_sets15.py
deleted file mode 100644
index bafa009..0000000
--- a/src/engine/SCons/compat/_scons_sets15.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# A Set class that works all the way back to Python 1.5. From:
-#
-# Python Cookbook: Yet another Set class for Python
-# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/106469
-# Goncalo Rodriques
-#
-# This is a pure Pythonic implementation of a set class. The syntax
-# and methods implemented are, for the most part, borrowed from
-# PEP 218 by Greg Wilson.
-#
-# Note that this class violates the formal definition of a set() by adding
-# a __getitem__() method so we can iterate over a set's elements under
-# Python 1.5 and 2.1, which don't support __iter__() and iterator types.
-#
-
-import string
-
-class Set:
- """The set class. It can contain mutable objects."""
-
- def __init__(self, seq = None):
- """The constructor. It can take any object giving an iterator as an optional
- argument to populate the new set."""
- self.elems = []
- if seq:
- for elem in seq:
- if elem not in self.elems:
- hash(elem)
- self.elems.append(elem)
-
- def __str__(self):
- return "set([%s])" % string.join(map(str, self.elems), ", ")
-
-
- def copy(self):
- """Shallow copy of a set object."""
- return Set(self.elems)
-
- def __contains__(self, elem):
- return elem in self.elems
-
- def __len__(self):
- return len(self.elems)
-
- def __getitem__(self, index):
- # Added so that Python 1.5 can iterate over the elements.
- # The cookbook recipe's author didn't like this because there
- # really isn't any order in a set object, but this is necessary
- # to make the class work well enough for our purposes.
- return self.elems[index]
-
- def items(self):
- """Returns a list of the elements in the set."""
- return self.elems
-
- def add(self, elem):
- """Add one element to the set."""
- if elem not in self.elems:
- hash(elem)
- self.elems.append(elem)
-
- def remove(self, elem):
- """Remove an element from the set. Return an error if elem is not in the set."""
- try:
- self.elems.remove(elem)
- except ValueError:
- raise LookupError, "Object %s is not a member of the set." % str(elem)
-
- def discard(self, elem):
- """Remove an element from the set. Do nothing if elem is not in the set."""
- try:
- self.elems.remove(elem)
- except ValueError:
- pass
-
- def sort(self, func=cmp):
- self.elems.sort(func)
-
- #Define an iterator for a set.
- def __iter__(self):
- return iter(self.elems)
-
- #The basic binary operations with sets.
- def __or__(self, other):
- """Union of two sets."""
- ret = self.copy()
- for elem in other.elems:
- if elem not in ret:
- ret.elems.append(elem)
- return ret
-
- def __sub__(self, other):
- """Difference of two sets."""
- ret = self.copy()
- for elem in other.elems:
- ret.discard(elem)
- return ret
-
- def __and__(self, other):
- """Intersection of two sets."""
- ret = Set()
- for elem in self.elems:
- if elem in other.elems:
- ret.elems.append(elem)
- return ret
-
- def __add__(self, other):
- """Symmetric difference of two sets."""
- ret = Set()
- temp = other.copy()
- for elem in self.elems:
- if elem in temp.elems:
- temp.elems.remove(elem)
- else:
- ret.elems.append(elem)
- #Add remaining elements.
- for elem in temp.elems:
- ret.elems.append(elem)
- return ret
-
- def __mul__(self, other):
- """Cartesian product of two sets."""
- ret = Set()
- for elemself in self.elems:
- x = map(lambda other, s=elemself: (s, other), other.elems)
- ret.elems.extend(x)
- return ret
-
- #Some of the binary comparisons.
- def __lt__(self, other):
- """Returns 1 if the lhs set is contained but not equal to the rhs set."""
- if len(self.elems) < len(other.elems):
- temp = other.copy()
- for elem in self.elems:
- if elem in temp.elems:
- temp.remove(elem)
- else:
- return 0
- return len(temp.elems) == 0
- else:
- return 0
-
- def __le__(self, other):
- """Returns 1 if the lhs set is contained in the rhs set."""
- if len(self.elems) <= len(other.elems):
- ret = 1
- for elem in self.elems:
- if elem not in other.elems:
- ret = 0
- break
- return ret
- else:
- return 0
-
- def __eq__(self, other):
- """Returns 1 if the sets are equal."""
- if len(self.elems) != len(other.elems):
- return 0
- else:
- return len(self - other) == 0
-
- def __cmp__(self, other):
- """Returns 1 if the sets are equal."""
- if self.__lt__(other):
- return -1
- elif other.__lt__(self):
- return 1
- else:
- return 0
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_shlex.py b/src/engine/SCons/compat/_scons_shlex.py
deleted file mode 100644
index 9e30a01..0000000
--- a/src/engine/SCons/compat/_scons_shlex.py
+++ /dev/null
@@ -1,325 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-"""A lexical analyzer class for simple shell-like syntaxes."""
-
-# Module and documentation by Eric S. Raymond, 21 Dec 1998
-# Input stacking and error message cleanup added by ESR, March 2000
-# push_source() and pop_source() made explicit by ESR, January 2001.
-# Posix compliance, split(), string arguments, and
-# iterator interface by Gustavo Niemeyer, April 2003.
-
-import os.path
-import sys
-#from collections import deque
-
-class deque:
- def __init__(self):
- self.data = []
- def __len__(self):
- return len(self.data)
- def appendleft(self, item):
- self.data.insert(0, item)
- def popleft(self):
- return self.data.pop(0)
-
-try:
- basestring
-except NameError:
- import types
- def is_basestring(s):
- return type(s) is types.StringType
-else:
- def is_basestring(s):
- return isinstance(s, basestring)
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-__all__ = ["shlex", "split"]
-
-class shlex:
- "A lexical analyzer class for simple shell-like syntaxes."
- def __init__(self, instream=None, infile=None, posix=False):
- if is_basestring(instream):
- instream = StringIO(instream)
- if instream is not None:
- self.instream = instream
- self.infile = infile
- else:
- self.instream = sys.stdin
- self.infile = None
- self.posix = posix
- if posix:
- self.eof = None
- else:
- self.eof = ''
- self.commenters = '#'
- self.wordchars = ('abcdfeghijklmnopqrstuvwxyz'
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_')
- if self.posix:
- self.wordchars = self.wordchars + ('ßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
- 'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ')
- self.whitespace = ' \t\r\n'
- self.whitespace_split = False
- self.quotes = '\'"'
- self.escape = '\\'
- self.escapedquotes = '"'
- self.state = ' '
- self.pushback = deque()
- self.lineno = 1
- self.debug = 0
- self.token = ''
- self.filestack = deque()
- self.source = None
- if self.debug:
- print 'shlex: reading from %s, line %d' \
- % (self.instream, self.lineno)
-
- def push_token(self, tok):
- "Push a token onto the stack popped by the get_token method"
- if self.debug >= 1:
- print "shlex: pushing token " + repr(tok)
- self.pushback.appendleft(tok)
-
- def push_source(self, newstream, newfile=None):
- "Push an input source onto the lexer's input source stack."
- if is_basestring(newstream):
- newstream = StringIO(newstream)
- self.filestack.appendleft((self.infile, self.instream, self.lineno))
- self.infile = newfile
- self.instream = newstream
- self.lineno = 1
- if self.debug:
- if newfile is not None:
- print 'shlex: pushing to file %s' % (self.infile,)
- else:
- print 'shlex: pushing to stream %s' % (self.instream,)
-
- def pop_source(self):
- "Pop the input source stack."
- self.instream.close()
- (self.infile, self.instream, self.lineno) = self.filestack.popleft()
- if self.debug:
- print 'shlex: popping to %s, line %d' \
- % (self.instream, self.lineno)
- self.state = ' '
-
- def get_token(self):
- "Get a token from the input stream (or from stack if it's nonempty)"
- if self.pushback:
- tok = self.pushback.popleft()
- if self.debug >= 1:
- print "shlex: popping token " + repr(tok)
- return tok
- # No pushback. Get a token.
- raw = self.read_token()
- # Handle inclusions
- if self.source is not None:
- while raw == self.source:
- spec = self.sourcehook(self.read_token())
- if spec:
- (newfile, newstream) = spec
- self.push_source(newstream, newfile)
- raw = self.get_token()
- # Maybe we got EOF instead?
- while raw == self.eof:
- if not self.filestack:
- return self.eof
- else:
- self.pop_source()
- raw = self.get_token()
- # Neither inclusion nor EOF
- if self.debug >= 1:
- if raw != self.eof:
- print "shlex: token=" + repr(raw)
- else:
- print "shlex: token=EOF"
- return raw
-
- def read_token(self):
- quoted = False
- escapedstate = ' '
- while True:
- nextchar = self.instream.read(1)
- if nextchar == '\n':
- self.lineno = self.lineno + 1
- if self.debug >= 3:
- print "shlex: in state", repr(self.state), \
- "I see character:", repr(nextchar)
- if self.state is None:
- self.token = '' # past end of file
- break
- elif self.state == ' ':
- if not nextchar:
- self.state = None # end of file
- break
- elif nextchar in self.whitespace:
- if self.debug >= 2:
- print "shlex: I see whitespace in whitespace state"
- if self.token or (self.posix and quoted):
- break # emit current token
- else:
- continue
- elif nextchar in self.commenters:
- self.instream.readline()
- self.lineno = self.lineno + 1
- elif self.posix and nextchar in self.escape:
- escapedstate = 'a'
- self.state = nextchar
- elif nextchar in self.wordchars:
- self.token = nextchar
- self.state = 'a'
- elif nextchar in self.quotes:
- if not self.posix:
- self.token = nextchar
- self.state = nextchar
- elif self.whitespace_split:
- self.token = nextchar
- self.state = 'a'
- else:
- self.token = nextchar
- if self.token or (self.posix and quoted):
- break # emit current token
- else:
- continue
- elif self.state in self.quotes:
- quoted = True
- if not nextchar: # end of file
- if self.debug >= 2:
- print "shlex: I see EOF in quotes state"
- # XXX what error should be raised here?
- raise ValueError, "No closing quotation"
- if nextchar == self.state:
- if not self.posix:
- self.token = self.token + nextchar
- self.state = ' '
- break
- else:
- self.state = 'a'
- elif self.posix and nextchar in self.escape and \
- self.state in self.escapedquotes:
- escapedstate = self.state
- self.state = nextchar
- else:
- self.token = self.token + nextchar
- elif self.state in self.escape:
- if not nextchar: # end of file
- if self.debug >= 2:
- print "shlex: I see EOF in escape state"
- # XXX what error should be raised here?
- raise ValueError, "No escaped character"
- # In posix shells, only the quote itself or the escape
- # character may be escaped within quotes.
- if escapedstate in self.quotes and \
- nextchar != self.state and nextchar != escapedstate:
- self.token = self.token + self.state
- self.token = self.token + nextchar
- self.state = escapedstate
- elif self.state == 'a':
- if not nextchar:
- self.state = None # end of file
- break
- elif nextchar in self.whitespace:
- if self.debug >= 2:
- print "shlex: I see whitespace in word state"
- self.state = ' '
- if self.token or (self.posix and quoted):
- break # emit current token
- else:
- continue
- elif nextchar in self.commenters:
- self.instream.readline()
- self.lineno = self.lineno + 1
- if self.posix:
- self.state = ' '
- if self.token or (self.posix and quoted):
- break # emit current token
- else:
- continue
- elif self.posix and nextchar in self.quotes:
- self.state = nextchar
- elif self.posix and nextchar in self.escape:
- escapedstate = 'a'
- self.state = nextchar
- elif nextchar in self.wordchars or nextchar in self.quotes \
- or self.whitespace_split:
- self.token = self.token + nextchar
- else:
- self.pushback.appendleft(nextchar)
- if self.debug >= 2:
- print "shlex: I see punctuation in word state"
- self.state = ' '
- if self.token:
- break # emit current token
- else:
- continue
- result = self.token
- self.token = ''
- if self.posix and not quoted and result == '':
- result = None
- if self.debug > 1:
- if result:
- print "shlex: raw token=" + repr(result)
- else:
- print "shlex: raw token=EOF"
- return result
-
- def sourcehook(self, newfile):
- "Hook called on a filename to be sourced."
- if newfile[0] == '"':
- newfile = newfile[1:-1]
- # This implements cpp-like semantics for relative-path inclusion.
- if is_basestring(self.infile) and not os.path.isabs(newfile):
- newfile = os.path.join(os.path.dirname(self.infile), newfile)
- return (newfile, open(newfile, "r"))
-
- def error_leader(self, infile=None, lineno=None):
- "Emit a C-compiler-like, Emacs-friendly error-message leader."
- if infile is None:
- infile = self.infile
- if lineno is None:
- lineno = self.lineno
- return "\"%s\", line %d: " % (infile, lineno)
-
- def __iter__(self):
- return self
-
- def next(self):
- token = self.get_token()
- if token == self.eof:
- raise StopIteration
- return token
-
-def split(s, comments=False):
- lex = shlex(s, posix=True)
- lex.whitespace_split = True
- if not comments:
- lex.commenters = ''
- #return list(lex)
- result = []
- while True:
- token = lex.get_token()
- if token == lex.eof:
- break
- result.append(token)
- return result
-
-if __name__ == '__main__':
- if len(sys.argv) == 1:
- lexer = shlex()
- else:
- file = sys.argv[1]
- lexer = shlex(open(file), file)
- while 1:
- tt = lexer.get_token()
- if tt:
- print "Token: " + repr(tt)
- else:
- break
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/compat/_scons_subprocess.py b/src/engine/SCons/compat/_scons_subprocess.py
index ccd403a..eebe53d 100644
--- a/src/engine/SCons/compat/_scons_subprocess.py
+++ b/src/engine/SCons/compat/_scons_subprocess.py
@@ -356,7 +356,6 @@ import sys
mswindows = (sys.platform == "win32")
import os
-import string
import types
import traceback
@@ -384,13 +383,13 @@ if mswindows:
try:
# Try to get _subprocess
from _subprocess import *
- class STARTUPINFO:
+ class STARTUPINFO(object):
dwFlags = 0
hStdInput = None
hStdOutput = None
hStdError = None
wShowWindow = 0
- class pywintypes:
+ class pywintypes(object):
error = IOError
except ImportError:
# If not there, then drop back to requiring pywin32
@@ -434,18 +433,11 @@ except KeyboardInterrupt:
except:
MAXFD = 256
-# True/False does not exist on 2.2.0
-try:
- False
-except NameError:
- False = 0
- True = 1
-
try:
isinstance(1, int)
except TypeError:
def is_int(obj):
- return type(obj) == type(1)
+ return isinstance(obj, type(1))
def is_int_or_long(obj):
return type(obj) in (type(1), type(1L))
else:
@@ -458,20 +450,17 @@ try:
types.StringTypes
except AttributeError:
try:
- types.StringTypes = (types.StringType, types.UnicodeType)
- except AttributeError:
- types.StringTypes = (types.StringType,)
- def is_string(obj):
- return type(obj) in types.StringTypes
-else:
- def is_string(obj):
- return isinstance(obj, types.StringTypes)
+ types.StringTypes = (str, unicode)
+ except NameError:
+ types.StringTypes = (str,)
+def is_string(obj):
+ return isinstance(obj, types.StringTypes)
_active = []
def _cleanup():
for inst in _active[:]:
- if inst.poll(_deadstate=sys.maxint) >= 0:
+ if inst.poll(_deadstate=sys.maxsize) >= 0:
try:
_active.remove(inst)
except ValueError:
@@ -504,7 +493,7 @@ def check_call(*popenargs, **kwargs):
check_call(["ls", "-l"])
"""
- retcode = apply(call, popenargs, kwargs)
+ retcode = call(*popenargs, **kwargs)
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
@@ -578,14 +567,7 @@ def list2cmdline(seq):
result.extend(bs_buf)
result.append('"')
- return string.join(result, '')
-
-
-try:
- object
-except NameError:
- class object:
- pass
+ return ''.join(result)
class Popen(object):
def __init__(self, args, bufsize=0, executable=None,
@@ -674,7 +656,7 @@ class Popen(object):
# We didn't get to successfully create a child process.
return
# In case the child hasn't been waited on, check if it's done.
- self.poll(_deadstate=sys.maxint)
+ self.poll(_deadstate=sys.maxsize)
if self.returncode is None and _active is not None:
# Child is still running, keep us alive until we can wait on it.
_active.append(self)
@@ -853,7 +835,7 @@ class Popen(object):
# a subclass of OSError. FIXME: We should really
# translate errno using _sys_errlist (or simliar), but
# how can this be done from Python?
- raise apply(WindowsError, e.args)
+ raise WindowsError(*e.args)
# Retain the process handle, but close the thread handle
self._child_created = True
@@ -1003,7 +985,7 @@ class Popen(object):
def _close_fds(self, but):
- for i in xrange(3, MAXFD):
+ for i in range(3, MAXFD):
if i == but:
continue
try:
@@ -1100,7 +1082,7 @@ class Popen(object):
exc_lines = traceback.format_exception(exc_type,
exc_value,
tb)
- exc_value.child_traceback = string.join(exc_lines, '')
+ exc_value.child_traceback = ''.join(exc_lines)
os.write(errpipe_write, pickle.dumps(exc_value))
# This exitcode won't be reported to applications, so it
@@ -1187,7 +1169,8 @@ class Popen(object):
# When select has indicated that the file is writable,
# we can write up to PIPE_BUF bytes without risk
# blocking. POSIX defines PIPE_BUF >= 512
- bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
+ m = memoryview(input)[input_offset:input_offset+512]
+ bytes_written = os.write(self.stdin.fileno(), m)
input_offset = input_offset + bytes_written
if input_offset >= len(input):
self.stdin.close()
@@ -1209,9 +1192,9 @@ class Popen(object):
# All data exchanged. Translate lists into strings.
if stdout is not None:
- stdout = string.join(stdout, '')
+ stdout = ''.join(stdout)
if stderr is not None:
- stderr = string.join(stderr, '')
+ stderr = ''.join(stderr)
# Translate newlines, if requested. We cannot let the file
# object do the translation: It is based on stdio, which is
diff --git a/src/engine/SCons/compat/_scons_textwrap.py b/src/engine/SCons/compat/_scons_textwrap.py
deleted file mode 100644
index 81781af..0000000
--- a/src/engine/SCons/compat/_scons_textwrap.py
+++ /dev/null
@@ -1,382 +0,0 @@
-"""Text wrapping and filling.
-"""
-
-# Copyright (C) 1999-2001 Gregory P. Ward.
-# Copyright (C) 2002, 2003 Python Software Foundation.
-# Written by Greg Ward <gward@python.net>
-
-__revision__ = "$Id: textwrap.py,v 1.32.8.2 2004/05/13 01:48:15 gward Exp $"
-
-import string, re
-
-try:
- unicode
-except NameError:
- class unicode:
- pass
-
-# Do the right thing with boolean values for all known Python versions
-# (so this module can be copied to projects that don't depend on Python
-# 2.3, e.g. Optik and Docutils).
-try:
- True, False
-except NameError:
- (True, False) = (1, 0)
-
-__all__ = ['TextWrapper', 'wrap', 'fill']
-
-# Hardcode the recognized whitespace characters to the US-ASCII
-# whitespace characters. The main reason for doing this is that in
-# ISO-8859-1, 0xa0 is non-breaking whitespace, so in certain locales
-# that character winds up in string.whitespace. Respecting
-# string.whitespace in those cases would 1) make textwrap treat 0xa0 the
-# same as any other whitespace char, which is clearly wrong (it's a
-# *non-breaking* space), 2) possibly cause problems with Unicode,
-# since 0xa0 is not in range(128).
-_whitespace = '\t\n\x0b\x0c\r '
-
-class TextWrapper:
- """
- Object for wrapping/filling text. The public interface consists of
- the wrap() and fill() methods; the other methods are just there for
- subclasses to override in order to tweak the default behaviour.
- If you want to completely replace the main wrapping algorithm,
- you'll probably have to override _wrap_chunks().
-
- Several instance attributes control various aspects of wrapping:
- width (default: 70)
- the maximum width of wrapped lines (unless break_long_words
- is false)
- initial_indent (default: "")
- string that will be prepended to the first line of wrapped
- output. Counts towards the line's width.
- subsequent_indent (default: "")
- string that will be prepended to all lines save the first
- of wrapped output; also counts towards each line's width.
- expand_tabs (default: true)
- Expand tabs in input text to spaces before further processing.
- Each tab will become 1 .. 8 spaces, depending on its position in
- its line. If false, each tab is treated as a single character.
- replace_whitespace (default: true)
- Replace all whitespace characters in the input text by spaces
- after tab expansion. Note that if expand_tabs is false and
- replace_whitespace is true, every tab will be converted to a
- single space!
- fix_sentence_endings (default: false)
- Ensure that sentence-ending punctuation is always followed
- by two spaces. Off by default because the algorithm is
- (unavoidably) imperfect.
- break_long_words (default: true)
- Break words longer than 'width'. If false, those words will not
- be broken, and some lines might be longer than 'width'.
- """
-
- whitespace_trans = string.maketrans(_whitespace, ' ' * len(_whitespace))
-
- unicode_whitespace_trans = {}
- try:
- uspace = eval("ord(u' ')")
- except SyntaxError:
- # Python1.5 doesn't understand u'' syntax, in which case we
- # won't actually use the unicode translation below, so it
- # doesn't matter what value we put in the table.
- uspace = ord(' ')
- for x in map(ord, _whitespace):
- unicode_whitespace_trans[x] = uspace
-
- # This funky little regex is just the trick for splitting
- # text up into word-wrappable chunks. E.g.
- # "Hello there -- you goof-ball, use the -b option!"
- # splits into
- # Hello/ /there/ /--/ /you/ /goof-/ball,/ /use/ /the/ /-b/ /option!
- # (after stripping out empty strings).
- try:
- wordsep_re = re.compile(r'(\s+|' # any whitespace
- r'[^\s\w]*\w{2,}-(?=\w{2,})|' # hyphenated words
- r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))') # em-dash
- except re.error:
- # Pre-2.0 Python versions don't have the (?<= negative look-behind
- # assertion. It mostly doesn't matter for the simple input
- # SCons is going to give it, so just leave it out.
- wordsep_re = re.compile(r'(\s+|' # any whitespace
- r'-*\w{2,}-(?=\w{2,}))') # hyphenated words
-
- # XXX will there be a locale-or-charset-aware version of
- # string.lowercase in 2.3?
- sentence_end_re = re.compile(r'[%s]' # lowercase letter
- r'[\.\!\?]' # sentence-ending punct.
- r'[\"\']?' # optional end-of-quote
- % string.lowercase)
-
-
- def __init__(self,
- width=70,
- initial_indent="",
- subsequent_indent="",
- expand_tabs=True,
- replace_whitespace=True,
- fix_sentence_endings=False,
- break_long_words=True):
- self.width = width
- self.initial_indent = initial_indent
- self.subsequent_indent = subsequent_indent
- self.expand_tabs = expand_tabs
- self.replace_whitespace = replace_whitespace
- self.fix_sentence_endings = fix_sentence_endings
- self.break_long_words = break_long_words
-
-
- # -- Private methods -----------------------------------------------
- # (possibly useful for subclasses to override)
-
- def _munge_whitespace(self, text):
- """_munge_whitespace(text : string) -> string
-
- Munge whitespace in text: expand tabs and convert all other
- whitespace characters to spaces. Eg. " foo\tbar\n\nbaz"
- becomes " foo bar baz".
- """
- if self.expand_tabs:
- text = string.expandtabs(text)
- if self.replace_whitespace:
- if type(text) == type(''):
- text = string.translate(text, self.whitespace_trans)
- elif isinstance(text, unicode):
- text = string.translate(text, self.unicode_whitespace_trans)
- return text
-
-
- def _split(self, text):
- """_split(text : string) -> [string]
-
- Split the text to wrap into indivisible chunks. Chunks are
- not quite the same as words; see wrap_chunks() for full
- details. As an example, the text
- Look, goof-ball -- use the -b option!
- breaks into the following chunks:
- 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
- 'use', ' ', 'the', ' ', '-b', ' ', 'option!'
- """
- chunks = self.wordsep_re.split(text)
- chunks = filter(None, chunks)
- return chunks
-
- def _fix_sentence_endings(self, chunks):
- """_fix_sentence_endings(chunks : [string])
-
- Correct for sentence endings buried in 'chunks'. Eg. when the
- original text contains "... foo.\nBar ...", munge_whitespace()
- and split() will convert that to [..., "foo.", " ", "Bar", ...]
- which has one too few spaces; this method simply changes the one
- space to two.
- """
- i = 0
- pat = self.sentence_end_re
- while i < len(chunks)-1:
- if chunks[i+1] == " " and pat.search(chunks[i]):
- chunks[i+1] = " "
- i = i + 2
- else:
- i = i + 1
-
- def _handle_long_word(self, chunks, cur_line, cur_len, width):
- """_handle_long_word(chunks : [string],
- cur_line : [string],
- cur_len : int, width : int)
-
- Handle a chunk of text (most likely a word, not whitespace) that
- is too long to fit in any line.
- """
- space_left = max(width - cur_len, 1)
-
- # If we're allowed to break long words, then do so: put as much
- # of the next chunk onto the current line as will fit.
- if self.break_long_words:
- cur_line.append(chunks[0][0:space_left])
- chunks[0] = chunks[0][space_left:]
-
- # Otherwise, we have to preserve the long word intact. Only add
- # it to the current line if there's nothing already there --
- # that minimizes how much we violate the width constraint.
- elif not cur_line:
- cur_line.append(chunks.pop(0))
-
- # If we're not allowed to break long words, and there's already
- # text on the current line, do nothing. Next time through the
- # main loop of _wrap_chunks(), we'll wind up here again, but
- # cur_len will be zero, so the next line will be entirely
- # devoted to the long word that we can't handle right now.
-
- def _wrap_chunks(self, chunks):
- """_wrap_chunks(chunks : [string]) -> [string]
-
- Wrap a sequence of text chunks and return a list of lines of
- length 'self.width' or less. (If 'break_long_words' is false,
- some lines may be longer than this.) Chunks correspond roughly
- to words and the whitespace between them: each chunk is
- indivisible (modulo 'break_long_words'), but a line break can
- come between any two chunks. Chunks should not have internal
- whitespace; ie. a chunk is either all whitespace or a "word".
- Whitespace chunks will be removed from the beginning and end of
- lines, but apart from that whitespace is preserved.
- """
- lines = []
- if self.width <= 0:
- raise ValueError("invalid width %r (must be > 0)" % self.width)
-
- while chunks:
-
- # Start the list of chunks that will make up the current line.
- # cur_len is just the length of all the chunks in cur_line.
- cur_line = []
- cur_len = 0
-
- # Figure out which static string will prefix this line.
- if lines:
- indent = self.subsequent_indent
- else:
- indent = self.initial_indent
-
- # Maximum width for this line.
- width = self.width - len(indent)
-
- # First chunk on line is whitespace -- drop it, unless this
- # is the very beginning of the text (ie. no lines started yet).
- if string.strip(chunks[0]) == '' and lines:
- del chunks[0]
-
- while chunks:
- l = len(chunks[0])
-
- # Can at least squeeze this chunk onto the current line.
- if cur_len + l <= width:
- cur_line.append(chunks.pop(0))
- cur_len = cur_len + l
-
- # Nope, this line is full.
- else:
- break
-
- # The current line is full, and the next chunk is too big to
- # fit on *any* line (not just this one).
- if chunks and len(chunks[0]) > width:
- self._handle_long_word(chunks, cur_line, cur_len, width)
-
- # If the last chunk on this line is all whitespace, drop it.
- if cur_line and string.strip(cur_line[-1]) == '':
- del cur_line[-1]
-
- # Convert current line back to a string and store it in list
- # of all lines (return value).
- if cur_line:
- lines.append(indent + string.join(cur_line, ''))
-
- return lines
-
-
- # -- Public interface ----------------------------------------------
-
- def wrap(self, text):
- """wrap(text : string) -> [string]
-
- Reformat the single paragraph in 'text' so it fits in lines of
- no more than 'self.width' columns, and return a list of wrapped
- lines. Tabs in 'text' are expanded with string.expandtabs(),
- and all other whitespace characters (including newline) are
- converted to space.
- """
- text = self._munge_whitespace(text)
- indent = self.initial_indent
- chunks = self._split(text)
- if self.fix_sentence_endings:
- self._fix_sentence_endings(chunks)
- return self._wrap_chunks(chunks)
-
- def fill(self, text):
- """fill(text : string) -> string
-
- Reformat the single paragraph in 'text' to fit in lines of no
- more than 'self.width' columns, and return a new string
- containing the entire wrapped paragraph.
- """
- return string.join(self.wrap(text), "\n")
-
-
-# -- Convenience interface ---------------------------------------------
-
-def wrap(text, width=70, **kwargs):
- """Wrap a single paragraph of text, returning a list of wrapped lines.
-
- Reformat the single paragraph in 'text' so it fits in lines of no
- more than 'width' columns, and return a list of wrapped lines. By
- default, tabs in 'text' are expanded with string.expandtabs(), and
- all other whitespace characters (including newline) are converted to
- space. See TextWrapper class for available keyword args to customize
- wrapping behaviour.
- """
- kw = kwargs.copy()
- kw['width'] = width
- w = apply(TextWrapper, (), kw)
- return w.wrap(text)
-
-def fill(text, width=70, **kwargs):
- """Fill a single paragraph of text, returning a new string.
-
- Reformat the single paragraph in 'text' to fit in lines of no more
- than 'width' columns, and return a new string containing the entire
- wrapped paragraph. As with wrap(), tabs are expanded and other
- whitespace characters converted to space. See TextWrapper class for
- available keyword args to customize wrapping behaviour.
- """
- kw = kwargs.copy()
- kw['width'] = width
- w = apply(TextWrapper, (), kw)
- return w.fill(text)
-
-
-# -- Loosely related functionality -------------------------------------
-
-def dedent(text):
- """dedent(text : string) -> string
-
- Remove any whitespace than can be uniformly removed from the left
- of every line in `text`.
-
- This can be used e.g. to make triple-quoted strings line up with
- the left edge of screen/whatever, while still presenting it in the
- source code in indented form.
-
- For example:
-
- def test():
- # end first line with \ to avoid the empty line!
- s = '''\
- hello
- world
- '''
- print repr(s) # prints ' hello\n world\n '
- print repr(dedent(s)) # prints 'hello\n world\n'
- """
- lines = text.expandtabs().split('\n')
- margin = None
- for line in lines:
- content = line.lstrip()
- if not content:
- continue
- indent = len(line) - len(content)
- if margin is None:
- margin = indent
- else:
- margin = min(margin, indent)
-
- if margin is not None and margin > 0:
- for i in range(len(lines)):
- lines[i] = lines[i][margin:]
-
- return string.join(lines, '\n')
-
-# Local Variables:
-# tab-width:4
-# indent-tabs-mode:nil
-# End:
-# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/cpp.py b/src/engine/SCons/cpp.py
index 485ba6e..ef09e11 100644
--- a/src/engine/SCons/cpp.py
+++ b/src/engine/SCons/cpp.py
@@ -21,20 +21,16 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/cpp.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/cpp.py 5023 2010/06/14 22:05:46 scons"
__doc__ = """
SCons C Pre-Processor module
"""
-
-# TODO(1.5): remove this import
-# This module doesn't use anything from SCons by name, but we import SCons
-# here to pull in zip() from the SCons.compat layer for early Pythons.
-import SCons
+#TODO 2.3 and before has no sorted()
+import SCons.compat
import os
import re
-import string
#
# First "subsystem" of regular expressions that we set up:
@@ -91,7 +87,7 @@ del op_list
override = {
'if' : 'if(?!def)',
}
-l = map(lambda x, o=override: o.get(x, x), Table.keys())
+l = [override.get(x, x) for x in Table.keys()]
# Turn the list of expressions into one big honkin' regular expression
@@ -99,7 +95,7 @@ l = map(lambda x, o=override: o.get(x, x), Table.keys())
# a list of tuples, one for each preprocessor line. The preprocessor
# directive will be the first element in each tuple, and the rest of
# the line will be the second element.
-e = '^\s*#\s*(' + string.join(l, '|') + ')(.*)$'
+e = '^\s*#\s*(' + '|'.join(l) + ')(.*)$'
# And last but not least, compile the expression.
CPP_Expression = re.compile(e, re.M)
@@ -126,7 +122,7 @@ CPP_to_Python_Ops_Dict = {
'\r' : '',
}
-CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[m.group(0)]
+CPP_to_Python_Ops_Sub = lambda m: CPP_to_Python_Ops_Dict[m.group(0)]
# We have to sort the keys by length so that longer expressions
# come *before* shorter expressions--in particular, "!=" must
@@ -134,12 +130,11 @@ CPP_to_Python_Ops_Sub = lambda m, d=CPP_to_Python_Ops_Dict: d[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 = CPP_to_Python_Ops_Dict.keys()
-l.sort(lambda a, b: cmp(len(b), len(a)))
+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.
-expr = string.join(map(re.escape, l), '|')
+expr = '|'.join(map(re.escape, l))
# ...and compile the expression.
CPP_to_Python_Ops_Expression = re.compile(expr)
@@ -147,12 +142,12 @@ CPP_to_Python_Ops_Expression = re.compile(expr)
# A separate list of expressions to be evaluated and substituted
# sequentially, not all at once.
CPP_to_Python_Eval_List = [
- ['defined\s+(\w+)', '__dict__.has_key("\\1")'],
- ['defined\s*\((\w+)\)', '__dict__.has_key("\\1")'],
+ ['defined\s+(\w+)', '"\\1" in __dict__'],
+ ['defined\s*\((\w+)\)', '"\\1" in __dict__'],
['/\*.*\*/', ''],
['/\*.*', ''],
['//.*', ''],
- ['(0x[0-9A-Fa-f]*)[UL]+', '\\1L'],
+ ['(0x[0-9A-Fa-f]*)[UL]+', '\\1'],
]
# Replace the string representations of the regular expressions in the
@@ -179,7 +174,7 @@ del override
-class FunctionEvaluator:
+class FunctionEvaluator(object):
"""
Handles delayed evaluation of a #define function call.
"""
@@ -192,10 +187,8 @@ class FunctionEvaluator:
self.name = name
self.args = function_arg_separator.split(args)
try:
- expansion = string.split(expansion, '##')
- except (AttributeError, TypeError):
- # Python 1.5 throws TypeError if "expansion" isn't a string,
- # later versions throw AttributeError.
+ expansion = expansion.split('##')
+ except AttributeError:
pass
self.expansion = expansion
def __call__(self, *values):
@@ -204,7 +197,7 @@ class FunctionEvaluator:
with the specified values.
"""
if len(self.args) != len(values):
- raise ValueError, "Incorrect number of arguments to `%s'" % self.name
+ raise ValueError("Incorrect number of arguments to `%s'" % self.name)
# Create a dictionary that maps the macro arguments to the
# corresponding values in this "call." We'll use this when we
# eval() the expansion so that arguments will get expanded to
@@ -218,7 +211,7 @@ class FunctionEvaluator:
if not s in self.args:
s = repr(s)
parts.append(s)
- statement = string.join(parts, ' + ')
+ statement = ' + '.join(parts)
return eval(statement, globals(), locals)
@@ -238,7 +231,7 @@ function_arg_separator = re.compile(',\s*')
-class PreProcessor:
+class PreProcessor(object):
"""
The main workhorse class for handling C pre-processing.
"""
@@ -292,9 +285,7 @@ class PreProcessor:
global CPP_Expression, Table
contents = line_continuations.sub('', contents)
cpp_tuples = CPP_Expression.findall(contents)
- return map(lambda m, t=Table:
- (m[0],) + t[m[0]].match(m[1]).groups(),
- cpp_tuples)
+ return [(m[0],) + Table[m[0]].match(m[1]).groups() for m in cpp_tuples]
def __call__(self, file):
"""
@@ -363,7 +354,7 @@ class PreProcessor:
eval()ing it in the C preprocessor namespace we use to
track #define values.
"""
- t = CPP_to_Python(string.join(t[1:]))
+ t = CPP_to_Python(' '.join(t[1:]))
try: return eval(t, self.cpp_namespace)
except (NameError, TypeError): return 0
@@ -446,13 +437,13 @@ class PreProcessor:
"""
Default handling of a #ifdef line.
"""
- self._do_if_else_condition(self.cpp_namespace.has_key(t[1]))
+ self._do_if_else_condition(t[1] in self.cpp_namespace)
def do_ifndef(self, t):
"""
Default handling of a #ifndef line.
"""
- self._do_if_else_condition(not self.cpp_namespace.has_key(t[1]))
+ self._do_if_else_condition(t[1] not in self.cpp_namespace)
def do_if(self, t):
"""
@@ -563,7 +554,7 @@ class PreProcessor:
s = self.cpp_namespace[m.group(1)]
if callable(s):
args = function_arg_separator.split(m.group(2))
- s = apply(s, args)
+ s = s(*args)
if not s:
return None
return (t[0], s[0], s[1:-1])
@@ -584,7 +575,7 @@ class DumbPreProcessor(PreProcessor):
to tailor its behavior.
"""
def __init__(self, *args, **kw):
- apply(PreProcessor.__init__, (self,)+args, kw)
+ PreProcessor.__init__(self, *args, **kw)
d = self.default_table
for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']:
d[func] = d[func] = self.do_nothing
diff --git a/src/engine/SCons/cppTests.py b/src/engine/SCons/cppTests.py
index 4469987..63ddf06 100644
--- a/src/engine/SCons/cppTests.py
+++ b/src/engine/SCons/cppTests.py
@@ -21,9 +21,8 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/cppTests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/cppTests.py 5023 2010/06/14 22:05:46 scons"
-import string
import sys
import unittest
@@ -635,7 +634,7 @@ class fileTestCase(unittest.TestCase):
def strip_initial_spaces(self, s):
#lines = s.split('\n')
- lines = string.split(s, '\n')
+ lines = s.split('\n')
spaces = re.match(' *', lines[0]).group(0)
def strip_spaces(l, spaces=spaces):
#if l.startswith(spaces):
@@ -643,7 +642,7 @@ class fileTestCase(unittest.TestCase):
l = l[len(spaces):]
return l
#return '\n'.join([ strip_spaces(l) for l in lines ])
- return string.join(map(strip_spaces, lines), '\n')
+ return '\n'.join(map(strip_spaces, lines))
def write(self, file, contents):
open(file, 'w').write(self.strip_initial_spaces(contents))
@@ -675,7 +674,7 @@ class fileTestCase(unittest.TestCase):
""")
class MyPreProcessor(cpp.DumbPreProcessor):
def __init__(self, *args, **kw):
- apply(cpp.DumbPreProcessor.__init__, (self,) + args, kw)
+ cpp.DumbPreProcessor.__init__(self, *args, **kw)
self.files = []
def __call__(self, file):
self.files.append(file)
@@ -704,7 +703,7 @@ if __name__ == '__main__':
except NameError:
pass
names.sort()
- suite.addTests(map(tclass, names))
+ suite.addTests(list(map(tclass, names)))
if not unittest.TextTestRunner().run(suite).wasSuccessful():
sys.exit(1)
diff --git a/src/engine/SCons/dblite.py b/src/engine/SCons/dblite.py
index bcb2aa0..ea24e6a 100644
--- a/src/engine/SCons/dblite.py
+++ b/src/engine/SCons/dblite.py
@@ -1,12 +1,14 @@
# dblite.py module contributed by Ralf W. Grosse-Kunstleve.
# Extended for Unicode by Steven Knight.
-import cPickle
-import time
-import shutil
+import SCons.compat
+
+import builtins
import os
-import types
-import __builtin__
+# compat layer imports "cPickle" for us if it's available.
+import pickle
+import shutil
+import time
keep_all_files = 00000
ignore_corrupt_dbfiles = 0
@@ -14,13 +16,13 @@ ignore_corrupt_dbfiles = 0
def corruption_warning(filename):
print "Warning: Discarding corrupt database:", filename
-if hasattr(types, 'UnicodeType'):
+try: unicode
+except NameError:
def is_string(s):
- t = type(s)
- return t is types.StringType or t is types.UnicodeType
+ return isinstance(s, str)
else:
def is_string(s):
- return type(s) is types.StringType
+ return type(s) in (str, unicode)
try:
unicode('a')
@@ -30,7 +32,7 @@ except NameError:
dblite_suffix = '.dblite'
tmp_suffix = '.tmp'
-class dblite:
+class dblite(object):
# Squirrel away references to the functions in various modules
# that we'll use when our __del__() method calls our sync() method
@@ -42,8 +44,8 @@ class dblite:
# See the discussion at:
# http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html
- _open = __builtin__.open
- _cPickle_dump = cPickle.dump
+ _open = builtins.open
+ _pickle_dump = staticmethod(pickle.dump)
_os_chmod = os.chmod
try:
_os_chown = os.chown
@@ -96,8 +98,8 @@ class dblite:
p = f.read()
if (len(p) > 0):
try:
- self._dict = cPickle.loads(p)
- except (cPickle.UnpicklingError, EOFError):
+ self._dict = pickle.loads(p)
+ except (pickle.UnpicklingError, EOFError):
if (ignore_corrupt_dbfiles == 0): raise
if (ignore_corrupt_dbfiles == 1):
corruption_warning(self._file_name)
@@ -109,7 +111,7 @@ class dblite:
def sync(self):
self._check_writable()
f = self._open(self._tmp_name, "wb", self._mode)
- self._cPickle_dump(self._dict, f, 1)
+ self._pickle_dump(self._dict, f, 1)
f.close()
# Windows doesn't allow renaming if the file exists, so unlink
# it first, chmod'ing it to make sure we can do so. On UNIX, we
@@ -142,14 +144,14 @@ class dblite:
def __setitem__(self, key, value):
self._check_writable()
if (not is_string(key)):
- raise TypeError, "key `%s' must be a string but is %s" % (key, type(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))
+ raise TypeError("value `%s' must be a string but is %s" % (value, type(value)))
self._dict[key] = value
self._needs_sync = 0001
def keys(self):
- return self._dict.keys()
+ return list(self._dict.keys())
def has_key(self, key):
return key in self._dict
@@ -158,7 +160,8 @@ class dblite:
return key in self._dict
def iterkeys(self):
- return self._dict.iterkeys()
+ # Wrapping name in () prevents fixer from "fixing" this
+ return (self._dict.iterkeys)()
__iter__ = iterkeys
@@ -195,7 +198,7 @@ def _exercise():
except IOError, e:
assert str(e) == "Read-only database: tmp.dblite"
else:
- raise RuntimeError, "IOError expected."
+ raise RuntimeError("IOError expected.")
db = open("tmp", "w")
assert len(db) == 4
db["ping"] = "pong"
@@ -205,26 +208,26 @@ def _exercise():
except TypeError, e:
assert str(e) == "key `(1, 2)' must be a string but is <type 'tuple'>", str(e)
else:
- raise RuntimeError, "TypeError exception expected"
+ raise RuntimeError("TypeError exception expected")
try:
db["list"] = [1,2]
except TypeError, e:
assert str(e) == "value `[1, 2]' must be a string but is <type 'list'>", str(e)
else:
- raise RuntimeError, "TypeError exception expected"
+ raise RuntimeError("TypeError exception expected")
db = open("tmp", "r")
assert len(db) == 5
db = open("tmp", "n")
assert len(db) == 0
- _open("tmp.dblite", "w")
+ dblite._open("tmp.dblite", "w")
db = open("tmp", "r")
- _open("tmp.dblite", "w").write("x")
+ dblite._open("tmp.dblite", "w").write("x")
try:
db = open("tmp", "r")
- except cPickle.UnpicklingError:
+ except pickle.UnpicklingError:
pass
else:
- raise RuntimeError, "cPickle exception expected."
+ raise RuntimeError("pickle exception expected.")
global ignore_corrupt_dbfiles
ignore_corrupt_dbfiles = 2
db = open("tmp", "r")
@@ -235,7 +238,7 @@ def _exercise():
except IOError, e:
assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e)
else:
- raise RuntimeError, "IOError expected."
+ raise RuntimeError("IOError expected.")
print "OK"
if (__name__ == "__main__"):
diff --git a/src/engine/SCons/exitfuncs.py b/src/engine/SCons/exitfuncs.py
index 6c75d01..0521568 100644
--- a/src/engine/SCons/exitfuncs.py
+++ b/src/engine/SCons/exitfuncs.py
@@ -27,7 +27,7 @@ Register functions which are executed when SCons exits for any reason.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/SCons/exitfuncs.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/SCons/exitfuncs.py 5023 2010/06/14 22:05:46 scons"
@@ -41,7 +41,7 @@ def _run_exitfuncs():
while _exithandlers:
func, targs, kargs = _exithandlers.pop()
- apply(func, targs, kargs)
+ func(*targs, **kargs)
def register(func, *targs, **kargs):
"""register a function to be executed upon normal program termination
diff --git a/src/engine/setup.py b/src/engine/setup.py
index 11f4847..3f54801 100644
--- a/src/engine/setup.py
+++ b/src/engine/setup.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/engine/setup.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/engine/setup.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
@@ -37,7 +37,7 @@ if head:
# May come in handy to allow this setup.py to switch-hit between
# python-scons and python2-scons.
#head, package = os.path.split(os.getcwd())
-#suffix = "-1.3.0"
+#suffix = "-2.0.0.final.0"
#if package[-len(suffix):] == suffix:
# package = package[:-len(suffix)]
@@ -51,7 +51,7 @@ ver = {
}
setup(name = package,
- version = "1.3.0",
+ version = "2.0.0.final.0",
description = "SCons Python %s extension modules" % ver[package],
long_description = """SCons is an Open Source software construction tool--that is, a build tool; an
improved substitute for the classic Make utility; a better way to build
diff --git a/src/script/README.txt b/src/script/README.txt
index 5fa1e31..1f46437 100644
--- a/src/script/README.txt
+++ b/src/script/README.txt
@@ -5,12 +5,12 @@
### A SEPARATE SCRIPT PACKAGE IN THE FUTURE.
###
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-# src/script/README.txt 4720 2010/03/24 03:14:11 jars
+# src/script/README.txt 5023 2010/06/14 22:05:46 scons
SCons - a software construction tool
- Version 1.3.0
+ Version 2.0.0.final.0
This is an alpha release of SCons, a tool for building software (and
diff --git a/src/script/scons-post-install.py b/src/script/scons-post-install.py
index 40cbac1..4b04fec 100644
--- a/src/script/scons-post-install.py
+++ b/src/script/scons-post-install.py
@@ -31,10 +31,19 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/script/scons-post-install.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/script/scons-post-install.py 5023 2010/06/14 22:05:46 scons"
-import os.path
+import os
import sys
+import imp
+
+try:
+ # Before Python 3.0, the 'winreg' module was named '_winreg'
+ sys.modules['winreg'] = \
+ imp.load_module('winreg', *imp.find_module('_winreg'))
+except ImportError:
+ # No '_winreg' module: either 3.x or not Windows
+ pass
scons_bat_path = os.path.join(sys.prefix, 'Scripts', 'scons.bat')
@@ -43,15 +52,15 @@ app_paths_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\SCons.bat'
def install():
if sys.platform == 'win32':
try:
- import _winreg
+ import winreg
except ImportError:
pass
else:
print 'Writing "App Paths" registry entry for %s' % scons_bat_path
- _winreg.SetValue(
- _winreg.HKEY_LOCAL_MACHINE,
+ winreg.SetValue(
+ winreg.HKEY_LOCAL_MACHINE,
app_paths_key,
- _winreg.REG_SZ,
+ winreg.REG_SZ,
scons_bat_path)
print 'Done.'
@@ -59,12 +68,12 @@ def install():
def remove():
if sys.platform == 'win32':
try:
- import _winreg
+ import winreg
except ImportError:
pass
else:
# print 'Remove "App Paths" registry entry'
- _winreg.DeleteKey(_winreg.HKEY_LOCAL_MACHINE, app_paths_key)
+ winreg.DeleteKey(winreg.HKEY_LOCAL_MACHINE, app_paths_key)
if len(sys.argv) > 1:
diff --git a/src/script/scons-time.py b/src/script/scons-time.py
index ed8530c..36c1134 100644
--- a/src/script/scons-time.py
+++ b/src/script/scons-time.py
@@ -29,36 +29,58 @@
# 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__ = "src/script/scons-time.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/script/scons-time.py 5023 2010/06/14 22:05:46 scons"
import getopt
import glob
import os
-import os.path
import re
import shutil
-import string
import sys
import tempfile
import time
try:
- False
+ sorted
except NameError:
- # Pre-2.2 Python has no False keyword.
- import __builtin__
- __builtin__.False = not 1
+ # Pre-2.4 Python has no sorted() function.
+ #
+ # The pre-2.4 Python list.sort() method does not support
+ # list.sort(key=) nor list.sort(reverse=) keyword arguments, so
+ # we must implement the functionality of those keyword arguments
+ # by hand instead of passing them to list.sort().
+ def sorted(iterable, cmp=None, key=None, reverse=False):
+ if key is not None:
+ result = [(key(x), x) for x in iterable]
+ else:
+ result = iterable[:]
+ if cmp is None:
+ # Pre-2.3 Python does not support list.sort(None).
+ result.sort()
+ else:
+ result.sort(cmp)
+ if key is not None:
+ result = [t1 for t0,t1 in result]
+ if reverse:
+ result.reverse()
+ return result
-try:
- True
-except NameError:
- # Pre-2.2 Python has no True keyword.
- import __builtin__
- __builtin__.True = not 0
+if os.environ.get('SCONS_HORRIBLE_REGRESSION_TEST_HACK') is not None:
+ # We can't apply the 'callable' fixer until the floor is 2.6, but the
+ # '-3' option to Python 2.6 and 2.7 generates almost ten thousand
+ # warnings. This hack allows us to run regression tests with the '-3'
+ # option by replacing the callable() built-in function with a hack
+ # that performs the same function but doesn't generate the warning.
+ # Note that this hack is ONLY intended to be used for regression
+ # testing, and should NEVER be used for real runs.
+ from types import ClassType
+ def callable(obj):
+ if hasattr(obj, '__call__'): return True
+ if isinstance(obj, (ClassType, type)): return True
+ return False
def make_temp_file(**kw):
try:
@@ -90,7 +112,7 @@ def HACK_for_exec(cmd, *args):
elif len(args) == 1: exec cmd in args[0]
else: exec cmd in args[0], args[1]
-class Plotter:
+class Plotter(object):
def increment_size(self, largest):
"""
Return the size of each horizontal increment line for a specified
@@ -98,12 +120,12 @@ class Plotter:
between 5 and 9 horizontal lines on the graph, on some set of
boundaries that are multiples of 10/100/1000/etc.
"""
- i = largest / 5
+ i = largest // 5
if not i:
return largest
multiplier = 1
while i >= 10:
- i = i / 10
+ i = i // 10
multiplier = multiplier * 10
return i * multiplier
@@ -111,9 +133,9 @@ class Plotter:
# Round up to next integer.
largest = int(largest) + 1
increment = self.increment_size(largest)
- return ((largest + increment - 1) / increment) * increment
+ return ((largest + increment - 1) // increment) * increment
-class Line:
+class Line(object):
def __init__(self, points, type, title, label, comment, fmt="%s %s"):
self.points = points
self.type = type
@@ -177,13 +199,13 @@ class Gnuplotter(Plotter):
result = []
for line in self.lines:
result.extend(line.get_x_values())
- return filter(lambda r: not r is None, result)
+ return [r for r in result if not r is None]
def get_all_y_values(self):
result = []
for line in self.lines:
result.extend(line.get_y_values())
- return filter(lambda r: not r is None, result)
+ return [r for r in result if not r is None]
def get_min_x(self):
try:
@@ -236,10 +258,9 @@ class Gnuplotter(Plotter):
min_y = self.get_min_y()
max_y = self.max_graph_value(self.get_max_y())
- range = max_y - min_y
- incr = range / 10.0
+ incr = (max_y - min_y) / 10.0
start = min_y + (max_y / 2.0) + (2.0 * incr)
- position = [ start - (i * incr) for i in xrange(5) ]
+ position = [ start - (i * incr) for i in range(5) ]
inx = 1
for line in self.lines:
@@ -274,12 +295,11 @@ def unzip(fname):
open(name, 'w').write(zf.read(name))
def read_tree(dir):
- def read_files(arg, dirname, fnames):
- for fn in fnames:
- fn = os.path.join(dirname, fn)
+ for dirpath, dirnames, filenames in os.walk(dir):
+ for fn in filenames:
+ fn = os.path.join(dirpath, fn)
if os.path.isfile(fn):
open(fn, 'rb').read()
- os.path.walk('.', read_files, None)
def redirect_to_file(command, log):
return '%s > %s 2>&1' % (command, log)
@@ -289,7 +309,7 @@ def tee_to_file(command, log):
-class SConsTimer:
+class SConsTimer(object):
"""
Usage: scons-time SUBCOMMAND [ARGUMENTS]
Type "scons-time help SUBCOMMAND" for help on a specific subcommand.
@@ -506,9 +526,7 @@ class SConsTimer:
"""
files = []
for a in args:
- g = glob.glob(a)
- g.sort()
- files.extend(g)
+ files.extend(sorted(glob.glob(a)))
if tail:
files = files[-tail:]
@@ -539,7 +557,7 @@ class SConsTimer:
for file in files:
base = os.path.splitext(file)[0]
- run, index = string.split(base, '-')[-2:]
+ run, index = base.split('-')[-2:]
run = int(run)
index = int(index)
@@ -577,11 +595,11 @@ class SConsTimer:
and returns the next run number after the largest it finds.
"""
x = re.compile(re.escape(prefix) + '-([0-9]+).*')
- matches = map(lambda e, x=x: x.match(e), os.listdir(dir))
- matches = filter(None, matches)
+ matches = [x.match(e) for e in os.listdir(dir)]
+ matches = [_f for _f in matches if _f]
if not matches:
return 0
- run_numbers = map(lambda m: int(m.group(1)), matches)
+ run_numbers = [int(m.group(1)) for m in matches]
return int(max(run_numbers)) + 1
def gnuplot_results(self, results, fmt='%s %.3f'):
@@ -590,10 +608,7 @@ class SConsTimer:
"""
gp = Gnuplotter(self.title, self.key_location)
- indices = results.keys()
- indices.sort()
-
- for i in indices:
+ for i in sorted(results.keys()):
try:
t = self.run_titles[i]
except IndexError:
@@ -964,7 +979,7 @@ class SConsTimer:
if self.chdir:
os.chdir(self.chdir)
- logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+ logfile_path = lambda x: os.path.join(self.chdir, x)
if not args:
@@ -1084,7 +1099,7 @@ class SConsTimer:
if self.chdir:
os.chdir(self.chdir)
- logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+ logfile_path = lambda x: os.path.join(self.chdir, x)
if not args:
@@ -1248,7 +1263,7 @@ class SConsTimer:
except ValueError:
result.append(int(n))
else:
- result.extend(range(int(x), int(y)+1))
+ result.extend(list(range(int(x), int(y)+1)))
return result
def scons_path(self, dir):
@@ -1462,7 +1477,7 @@ class SConsTimer:
if self.chdir:
os.chdir(self.chdir)
- logfile_path = lambda x, c=self.chdir: os.path.join(c, x)
+ logfile_path = lambda x: os.path.join(self.chdir, x)
if not args:
diff --git a/src/script/scons.bat b/src/script/scons.bat
index 892f867..dbc1e75 100644
--- a/src/script/scons.bat
+++ b/src/script/scons.bat
@@ -1,11 +1,11 @@
@REM Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
-@REM src/script/scons.bat 4720 2010/03/24 03:14:11 jars
+@REM src/script/scons.bat 5023 2010/06/14 22:05:46 scons
@echo off
set SCONS_ERRORLEVEL=
if "%OS%" == "Windows_NT" goto WinNT
@REM for 9x/Me you better not have more than 9 args
-python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-1.3.0'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons-1.3.0'), join(sys.prefix, 'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 %6 %7 %8 %9
+python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-2.0.0.final.0'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons-2.0.0.final.0'), join(sys.prefix, 'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %1 %2 %3 %4 %5 %6 %7 %8 %9
@REM no way to set exit status of this script for 9x/Me
goto endscons
@@ -17,7 +17,7 @@ goto endscons
setlocal
@REM ensure the script will be executed with the Python it was installed for
set path=%~dp0;%~dp0..;%path%
-python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-1.3.0'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons-1.3.0'), join(sys.prefix, 'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %*
+python -c "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-2.0.0.final.0'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons-2.0.0.final.0'), join(sys.prefix, 'scons')] + sys.path; import SCons.Script; SCons.Script.main()" %*
endlocal & set SCONS_ERRORLEVEL=%ERRORLEVEL%
if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto returncode
diff --git a/src/script/scons.py b/src/script/scons.py
index 7fe4c60..c95bfac 100644
--- a/src/script/scons.py
+++ b/src/script/scons.py
@@ -24,17 +24,17 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/script/scons.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/script/scons.py 5023 2010/06/14 22:05:46 scons"
-__version__ = "1.3.0"
+__version__ = "2.0.0.final.0"
-__build__ = "r4720"
+__build__ = "r5023"
-__buildsys__ = "jars-desktop"
+__buildsys__ = "scons-dev"
-__date__ = "2010/03/24 03:14:11"
+__date__ = "2010/06/14 22:05:46"
-__developer__ = "jars"
+__developer__ = "scons"
import os
import os.path
@@ -76,7 +76,7 @@ if script_dir in sys.path:
libs = []
-if os.environ.has_key("SCONS_LIB_DIR"):
+if "SCONS_LIB_DIR" in os.environ:
libs.append(os.environ["SCONS_LIB_DIR"])
local_version = 'scons-local-' + __version__
@@ -137,12 +137,11 @@ else:
# check only /foo/lib/scons*.
prefs.append(sys.prefix)
- temp = map(lambda x: os.path.join(x, 'lib'), prefs)
- temp.extend(map(lambda x: os.path.join(x,
+ temp = [os.path.join(x, 'lib') for x in prefs]
+ temp.extend([os.path.join(x,
'lib',
'python' + sys.version[:3],
- 'site-packages'),
- prefs))
+ 'site-packages') for x in prefs])
prefs = temp
# Add the parent directory of the current python's library to the
@@ -175,8 +174,8 @@ else:
# Look first for 'scons-__version__' in all of our preference libs,
# then for 'scons'.
-libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
-libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
+libs.extend([os.path.join(x, scons_version) for x in prefs])
+libs.extend([os.path.join(x, 'scons') for x in prefs])
sys.path = libs + sys.path
diff --git a/src/script/sconsign.py b/src/script/sconsign.py
index e86f47f..c1f9632 100644
--- a/src/script/sconsign.py
+++ b/src/script/sconsign.py
@@ -22,22 +22,20 @@
# 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__ = "src/script/sconsign.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/script/sconsign.py 5023 2010/06/14 22:05:46 scons"
-__version__ = "1.3.0"
+__version__ = "2.0.0.final.0"
-__build__ = "r4720"
+__build__ = "r5023"
-__buildsys__ = "jars-desktop"
+__buildsys__ = "scons-dev"
-__date__ = "2010/03/24 03:14:11"
+__date__ = "2010/06/14 22:05:46"
-__developer__ = "jars"
+__developer__ = "scons"
import os
-import os.path
import sys
import time
@@ -64,7 +62,7 @@ if script_dir in sys.path:
libs = []
-if os.environ.has_key("SCONS_LIB_DIR"):
+if "SCONS_LIB_DIR" in os.environ:
libs.append(os.environ["SCONS_LIB_DIR"])
local_version = 'scons-local-' + __version__
@@ -125,12 +123,11 @@ else:
# check only /foo/lib/scons*.
prefs.append(sys.prefix)
- temp = map(lambda x: os.path.join(x, 'lib'), prefs)
- temp.extend(map(lambda x: os.path.join(x,
+ temp = [os.path.join(x, 'lib') for x in prefs]
+ temp.extend([os.path.join(x,
'lib',
'python' + sys.version[:3],
- 'site-packages'),
- prefs))
+ 'site-packages') for x in prefs])
prefs = temp
# Add the parent directory of the current python's library to the
@@ -163,8 +160,8 @@ else:
# Look first for 'scons-__version__' in all of our preference libs,
# then for 'scons'.
-libs.extend(map(lambda x: os.path.join(x, scons_version), prefs))
-libs.extend(map(lambda x: os.path.join(x, 'scons'), prefs))
+libs.extend([os.path.join(x, scons_version) for x in prefs])
+libs.extend([os.path.join(x, 'scons') for x in prefs])
sys.path = libs + sys.path
@@ -172,10 +169,11 @@ sys.path = libs + sys.path
# END STANDARD SCons SCRIPT HEADER
##############################################################################
-import cPickle
-import imp
-import string
+import SCons.compat # so pickle will import cPickle instead
+
import whichdb
+import pickle
+import imp
import SCons.SConsign
@@ -195,7 +193,7 @@ whichdb.whichdb = my_whichdb
def my_import(mname):
if '.' in mname:
- i = string.rfind(mname, '.')
+ i = mname.rfind('.')
parent = my_import(mname[:i])
fp, pathname, description = imp.find_module(mname[i+1:],
parent.__path__)
@@ -203,7 +201,7 @@ def my_import(mname):
fp, pathname, description = imp.find_module(mname)
return imp.load_module(mname, fp, pathname, description)
-class Flagger:
+class Flagger(object):
default_value = 1
def __setitem__(self, item, value):
self.__dict__[item] = value
@@ -250,11 +248,11 @@ def map_bkids(entry, name):
except AttributeError:
return None
result = []
- for i in xrange(len(bkids)):
+ for i in range(len(bkids)):
result.append(nodeinfo_string(bkids[i], bkidsigs[i], " "))
if result == []:
return None
- return string.join(result, "\n ")
+ return "\n ".join(result)
map_field = {
'action' : map_action,
@@ -283,29 +281,27 @@ def nodeinfo_raw(name, ninfo, prefix=""):
try:
keys = ninfo.field_list + ['_version_id']
except AttributeError:
- keys = d.keys()
- keys.sort()
+ keys = sorted(d.keys())
l = []
for k in keys:
l.append('%s: %s' % (repr(k), repr(d.get(k))))
if '\n' in name:
name = repr(name)
- return name + ': {' + string.join(l, ', ') + '}'
+ return name + ': {' + ', '.join(l) + '}'
def nodeinfo_cooked(name, ninfo, prefix=""):
try:
field_list = ninfo.field_list
except AttributeError:
field_list = []
- f = lambda x, ni=ninfo, v=Verbose: field(x, ni, v)
if '\n' in name:
name = repr(name)
- outlist = [name+':'] + filter(None, map(f, field_list))
+ outlist = [name+':'] + [_f for _f in [field(x, ninfo, Verbose) for x in field_list] if _f]
if Verbose:
sep = '\n ' + prefix
else:
sep = ' '
- return string.join(outlist, sep)
+ return sep.join(outlist)
nodeinfo_string = nodeinfo_cooked
@@ -338,9 +334,7 @@ def printentries(entries, location):
print nodeinfo_string(name, entry.ninfo)
printfield(name, entry.binfo)
else:
- names = entries.keys()
- names.sort()
- for name in names:
+ for name in sorted(entries.keys()):
entry = entries[name]
try:
ninfo = entry.ninfo
@@ -350,7 +344,7 @@ def printentries(entries, location):
print nodeinfo_string(name, entry.ninfo)
printfield(name, entry.binfo)
-class Do_SConsignDB:
+class Do_SConsignDB(object):
def __init__(self, dbm_name, dbm):
self.dbm_name = dbm_name
self.dbm = dbm
@@ -388,7 +382,7 @@ class Do_SConsignDB:
return
except KeyboardInterrupt:
raise
- except cPickle.UnpicklingError:
+ except pickle.UnpicklingError:
sys.stderr.write("sconsign: ignoring invalid `%s' file `%s'\n" % (self.dbm_name, fname))
return
except Exception, e:
@@ -404,14 +398,12 @@ class Do_SConsignDB:
else:
self.printentries(dir, val)
else:
- keys = db.keys()
- keys.sort()
- for dir in keys:
+ for dir in sorted(db.keys()):
self.printentries(dir, db[dir])
def printentries(self, dir, val):
print '=== ' + dir + ':'
- printentries(cPickle.loads(val), dir)
+ printentries(pickle.loads(val), dir)
def Do_SConsignDir(name):
try:
@@ -423,7 +415,7 @@ def Do_SConsignDir(name):
sconsign = SCons.SConsign.Dir(fp)
except KeyboardInterrupt:
raise
- except cPickle.UnpicklingError:
+ except pickle.UnpicklingError:
sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s'\n" % (name))
return
except Exception, e:
diff --git a/src/script/setup.py b/src/script/setup.py
index c4955ea..36e5e00 100644
--- a/src/script/setup.py
+++ b/src/script/setup.py
@@ -21,7 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/script/setup.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/script/setup.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
@@ -36,7 +36,7 @@ if head:
from distutils.core import setup
setup(name = "scons-script",
- version = "1.3.0",
+ version = "2.0.0.final.0",
description = "an Open Source software construction tool script",
long_description = """SCons is an Open Source software construction tool--that is, a build tool; an
improved substitute for the classic Make utility; a better way to build
diff --git a/src/setup.py b/src/setup.py
index 893712f..bc5dcb5 100644
--- a/src/setup.py
+++ b/src/setup.py
@@ -19,17 +19,15 @@
# 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__ = "src/setup.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/setup.py 5023 2010/06/14 22:05:46 scons"
import os
import os.path
import stat
-import string
import sys
-Version = "1.3.0"
+Version = "2.0.0.final.0"
man_pages = [
'scons.1',
@@ -77,7 +75,7 @@ _install_lib = distutils.command.install_lib.install_lib
_install_scripts = distutils.command.install_scripts.install_scripts
_build_scripts = distutils.command.build_scripts.build_scripts
-class _options:
+class _options(object):
pass
Options = _options()
@@ -198,7 +196,7 @@ def get_scons_prefix(libdir, is_win32):
if head == os.sep:
break
head, tail = os.path.split(head)
- if string.lower(tail)[:6] == "python":
+ if tail.lower()[:6] == "python":
# Found the Python library directory...
if is_win32:
# ...on Win32 systems, "scons" goes in the directory:
@@ -297,8 +295,8 @@ class install_scripts(_install_scripts):
create_version_script = self.do_nothing
inputs = self.get_inputs()
- bat_scripts = filter(lambda x: x[-4:] == '.bat', inputs)
- non_bat_scripts = filter(lambda x: x[-4:] != '.bat', inputs)
+ bat_scripts = [x for x in inputs if x[-4:] == '.bat']
+ non_bat_scripts = [x for x in inputs if x[-4:] != '.bat']
self.outfiles = []
self.mkpath(self.install_dir)
@@ -415,10 +413,10 @@ arguments = {
'build_scripts' : build_scripts}
}
-apply(distutils.core.setup, (), arguments)
+distutils.core.setup(**arguments)
if Installed:
- print string.join(Installed, '\n')
+ print '\n'.join(Installed)
# Local Variables:
# tab-width:4
diff --git a/src/test_aegistests.py b/src/test_aegistests.py
index dc160f3..919c621 100644
--- a/src/test_aegistests.py
+++ b/src/test_aegistests.py
@@ -20,9 +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.
-#
-__revision__ = "src/test_aegistests.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_aegistests.py 5023 2010/06/14 22:05:46 scons"
"""
Verify that we have proper Copyright notices on all the right files
@@ -35,7 +34,6 @@ name of this script doesn't end in *Tests.py.
import os
import popen2
import re
-import string
import sys
import TestSCons
@@ -57,8 +55,8 @@ else:
output = get_stdout('aegis -list -unformatted pf') +\
get_stdout('aegis -list -unformatted cf')
-lines = string.split(output, '\n')[:-1]
-sources = filter(lambda x: x[:7] == 'source ', lines)
+lines = output.split('\n')[:-1]
+sources = [x for x in lines if x[:7] == 'source ']
re1 = re.compile(r' src/.*Tests\.py')
re2 = re.compile(r' src/test_.*\.py')
@@ -67,11 +65,11 @@ re3 = re.compile(r' test/.*\.py')
def filename_is_a_test(x):
return re1.search(x) or re2.search(x) or re3.search(x)
-test_files = filter(filename_is_a_test, sources)
+test_files = list(filter(filename_is_a_test, sources))
if test_files:
sys.stderr.write("Found the following files with test names not marked as Aegis tests:\n")
- sys.stderr.write('\t' + string.join(test_files, '\n\t') + '\n')
+ sys.stderr.write('\t' + '\n\t'.join(test_files) + '\n')
test.fail_test(1)
test.pass_test()
diff --git a/src/test_files.py b/src/test_files.py
index 2d1294e..ef666c7 100644
--- a/src/test_files.py
+++ b/src/test_files.py
@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/test_files.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_files.py 5023 2010/06/14 22:05:46 scons"
"""
Verify that we have certain important files in our distribution
@@ -35,7 +35,6 @@ name of this script doesn't end in *Tests.py.
import os
import os.path
import re
-import string
import TestSCons
@@ -47,7 +46,7 @@ except KeyError:
cwd = os.getcwd()
def build_path(*args):
- return apply(os.path.join, (cwd, 'build',) + args)
+ return os.path.join(cwd, 'build', *args)
build_scons_tar_gz = build_path('unpack-tar-gz', 'scons-'+test.scons_version)
build_scons_zip = build_path('unpack-zip', 'scons-'+test.scons_version)
@@ -89,12 +88,12 @@ for directory, check_list in check.items():
if missing:
print "Missing the following files:\n"
- print "\t" + string.join(missing, "\n\t")
+ print "\t" + "\n\t".join(missing)
test.fail_test(1)
if no_result:
print "Cannot check files, the following have apparently not been built:"
- print "\t" + string.join(no_result, "\n\t")
+ print "\t" + "\n\t".join(no_result)
test.no_result(1)
test.pass_test()
diff --git a/src/test_interrupts.py b/src/test_interrupts.py
index 24f9bc3..ec7ad50 100644
--- a/src/test_interrupts.py
+++ b/src/test_interrupts.py
@@ -20,9 +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.
-#
-__revision__ = "src/test_interrupts.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_interrupts.py 5023 2010/06/14 22:05:46 scons"
"""
Verify that the SCons source code contains only correct handling of
@@ -32,7 +31,6 @@ keyboard interrupts (e.g. Ctrl-C).
import os
import os.path
import re
-import string
import time
import TestSCons
@@ -76,8 +74,8 @@ try:
except IOError:
test.skip_test('%s does not exist; skipping test.\n' % MANIFEST)
else:
- files = string.split(fp.read())
- files = filter(lambda f: f[-3:] == '.py', files)
+ files = fp.read().split()
+ files = [f for f in files if f[-3:] == '.py']
# some regexps to parse the python files
tryexc_pat = re.compile(
@@ -90,7 +88,7 @@ for f in files:
contents = open(os.path.join(scons_lib_dir, f)).read()
try_except_lines = {}
lastend = 0
- while 1:
+ while True:
match = tryexc_pat.search( contents, lastend )
if match is None:
break
@@ -100,7 +98,7 @@ for f in files:
indent_list = try_except_lines[match.group('indent')]
except:
indent_list = []
- line_num = 1 + string.count(contents[:match.start()], '\n')
+ line_num = 1 + contents[:match.start()].count('\n')
indent_list.append( (line_num, match.group('try_or_except') ) )
try_except_lines[match.group('indent')] = indent_list
uncaught_this_file = []
@@ -111,7 +109,7 @@ for f in files:
#print "%4d %s" % (l,statement),
m1 = keyboardint_pat.match(statement)
m2 = exceptall_pat.match(statement)
- if string.find(statement, indent + 'try') == 0:
+ if statement.find(indent + 'try') == 0:
if exc_all_seen and not exc_keyboardint_seen:
uncaught_this_file.append(line)
exc_keyboardint_seen = 0
diff --git a/src/test_pychecker.py b/src/test_pychecker.py
index e6efcb8..b4cf685 100644
--- a/src/test_pychecker.py
+++ b/src/test_pychecker.py
@@ -20,9 +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.
-#
-__revision__ = "src/test_pychecker.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_pychecker.py 5023 2010/06/14 22:05:46 scons"
"""
Use pychecker to catch various Python coding errors.
@@ -30,7 +29,6 @@ Use pychecker to catch various Python coding errors.
import os
import os.path
-import string
import sys
import TestSCons
@@ -64,21 +62,16 @@ else:
src_engine_ = os.path.join(src_engine, '')
MANIFEST = os.path.join(src_engine, 'MANIFEST.in')
-files = string.split(open(MANIFEST).read())
+files = open(MANIFEST).read().split()
-files = filter(lambda f: f[-3:] == '.py', files)
+files = [f for f in files if f[-3:] == '.py']
ignore = [
'SCons/compat/__init__.py',
'SCons/compat/_scons_UserString.py',
'SCons/compat/_scons_hashlib.py',
- 'SCons/compat/_scons_itertools.py',
- 'SCons/compat/_scons_optparse.py',
'SCons/compat/_scons_sets.py',
- 'SCons/compat/_scons_sets15.py',
- 'SCons/compat/_scons_shlex.py',
'SCons/compat/_scons_subprocess.py',
- 'SCons/compat/_scons_textwrap.py',
'SCons/compat/builtins.py',
]
@@ -90,10 +83,7 @@ for file in ignore:
del u[file]
except KeyError:
pass
-
-files = u.keys()
-
-files.sort()
+files = sorted(u.keys())
mismatches = []
@@ -131,15 +121,15 @@ for file in files:
test.run(program=program, arguments=args, status=None, stderr=None)
stdout = test.stdout()
- stdout = string.replace(stdout, src_engine_, '')
+ stdout = stdout.replace(src_engine_, '')
stderr = test.stderr()
- stderr = string.replace(stderr, src_engine_, '')
- stderr = string.replace(stderr, pywintypes_warning, '')
+ stderr = stderr.replace(src_engine_, '')
+ stderr = stderr.replace(pywintypes_warning, '')
if test.status or stdout or stderr:
mismatches.append('\n')
- mismatches.append(string.join([program] + args) + '\n')
+ mismatches.append(' '.join([program] + args) + '\n')
mismatches.append('STDOUT =====================================\n')
mismatches.append(stdout)
@@ -149,7 +139,7 @@ for file in files:
mismatches.append(stderr)
if mismatches:
- print string.join(mismatches[1:], '')
+ print ''.join(mismatches[1:])
test.fail_test()
test.pass_test()
diff --git a/src/test_setup.py b/src/test_setup.py
index a94cfe6..5d30638 100644
--- a/src/test_setup.py
+++ b/src/test_setup.py
@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/test_setup.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_setup.py 5023 2010/06/14 22:05:46 scons"
"""
Test how the setup.py script installs SCons.
@@ -34,7 +34,6 @@ name of this script doesn't end in *Tests.py.
import os
import os.path
import shutil
-import string
import sys
try: WindowsError
@@ -109,51 +108,50 @@ class MyTestSCons(TestSCons.TestSCons):
self.version_lib = os.path.join(self.lib_dir, scons_version)
self.man_dir = os.path.join(self.prefix, 'man', 'man1')
- self.prepend_bin_dir = lambda p, d=self.bin_dir: os.path.join(d, p)
- self.prepend_bat_dir = lambda p, d=self.bat_dir: os.path.join(d, p)
- self.prepend_man_dir = lambda p, d=self.man_dir: os.path.join(d, p)
+ self.prepend_bin_dir = lambda p: os.path.join(self.bin_dir, p)
+ self.prepend_bat_dir = lambda p: os.path.join(self.bat_dir, p)
+ self.prepend_man_dir = lambda p: os.path.join(self.man_dir, p)
def run(self, *args, **kw):
kw['chdir'] = scons_version
kw['program'] = python
kw['stderr'] = None
- return apply(TestSCons.TestSCons.run, (self,)+args, kw)
+ return TestSCons.TestSCons.run(self, *args, **kw)
def remove(self, dir):
try: shutil.rmtree(dir)
except (OSError, WindowsError): pass
def stdout_lines(self):
- return string.split(self.stdout(), '\n')
+ return self.stdout().split('\n')
def lib_line(self, lib):
return 'Installed SCons library modules into %s' % lib
def lib_paths(self, lib_dir):
- prepend_lib_dir = lambda p, d=lib_dir: os.path.join(d, 'SCons', p)
- return map(prepend_lib_dir, self._lib_modules)
+ return [os.path.join(lib_dir, 'SCons', p) for p in self._lib_modules]
def scripts_line(self):
return 'Installed SCons scripts into %s' % self.bin_dir
def base_script_paths(self):
scripts = self._base_scripts
- return map(self.prepend_bin_dir, scripts)
+ return list(map(self.prepend_bin_dir, scripts))
def version_script_paths(self):
scripts = self._version_scripts
- return map(self.prepend_bin_dir, scripts)
+ return list(map(self.prepend_bin_dir, scripts))
def bat_script_paths(self):
scripts = self._bat_scripts + self._bat_version_scripts
- return map(self.prepend_bat_dir, scripts)
+ return list(map(self.prepend_bat_dir, scripts))
def man_page_line(self):
return 'Installed SCons man pages into %s' % self.man_dir
def man_page_paths(self):
- return map(self.prepend_man_dir, self._man_pages)
+ return list(map(self.prepend_man_dir, self._man_pages))
def must_have_installed(self, paths):
@@ -321,8 +319,7 @@ test.must_have_installed(test.man_page_paths())
other_prefix = test.workpath('other-prefix')
test.subdir(other_prefix)
test.run(arguments = 'setup.py install --prefix=%s' % other_prefix)
-test.fail_test(string.find(test.stderr(),
- "you'll have to change the search path yourself")
+test.fail_test(test.stderr().find("you'll have to change the search path yourself")
!= -1)
# All done.
diff --git a/src/test_strings.py b/src/test_strings.py
index 0def9bb..ce48d4c 100644
--- a/src/test_strings.py
+++ b/src/test_strings.py
@@ -22,7 +22,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "src/test_strings.py 4720 2010/03/24 03:14:11 jars"
+__revision__ = "src/test_strings.py 5023 2010/06/14 22:05:46 scons"
"""
Verify that we have proper strings like Copyright notices on all the
@@ -36,7 +36,6 @@ import fnmatch
import os
import os.path
import re
-import string
import TestCmd
import TestSCons
@@ -47,13 +46,13 @@ test = TestCmd.TestCmd()
scons_version = TestSCons.SConsVersion
def build_path(*args):
- return apply(os.path.join, ('build',)+args)
+ return os.path.join('build', *args)
build_scons = build_path('scons')
build_local = build_path('scons-local', 'scons-local-'+scons_version)
build_src = build_path('scons-src')
-class Checker:
+class Checker(object):
def __init__(self, directory,
search_list = [],
remove_list = [],
@@ -86,27 +85,29 @@ class Checker:
else:
return os.path.isfile(path)
- def visit(self, result, dirname, names):
- make_path_tuple = lambda n, d=dirname: (n, os.path.join(d, n))
- for name, path in map(make_path_tuple, names):
- if self.remove_this(name, path):
- names.remove(name)
- elif self.search_this(path):
- body = open(path, 'r').read()
- for expr in self.expressions:
- if not expr.search(body):
- msg = '%s: missing %s' % (path, repr(expr.pattern))
- result.append(msg)
-
def find_missing(self):
result = []
- os.path.walk(self.directory, self.visit, result)
+ for dirpath, dirnames, filenames in os.walk(self.directory):
+ if '.svn' in dirnames:
+ dirnames.remove('.svn')
+ for dname in dirnames[:]:
+ dpath = os.path.join(dirpath, dname)
+ if self.remove_this(dname, dpath):
+ dirnames.remove(dname)
+ for fname in filenames:
+ fpath = os.path.join(dirpath, fname)
+ if self.search_this(fpath) and not self.remove_this(fname, fpath):
+ body = open(fpath, 'r').read()
+ for expr in self.expressions:
+ if not expr.search(body):
+ msg = '%s: missing %s' % (fpath, repr(expr.pattern))
+ result.append(msg)
return result
class CheckUnexpandedStrings(Checker):
expressions = [
re.compile('Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation'),
- re.compile('src/test_strings.py 4720 2010/03/24 03:14:11 jars'),
+ re.compile('src/test_strings.py 5023 2010/06/14 22:05:46 scons'),
]
def must_be_built(self):
return None
@@ -131,12 +132,8 @@ check_list = [
'src',
search_list = [ '*.py' ],
remove_list = [
- 'engine/SCons/compat/_scons_optparse.py',
'engine/SCons/compat/_scons_sets.py',
- 'engine/SCons/compat/_scons_sets15.py',
- 'engine/SCons/compat/_scons_shlex.py',
'engine/SCons/compat/_scons_subprocess.py',
- 'engine/SCons/compat/_scons_textwrap.py',
'engine/SCons/Conftest.py',
'engine/SCons/dblite.py',
],
@@ -164,12 +161,8 @@ check_list = [
'debian',
'dist',
'gentoo',
- 'engine/SCons/compat/_scons_optparse.py',
'engine/SCons/compat/_scons_sets.py',
- 'engine/SCons/compat/_scons_sets15.py',
- 'engine/SCons/compat/_scons_shlex.py',
'engine/SCons/compat/_scons_subprocess.py',
- 'engine/SCons/compat/_scons_textwrap.py',
'engine/SCons/Conftest.py',
'engine/SCons/dblite.py',
'MANIFEST',
@@ -185,12 +178,8 @@ check_list = [
CheckExpandedCopyright(
build_local,
remove_list = [
- 'SCons/compat/_scons_optparse.py',
'SCons/compat/_scons_sets.py',
- 'SCons/compat/_scons_sets15.py',
- 'SCons/compat/_scons_shlex.py',
'SCons/compat/_scons_subprocess.py',
- 'SCons/compat/_scons_textwrap.py',
'SCons/Conftest.py',
'SCons/dblite.py',
'scons-%s.egg-info' % scons_version,
@@ -223,19 +212,14 @@ check_list = [
'QMTest/configuration',
'QMTest/TestCmd.py',
'QMTest/TestCommon.py',
- 'QMTest/unittest.py',
'src/os_spawnv_fix.diff',
'src/MANIFEST.in',
'src/setup.cfg',
'src/engine/MANIFEST.in',
'src/engine/MANIFEST-xml.in',
'src/engine/setup.cfg',
- 'src/engine/SCons/compat/_scons_optparse.py',
'src/engine/SCons/compat/_scons_sets.py',
- 'src/engine/SCons/compat/_scons_sets15.py',
- 'src/engine/SCons/compat/_scons_shlex.py',
'src/engine/SCons/compat/_scons_subprocess.py',
- 'src/engine/SCons/compat/_scons_textwrap.py',
'src/engine/SCons/Conftest.py',
'src/engine/SCons/dblite.py',
'src/script/MANIFEST.in',
@@ -263,12 +247,12 @@ for collector in check_list:
if missing_strings:
print "Found the following files with missing strings:"
- print "\t" + string.join(missing_strings, "\n\t")
+ print "\t" + "\n\t".join(missing_strings)
test.fail_test(1)
if not_built:
print "Cannot check all strings, the following have apparently not been built:"
- print "\t" + string.join(not_built, "\n\t")
+ print "\t" + "\n\t".join(not_built)
test.no_result(1)
test.pass_test()