Skip to content

Commit 898415e

Browse files
committed
Updates on Value nodes
Some doc changes. E2E tests cleaned up a bit. Before merge: TODO: second half of manpage example doesn't work. Also: should test give SCons.Node.Value.Value as factory, or just Value? (remove new import if the latter). SCons.Node.Value.Value and SCons.Environment.Value are not the same thing. Signed-off-by: Mats Wichmann <[email protected]>
1 parent 351c604 commit 898415e

File tree

9 files changed

+104
-79
lines changed

9 files changed

+104
-79
lines changed

.appveyor.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ environment:
3636
matrix:
3737
# Test oldest and newest supported Pythons, and a subset in between.
3838
# Skipping 3.7 and 3.9 at this time
39-
- WINPYTHON: "Python311"
39+
- WINPYTHON: "Python312"
4040

4141
- WINPYTHON: "Python310"
4242

@@ -50,15 +50,15 @@ matrix:
5050
exclude:
5151
# test python 3.6 on Visual Studio 2017 image
5252
- image: Visual Studio 2017
53-
WINPYTHON: "Python311"
53+
WINPYTHON: "Python312"
5454
- image: Visual Studio 2017
5555
WINPYTHON: "Python310"
5656
- image: Visual Studio 2017
5757
WINPYTHON: "Python38"
5858

5959
# test python 3.8 on Visual Studio 2019 image
6060
- image: Visual Studio 2019
61-
WINPYTHON: "Python311"
61+
WINPYTHON: "Python312"
6262
- image: Visual Studio 2019
6363
WINPYTHON: "Python310"
6464
- image: Visual Studio 2019

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
104104
DeprecatedMissingSConscriptWarning) add two warnings to manpage
105105
(cache-cleanup-error, future-reserved-variable), improve unittest, tweak
106106
Sphinx build.
107+
- Updated Value Node docs and tests.
107108

108109

109110
RELEASE 4.6.0 - Sun, 19 Nov 2023 17:22:20 -0700

RELEASE.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ DOCUMENTATION
9696
- The manpage entry for SharedLibrary was clarified.
9797
- Update API docs for Warnings framework; add two warns to manpage
9898
enable/disable control.
99+
- Updated Value Node docs.
99100

100101
DEVELOPMENT
101102
-----------

SCons/Environment.xml

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,33 +3511,22 @@ gltool(env) # adds 'opengl' to the TOOLS variable
35113511
</arguments>
35123512
<summary>
35133513
<para>
3514-
Returns a Node object representing the specified &Python; value. Value
3515-
Nodes can be used as dependencies of targets. If the result of
3516-
calling
3517-
<function>str</function>(<parameter>value</parameter>)
3518-
changes between SCons runs, any targets depending on
3519-
<function>Value</function>(<parameter>value</parameter>)
3520-
will be rebuilt.
3521-
(This is true even when using timestamps to decide if
3522-
files are up-to-date.)
3523-
When using timestamp source signatures, Value Nodes'
3524-
timestamps are equal to the system time when the Node is created.
3514+
Returns a Node object representing the specified &Python;
3515+
<parameter>value</parameter>.
3516+
Value Nodes can be used as dependencies of targets.
3517+
If the string representation of the Value Node
3518+
changes between &SCons; runs, it is considered
3519+
out of date and any targets depending it will be rebuilt.
3520+
Since Value Nodes have no filesystem representation,
3521+
timestamps are not used; the timestamp deciders
3522+
perform the same content-based up to date check.
35253523
</para>
3526-
35273524
<para>
3528-
The returned Value Node object has a
3529-
<function>write</function>()
3530-
method that can be used to "build" a Value Node
3531-
by setting a new value.
35323525
The optional
35333526
<parameter>built_value</parameter>
35343527
argument can be specified
35353528
when the Value Node is created
3536-
to indicate the Node should already be considered
3537-
"built."
3538-
There is a corresponding
3539-
<function>read</function>()
3540-
method that will return the built value of the Node.
3529+
to indicate the Node should already be considered "built."
35413530
</para>
35423531

35433532
<para>
@@ -3547,6 +3536,16 @@ this is advised if the <parameter>value</parameter> parameter
35473536
cannot be converted to a string.
35483537
</para>
35493538

3539+
<para>
3540+
Value Nodes have a
3541+
<methodname>write</methodname>
3542+
method that can be used to "build" a Value Node
3543+
by setting a new value.
3544+
The corresponding
3545+
<methodname>read</methodname>
3546+
method returns the built value of the Node.
3547+
</para>
3548+
35503549
<para>
35513550
<emphasis>Changed in version 4.0:</emphasis>
35523551
the <parameter>name</parameter> parameter was added.
@@ -3556,36 +3555,39 @@ the <parameter>name</parameter> parameter was added.
35563555
Examples:
35573556
</para>
35583557

