diff options
Diffstat (limited to 'doc/user')
29 files changed, 452 insertions, 249 deletions
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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < %s > %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 < %s > %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 < %s > %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 > $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 > $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" > $TARGET', + 'cat $SOURCE >> $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < $SOURCE > $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 < %s > %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 > $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) > 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( '->$MISSING<-' ) + </programlisting> + + <screen> + % <userinput>scons -Q</userinput> + value is: -><- + 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( '->$MISSING<-' ) + </programlisting> + + <screen> + % <userinput>scons -Q</userinput> + value is: + scons: *** NameError `MISSING' trying to evaluate `$MISSING' + File "/home/my/project/SConstruct", line 3, in <module> + </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( '->${1 / 0}<-' ) + </programlisting> + + <screen> + % <userinput>scons -Q</userinput> + value is: -><- + 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) > 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 + <class 'SCons.Node.FS.File'> 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': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, - 'ENV': {'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'ENV': { 'PATH': '/usr/local/bin:/opt/bin:/bin:/usr/bin'}, 'ESCAPE': <function escape at 0x700000>, - 'File': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': None, 'HOST_OS': None, 'IDLSUFFIXES': ['.idl', '.IDL'], @@ -304,7 +304,7 @@ 'PROGPREFIX': '', 'PROGSUFFIX': '', 'PSPAWN': <function piped_env_spawn at 0x700000>, - 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'SCANNERS': [], 'SHELL': 'sh', 'SHLIBPREFIX': '$LIBPREFIX', @@ -314,7 +314,7 @@ 'SPAWN': <function spawnvpe_spawn at 0x700000>, 'TARGET_ARCH': None, 'TARGET_OS': None, - 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0x700000>, + 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, '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': <function InstallBuilderWrapper at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder instance at 0x700000>, 'PCH': <SCons.Builder.BuilderBase instance at 0x700000>, 'RES': <SCons.Builder.BuilderBase instance at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder instance at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder instance at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, + { 'BUILDERS': {'_InternalInstall': <function InstallBuilderWrapper at 0x700000>, 'Object': <SCons.Builder.CompositeBuilder object at 0x700000>, 'PCH': <SCons.Builder.BuilderBase object at 0x700000>, 'RES': <SCons.Builder.BuilderBase object at 0x700000>, 'SharedObject': <SCons.Builder.CompositeBuilder object at 0x700000>, 'StaticObject': <SCons.Builder.CompositeBuilder object at 0x700000>, '_InternalInstallAs': <function InstallAsBuilderWrapper at 0x700000>}, 'CC': 'cl', - 'CCCOM': <SCons.Action.FunctionAction instance at 0x700000>, + 'CCCOM': <SCons.Action.FunctionAction object at 0x700000>, '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': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, - 'Dirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'Dir': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, + 'Dirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'ENV': { 'PATH': 'C:\\WINDOWS\\System32', 'PATHEXT': '.COM;.EXE;.BAT;.CMD', 'SystemRoot': 'C:\\WINDOWS'}, 'ESCAPE': <function escape at 0x700000>, - 'File': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'File': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'HOST_ARCH': '', 'HOST_OS': 'win32', 'IDLSUFFIXES': ['.idl', '.IDL'], @@ -405,13 +405,13 @@ 'PROGSUFFIX': '.exe', 'PSPAWN': <function piped_spawn at 0x700000>, 'RC': 'rc', - 'RCCOM': <SCons.Action.FunctionAction instance at 0x700000>, + 'RCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'RCFLAGS': [], 'RCSUFFIXES': ['.rc', '.rc2'], - 'RDirs': <SCons.Defaults.Variable_Method_Caller instance at 0x700000>, + 'RDirs': <SCons.Defaults.Variable_Method_Caller object at 0x700000>, 'SCANNERS': [], 'SHCC': '$CC', - 'SHCCCOM': <SCons.Action.FunctionAction instance at 0x700000>, + 'SHCCCOM': <SCons.Action.FunctionAction object at 0x700000>, 'SHCCFLAGS': ['$CCFLAGS'], 'SHCFLAGS': ['$CFLAGS'], 'SHCXX': '$CXX', @@ -426,7 +426,7 @@ 'STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME': 1, 'TARGET_ARCH': '', 'TARGET_OS': 'win32', - 'TEMPFILE': <class SCons.Platform.TempFileMunge at 0x700000>, + 'TEMPFILE': <class 'SCons.Platform.TempFileMunge'>, '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> |