Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach Clone() to respect the variables= kwarg. #4553

Merged
merged 1 commit into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
Now matches the annotation and docstring (which were prematurely
updated in 4.6). All SCons usage except unit test was already fully
consistent with a bool.
- The Clone() method now respects the variables argument (fixes #3590)


RELEASE 4.7.0 - Sun, 17 Mar 2024 17:22:20 -0700
Expand Down
1 change: 1 addition & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ FIXES
- Improved the conversion of a "foreign" exception from an action
into BuildError by making sure our defaults get applied even in
corner cases. Fixes Issue #4530
- The Clone() method now respects the variables argument (fixes #3590)

IMPROVEMENTS
------------
Expand Down
28 changes: 21 additions & 7 deletions SCons/Environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -1568,16 +1568,28 @@ def AppendUnique(self, delete_existing: bool=False, **kw) -> None:
self._dict[key] = dk + val
self.scanner_map_delete(kw)

def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw):
def Clone(self, tools=[], toolpath=None, variables=None, parse_flags=None, **kw):
"""Return a copy of a construction Environment.

The copy is like a Python "deep copy"--that is, independent
copies are made recursively of each objects--except that
a reference is copied when an object is not deep-copyable
(like a function). There are no references to any mutable
objects in the original Environment.
"""
The copy is like a Python "deep copy": independent copies are made
recursively of each object, except that a reference is copied when
an object is not deep-copyable (like a function). There are no
references to any mutable objects in the original environment.

Unrecognized keyword arguments are taken as construction variable
assignments.

Arguments:
tools: list of tools to initialize.
toolpath: list of paths to search for tools.
variables: a :class:`~SCons.Variables.Variables` object to
use to populate construction variables from command-line
variables.
parse_flags: option strings to parse into construction variables.

.. versionadded:: 4.8.0
The optional *variables* parameter was added.
"""
builders = self._dict.get('BUILDERS', {})

clone = copy.copy(self)
Expand All @@ -1603,6 +1615,8 @@ def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw):
for key, value in kw.items():
new[key] = SCons.Subst.scons_subst_once(value, self, key)
clone.Replace(**new)
if variables:
variables.Update(clone)

apply_tools(clone, tools, toolpath)

Expand Down
32 changes: 23 additions & 9 deletions SCons/Environment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1079,11 +1079,12 @@ Clean(docdir, os.path.join(docdir, projectname))
</arguments>
<summary>
<para>
Returns a separate copy of a construction environment.
If there are any keyword arguments specified,
they are added to the returned copy,
Returns an independent copy of a &consenv;.
If there are any unrecognized keyword arguments specified,
they are added as &consvars; in the copy,
overwriting any existing values
for the keywords.
for those keywords.
See the manpage section "Construction Environments" for more details.
</para>

<para>
Expand All @@ -1096,8 +1097,9 @@ env3 = env.Clone(CCFLAGS='-g')
</example_commands>

<para>
Additionally, a list of tools and a toolpath may be specified, as in
the &f-link-Environment; constructor:
A list of <parameter>tools</parameter>
and a <parameter>toolpath</parameter> may be specified,
as in the &f-link-Environment; constructor:
</para>

<example_commands>
Expand All @@ -1110,7 +1112,7 @@ env4 = env.Clone(tools=['msvc', MyTool])
<para>
The
<parameter>parse_flags</parameter>
keyword argument is also recognized to allow merging command-line
keyword argument is also recognized, to allow merging command-line
style arguments into the appropriate construction
variables (see &f-link-env-MergeFlags;).
</para>
Expand All @@ -1119,6 +1121,17 @@ variables (see &f-link-env-MergeFlags;).
# create an environment for compiling programs that use wxWidgets
wx_env = env.Clone(parse_flags='!wx-config --cflags --cxxflags')
</example_commands>

<para>
The <parameter>variables</parameter>
keyword argument is also recognized, to allow (re)initializing
&consvars; from a <literal>Variables</literal> object.
</para>

<para>
<emphasis>Changed in version 4.8.0:</emphasis>
the <parameter>variables</parameter> parameter was added.
</para>
</summary>
</scons_function>

Expand Down Expand Up @@ -1760,7 +1773,7 @@ will print:
</arguments>
<summary>
<para>
Return a new construction environment
Return a new &consenv;
initialized with the specified
<parameter>key</parameter>=<replaceable>value</replaceable>
pairs.
Expand All @@ -1770,7 +1783,8 @@ The keyword arguments
<parameter>toolpath</parameter>,
<parameter>tools</parameter>
and <parameter>variables</parameter>
are also specially recognized.
are specially recognized and do not lead to
&consvar; creation.
See the manpage section "Construction Environments" for more details.
</para>
</summary>
Expand Down
63 changes: 63 additions & 0 deletions test/Clone-Variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
#
# MIT License
#
# Copyright 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.


"""
Verify that Clone() respects the variables kwarg.

"""

import TestSCons

test = TestSCons.TestSCons()

test.write('SConstruct', """\
vars = Variables()
vars.Add(BoolVariable('MYTEST', 'help', default=False))

_ = DefaultEnvironment(tools=[])
env = Environment(variables=vars, tools=[])
print(f"MYTEST={env.Dictionary('MYTEST')}")
env.Replace(MYTEST=True)
print(f"MYTEST={env.Dictionary('MYTEST')}")
env1 = env.Clone(variables=vars)
print(f"MYTEST={env1.Dictionary('MYTEST')}")
""")

expect = """\
MYTEST=False
MYTEST=True
MYTEST=False
"""

test.run(arguments = '-q -Q', stdout=expect)

test.pass_test()

# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
# End:
# vim: set expandtab tabstop=4 shiftwidth=4:
Loading