3558+
<!-- TODO fix second example or replace - still doesn't work -->
35593559
<example_commands>
35603560
env = Environment()
35613561

35623562
def create(target, source, env):
3563-
# A function that will write a 'prefix=$SOURCE'
3564-
# string into the file name specified as the
3565-
# $TARGET.
3563+
"""Action function to create a file from a Value.
3564+
3565+
Writes 'prefix=$SOURCE' into the file name given as $TARGET.
3566+
"""
35663567
with open(str(target[0]), 'wb') as f:
3567-
f.write('prefix=' + source[0].get_contents())
3568+
f.write(b'prefix=' + source[0].get_contents() + b'\n')
35683569

3569-
# Fetch the prefix= argument, if any, from the command
3570-
# line, and use /usr/local as the default.
3570+
# Fetch the prefix= argument, if any, from the command line.
3571+
# Use /usr/local as the default.
35713572
prefix = ARGUMENTS.get('prefix', '/usr/local')
35723573

3573-
# Attach a .Config() builder for the above function action
3574-
# to the construction environment.
3574+
# Attach builder named Config to the construction environment
3575+
# using the 'create' action function above.
35753576
env['BUILDERS']['Config'] = Builder(action=create)
35763577
env.Config(target='package-config', source=Value(prefix))
35773578

35783579
def build_value(target, source, env):
3579-
# A function that "builds" a Python Value by updating
3580-
# the Python value with the contents of the file
3581-
# specified as the source of the Builder call ($SOURCE).
3580+
"""Action function to "build" a Value.
3581+
3582+
Writes contents of $SOURCE into $TARGET, thus updating if it existed.
3583+
"""
35823584
target[0].write(source[0].get_contents())
35833585

35843586
output = env.Value('before')
35853587
input = env.Value('after')
35863588

3587-
# Attach a .UpdateValue() builder for the above function
3588-
# action to the construction environment.
3589+
# Attach a builder named UpdateValue to the construction environment
3590+
# using the 'build_value' action function above.
35893591
env['BUILDERS']['UpdateValue'] = Builder(action=build_value)
35903592
env.UpdateValue(target=Value(output), source=Value(input))
35913593
</example_commands>
@@ -3600,7 +3602,7 @@ env.UpdateValue(target=Value(output), source=Value(input))
36003602
<para>
36013603
Sets up a mapping to define a variant build directory in
36023604
<parameter>variant_dir</parameter>.
3603-
<parameter>src_dir</parameter> may not be underneath
3605+
<parameter>src_dir</parameter> must not be underneath
36043606
<parameter>variant_dir</parameter>.
36053607
A &f-VariantDir; mapping is global, even if called using the
36063608
&f-env-VariantDir; form.

SCons/Node/PythonTests.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525

2626
import SCons.Errors
2727
import SCons.Node.Python
28+
from SCons.Script import Depends
2829

2930

3031
class ValueTestCase(unittest.TestCase):
3132
def test_Value(self) -> None:
32-
"""Test creating a Value() object
33-
"""
33+
"""Test creating a Value() object."""
3434
v1 = SCons.Node.Python.Value('a')
3535
assert v1.value == 'a', v1.value
3636

@@ -39,45 +39,50 @@ def test_Value(self) -> None:
3939
assert v2.value == value2, v2.value
4040
assert v2.value is value2, v2.value
4141

42+
# the two nodes are not the same though they have same attributes
4243
assert v1 is not v2
4344
assert v1.value == v2.value
45+
assert v1.name == v2.name
4446

47+
# node takes the built_value if one is supplied.
4548
v3 = SCons.Node.Python.Value('c', 'cb')
4649
assert v3.built_value == 'cb'
4750

4851
def test_build(self) -> None:
49-
"""Test "building" a Value Node
50-
"""
52+
"""Test "building" a Value Node."""
5153
class fake_executor:
5254
def __call__(self, node) -> None:
5355
node.write('faked')
5456

55-
v1 = SCons.Node.Python.Value('b', 'built')
57+
# *built_value* arg means already built, executor will not be called
58+
v1 = SCons.Node.Python.Value('b', built_value='built')
5659
v1.executor = fake_executor()
5760
v1.build()
5861
assert v1.built_value == 'built', v1.built_value
5962

63+
# not built, executor will build it
6064
v2 = SCons.Node.Python.Value('b')
6165
v2.executor = fake_executor()
6266
v2.build()
6367
assert v2.built_value == 'faked', v2.built_value
6468

69+
# test the *name* parameter to refer to the node
6570
v3 = SCons.Node.Python.Value(b'\x00\x0F', name='name')
6671
v3.executor = fake_executor()
6772
v3.build()
68-
assert v3.name == 'name', v3.name
6973
assert v3.built_value == 'faked', v3.built_value
74+
# building the node does not change the name
75+
assert v3.name == 'name', v3.name
7076

