summaryrefslogtreecommitdiffstats
path: root/SCons/Variables/EnumVariable.py
diff options
context:
space:
mode:
Diffstat (limited to 'SCons/Variables/EnumVariable.py')
-rw-r--r--SCons/Variables/EnumVariable.py116
1 files changed, 78 insertions, 38 deletions
diff --git a/SCons/Variables/EnumVariable.py b/SCons/Variables/EnumVariable.py
index 1a4f3fb..d13e9a9 100644
--- a/SCons/Variables/EnumVariable.py
+++ b/SCons/Variables/EnumVariable.py
@@ -38,12 +38,12 @@ Usage example::
ignorecase=2,
)
)
- ...
+ env = Environment(variables=opts)
if env['debug'] == 'full':
- ...
+ ...
"""
-from typing import Tuple, Callable
+from typing import Callable, List, Optional, Tuple
import SCons.Errors
@@ -51,57 +51,97 @@ __all__ = ['EnumVariable',]
def _validator(key, val, env, vals) -> None:
- if val not in vals:
- raise SCons.Errors.UserError(
- 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals))
-
+ """Validate that val is in vals.
-def EnumVariable(key, help, default, allowed_values, map={}, ignorecase: int=0) -> Tuple[str, str, str, Callable, Callable]:
+ Usable as the base for :class:`EnumVariable` validators.
+ """
+ if val not in vals:
+ msg = (
+ f"Invalid value for enum variable {key!r}: {val!r}. "
+ f"Valid values are: {vals}"
+ )
+ raise SCons.Errors.UserError(msg) from None
+
+
+# lint: W0622: Redefining built-in 'help' (redefined-builtin)
+# lint: W0622: Redefining built-in 'map' (redefined-builtin)
+def EnumVariable(
+ key,
+ help: str,
+ default: str,
+ allowed_values: List[str],
+ map: Optional[dict] = None,
+ ignorecase: int = 0,
+) -> Tuple[str, str, str, Callable, Callable]:
"""Return a tuple describing an enumaration SCons Variable.
- The input parameters describe an option with only certain values
- allowed. Returns A tuple including an appropriate converter and
- validator. The result is usable as input to :meth:`Add`.
-
- *key* and *default* are passed directly on to :meth:`Add`.
-
- *help* is the descriptive part of the help text,
- and will have the allowed values automatically appended.
+ The input parameters describe a variable with only predefined values
+ allowed. The value of *ignorecase* defines the behavior of the
+ validator and converter: if ``0``, the validator/converter are
+ case-sensitive; if ``1``, the validator/converter are case-insensitive;
+ if ``2``, the validator/converter are case-insensitive and the
+ converted value will always be lower-case.
+
+ Arguments:
+ key: variable name, passed directly through to the return tuple.
+ default: default values, passed directly through to the return tuple.
+ help: descriptive part of the help text,
+ will have the allowed values automatically appended.
+ allowed_values: list of the allowed values for this variable.
+ map: optional dictionary which may be used for converting the
+ input value into canonical values (e.g. for aliases).
+ ignorecase: defines the behavior of the validator and converter.
+ validator: callback function to test whether the value is in the
+ list of allowed values.
+ converter: callback function to convert input values according to
+ the given *map*-dictionary. Unmapped input values are returned
+ unchanged.
+
+ Returns:
+ A tuple including an appropriate converter and validator.
+ The result is usable as input to :meth:`~SCons.Variables.Variables.Add`.
+ and :meth:`~SCons.Variables.Variables.AddVariables`.
+ """
+ # these are all inner functions so they can access EnumVariable locals.
+ def validator_rcase(key, val, env):
+ """Case-respecting validator."""
+ return _validator(key, val, env, allowed_values)
- *allowed_values* is a list of strings, which are the allowed values
- for this option.
+ def validator_icase(key, val, env):
+ """Case-ignoring validator."""
+ return _validator(key, val.lower(), env, allowed_values)
- The *map*-dictionary may be used for converting the input value
- into canonical values (e.g. for aliases).
+ def converter_rcase(val):
+ """Case-respecting converter."""
+ return map.get(val, val)
- The value of *ignorecase* defines the behaviour of the validator:
+ def converter_icase(val):
+ """Case-ignoring converter."""
+ return map.get(val.lower(), val)
- * 0: the validator/converter are case-sensitive.
- * 1: the validator/converter are case-insensitive.
- * 2: the validator/converter is case-insensitive and the
- converted value will always be lower-case.
+ def converter_lcase(val):
+ """Case-lowering converter."""
+ return map.get(val.lower(), val).lower()
- The *validator* tests whether the value is in the list of allowed values.
- The *converter* converts input values according to the given
- *map*-dictionary (unmapped input values are returned unchanged).
- """
+ if map is None:
+ map = {}
+ help = f"{help} ({'|'.join(allowed_values)})"
- help = '%s (%s)' % (help, '|'.join(allowed_values))
# define validator
if ignorecase:
- validator = lambda key, val, env: \
- _validator(key, val.lower(), env, allowed_values)
+ validator = validator_icase
else:
- validator = lambda key, val, env: \
- _validator(key, val, env, allowed_values)
+ validator = validator_rcase
+
# define converter
if ignorecase == 2:
- converter = lambda val: map.get(val.lower(), val).lower()
+ converter = converter_lcase
elif ignorecase == 1:
- converter = lambda val: map.get(val.lower(), val)
+ converter = converter_icase
else:
- converter = lambda val: map.get(val, val)
- return (key, help, default, validator, converter)
+ converter = converter_rcase
+
+ return key, help, default, validator, converter
# Local Variables:
# tab-width:4