From 18b45e456412379c9182dd9cb4c8b30ca1e841b8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 3 Jun 2024 07:18:54 -0600 Subject: [PATCH] Allow a Variable to not be substituted New parameter do_subst added to the variables Add method, if false indicates the variable value should not be substituted by the Variables logic. The default is True. Fixes #4241. Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 +++ RELEASE.txt | 3 +++ SCons/Tool/yacc.xml | 4 ++-- SCons/Variables/PathVariable.py | 2 +- SCons/Variables/__init__.py | 26 ++++++++++++++++++-------- doc/generated/variables.gen | 4 ++-- doc/man/scons.xml | 17 ++++++++++++++++- 7 files changed, 45 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ab13ef074b..8850bfe9d2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -85,6 +85,9 @@ 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. + - When a variable is added to a Variables object, it can now be flagged + as "don't perform substitution". This allows variables to contain + characters which would otherwise cause expansion. Fixes #4241. RELEASE 4.7.0 - Sun, 17 Mar 2024 17:22:20 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index b9c253f4d4..ec22f1057a 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -50,6 +50,9 @@ CHANGED/ENHANCED EXISTING FUNCTIONALITY 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 Variables object Add method now accepts a do_subst keyword argument + (defaults to True) which can be set to inhibit substitution prior to + calling the variable's converter and validator. FIXES ----- diff --git a/SCons/Tool/yacc.xml b/SCons/Tool/yacc.xml index 82725dbade..729c408286 100644 --- a/SCons/Tool/yacc.xml +++ b/SCons/Tool/yacc.xml @@ -236,7 +236,7 @@ The value is used only if &cv-YACC_GRAPH_FILE_SUFFIX; is not set. The default value is .gv. -Changed in version 4.X.Y: deprecated. The default value +Changed in version 4.6.0: deprecated. The default value changed from .vcg (&bison; stopped generating .vcg output with version 2.4, in 2006). @@ -261,7 +261,7 @@ Various yacc tools have emitted various formats at different times. Set this to match what your parser generator produces. -New in version 4.X.Y. +New in version 4.6.0. diff --git a/SCons/Variables/PathVariable.py b/SCons/Variables/PathVariable.py index 6ea4e6bc93..4a827c5e12 100644 --- a/SCons/Variables/PathVariable.py +++ b/SCons/Variables/PathVariable.py @@ -141,7 +141,7 @@ def PathExists(key, val, env) -> None: # lint: W0622: Redefining built-in 'help' (redefined-builtin) def __call__( - self, key, help: str, default, validator: Optional[Callable] = None + self, key: str, help: str, default, validator: Optional[Callable] = None ) -> Tuple[str, str, str, Callable, None]: """Return a tuple describing a path list SCons Variable. diff --git a/SCons/Variables/__init__.py b/SCons/Variables/__init__.py index 867493d7c8..03f7ef3b50 100644 --- a/SCons/Variables/__init__.py +++ b/SCons/Variables/__init__.py @@ -49,7 +49,7 @@ class Variable: """A Build Variable.""" - __slots__ = ('key', 'aliases', 'help', 'default', 'validator', 'converter') + __slots__ = ('key', 'aliases', 'help', 'default', 'validator', 'converter', 'do_subst') def __lt__(self, other): """Comparison fuction so Variable instances sort.""" @@ -87,9 +87,9 @@ def __init__( ) -> None: self.options: List[Variable] = [] self.args = args if args is not None else {} - if not SCons.Util.is_List(files): + if not SCons.Util.is_Sequence(files): files = [files] if files else [] - self.files = files + self.files: Sequence[str] = files self.unknown: Dict[str, str] = {} def __str__(self) -> str: @@ -132,6 +132,7 @@ def _do_add( option.default = default option.validator = validator option.converter = converter + option.do_subst = kwargs.get("subst", True) self.options.append(option) @@ -171,8 +172,11 @@ def Add( value before putting it in the environment. (default: ``None``) """ if SCons.Util.is_Sequence(key): - if not (len(args) or len(kwargs)): - return self._do_add(*key) + # If no other positional args (and no fundamental kwargs), + # unpack key, and pass the kwargs on: + known_kw = {'help', 'default', 'validator', 'converter'} + if not args and not known_kw.intersection(kwargs.keys()): + return self._do_add(*key, **kwargs) return self._do_add(key, *args, **kwargs) @@ -247,7 +251,10 @@ def Update(self, env, args: Optional[dict] = None) -> None: # apply converters for option in self.options: if option.converter and option.key in values: - value = env.subst(f'${option.key}') + if option.do_subst: + value = env.subst(f'${option.key}') + else: + value = env[option.key] try: try: env[option.key] = option.converter(value) @@ -262,7 +269,11 @@ def Update(self, env, args: Optional[dict] = None) -> None: # apply validators for option in self.options: if option.validator and option.key in values: - option.validator(option.key, env.subst(f'${option.key}'), env) + if option.do_subst: + value = env.subst('${%s}'%option.key) + else: + value = env[option.key] + option.validator(option.key, value, env) def UnknownVariables(self) -> dict: """Return dict of unknown variables. @@ -340,7 +351,6 @@ def GenerateHelpText(self, env, sort: Union[bool, Callable] = False) -> str: # removed so now we have to convert to a key. if callable(sort): options = sorted(self.options, key=cmp_to_key(lambda x, y: sort(x.key, y.key))) - elif sort is True: options = sorted(self.options) else: diff --git a/doc/generated/variables.gen b/doc/generated/variables.gen index 8c89616d35..fad7d5d4ae 100644 --- a/doc/generated/variables.gen +++ b/doc/generated/variables.gen @@ -10668,7 +10668,7 @@ Various yacc tools have emitted various formats at different times. Set this to match what your parser generator produces. -New in version 4.X.Y. +New in version 4.6.0. @@ -10826,7 +10826,7 @@ The value is used only if &cv-YACC_GRAPH_FILE_SUFFIX; is not set. The default value is .gv. -Changed in version 4.X.Y: deprecated. The default value +Changed in version 4.6.0: deprecated. The default value changed from .vcg (&bison; stopped generating .vcg output with version 2.4, in 2006). diff --git a/doc/man/scons.xml b/doc/man/scons.xml index cdaaa44ac9..eb02a23248 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -4835,7 +4835,7 @@ not to any stored-values files. - vars.Add(key, [help, default, validator, converter]) + vars.Add(key, [help, default, validator, converter, do_subst]) Add a customizable &consvar; to the &Variables; object. key @@ -4887,6 +4887,16 @@ or there is no separate validator it can raise a ValueError. + +Substitution will be performed on the variable value +as it is added, before the converter and validator are called, +unless the optional do_subst parameter +is false (default True). +Suppressing substitution may be useful if the variable value +looks like a &consvar; reference ($VAR) +to be expanded later. + + As a special case, if key is a sequence and is the only @@ -4919,6 +4929,11 @@ def valid_color(key, val, env): vars.Add('COLOR', validator=valid_color) + + +Changed in version 4.8.0: +added the do_subst parameter. +