7177
def test_read(self) -> None:
72-
"""Test the Value.read() method
73-
"""
78+
"""Test the Value.read() method."""
7479
v1 = SCons.Node.Python.Value('a')
7580
x = v1.read()
7681
assert x == 'a', x
7782

7883
def test_write(self) -> None:
79-
"""Test the Value.write() method
80-
"""
84+
"""Test the Value.write() method."""
85+
# creating the node without built_value does not set it
8186
v1 = SCons.Node.Python.Value('a')
8287
assert v1.value == 'a', v1.value
8388
assert not hasattr(v1, 'built_value')
@@ -87,8 +92,7 @@ def test_write(self) -> None:
8792
assert v1.built_value == 'new', v1.built_value
8893

8994
def test_get_csig(self) -> None:
90-
"""Test calculating the content signature of a Value() object
91-
"""
95+
"""Test calculating the content signature of a Value() object."""
9296
v1 = SCons.Node.Python.Value('aaa')
9397
csig = v1.get_csig(None)
9498
assert csig == 'aaa', csig
@@ -101,8 +105,17 @@ def test_get_csig(self) -> None:
101105
csig = v3.get_csig(None)
102106
assert csig == 'None', csig
103107

104-
105-
108+
# Dependencies: a tree of Value nodes comes back as a single string.
109+
# This may change someday, bot for now:
110+
v1 = SCons.Node.Python.Value('node1')
111+
v2 = SCons.Node.Python.Value('node2')
112+
v3 = SCons.Node.Python.Value('node3')
113+
v4 = SCons.Node.Python.Value('node4')
114+
Depends(v1, [v2, v3])
115+
Depends(v3, v4)
116+
assert v1.read() == 'node1', v1.read
117+
csig = v1.get_csig()
118+
assert csig == 'node1node2node3node4', csig
106119

107120

108121
class ValueNodeInfoTestCase(unittest.TestCase):

SCons/Taskmaster/Job.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,8 @@ def __init__(self, num, stack_size, interrupted) -> None:
278278

279279
try:
280280
prev_size = threading.stack_size(stack_size * 1024)
281-
except AttributeError as e:
282-
# Only print a warning if the stack size has been
283-
# explicitly set.
281+
except RuntimeError as e:
282+
# Only print a warning if the stack size has been explicitly set.
284283
if explicit_stack_size is not None:
285284
msg = "Setting stack size is unsupported by this version of Python:\n " + \
286285
e.args[0]

test/Actions/function.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@
3939
test.write('SConstruct', r"""
4040
import re
4141
42-
import SCons.Action
43-
import SCons.Builder
44-
4542
options = Variables()
4643
options.AddVariables(
4744
('header', 'Header string (default cell argument)', 'Head:'),
@@ -91,8 +88,8 @@ def foo(b=b):
9188
9289
exec(withClosure % optEnv)
9390
94-
genHeaderBld = SCons.Builder.Builder(
95-
action=SCons.Action.Action(toto(), 'Generating $TARGET', varlist=['ENVDEPS']),
91+
genHeaderBld = Builder(
92+
action=Action(toto(), 'Generating $TARGET', varlist=['ENVDEPS']),
9693
suffix='.gen.h',
9794
)
9895

test/Value/GetContent.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python
22
#
3-
# __COPYRIGHT__
3+
# SPDX-License-Identifier: MIT
4+
#
5+
# Copyright The SCons Foundation
46
#
57
# Permission is hereby granted, free of charge, to any person obtaining
68
# a copy of this software and associated documentation files (the
@@ -20,9 +22,6 @@
2022
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
2123
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
2224
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23-
#
24-
25-
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
2625

2726
"""
2827
Test the Value node as a build target
@@ -33,18 +32,25 @@
3332
test = TestSCons.TestSCons()
3433

3534
test.write('SConstruct', """
36-
import SCons.Script
35+
import SCons.Node
36+
3737
def null_build(target, source, env):
3838
pass
39+
3940
env = DefaultEnvironment()
40-
env['BUILDERS']['ValueBuilder'] = SCons.Builder.Builder(
41-
action=SCons.Action.Action(null_build),
42-
target_factory=SCons.Node.Python.Value,
43-
)
44-
v = env.ValueBuilder("myvalue",env.Dir("#"))
45-
v[0].get_text_contents()
41+
env['BUILDERS']['ValueBuilder'] = Builder(
42+
action=Action(null_build),
43+
target_factory=SCons.Node.Python.Value,
44+
)
45+
v = env.ValueBuilder("myvalue", env.Dir("#"))
46+
_ = v[0].get_text_contents() # only care it doesn't take exception
4647
""")
4748

4849
test.run()
4950
test.pass_test()
5051

52+
# Local Variables:
53+
# tab-width:4
54+
# indent-tabs-mode:nil
55+
# End:
56+
# vim: set expandtab tabstop=4 shiftwidth=4:

0 commit comments

Comments
 (0)