|
38 | 38 | ignorecase=2,
|
39 | 39 | )
|
40 | 40 | )
|
41 |
| - ... |
| 41 | + env = Environment(variables=opts) |
42 | 42 | if env['debug'] == 'full':
|
43 |
| - ... |
| 43 | + ... |
44 | 44 | """
|
45 | 45 |
|
46 |
| -from typing import Tuple, Callable |
| 46 | +from typing import Callable, List, Optional, Tuple |
47 | 47 |
|
48 | 48 | import SCons.Errors
|
49 | 49 |
|
50 | 50 | __all__ = ['EnumVariable',]
|
51 | 51 |
|
52 | 52 |
|
53 | 53 | def _validator(key, val, env, vals) -> None:
|
54 |
| - if val not in vals: |
55 |
| - raise SCons.Errors.UserError( |
56 |
| - 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals)) |
57 |
| - |
| 54 | + """Validate that val is in vals. |
58 | 55 |
|
59 |
| -def EnumVariable(key, help, default, allowed_values, map={}, ignorecase: int=0) -> Tuple[str, str, str, Callable, Callable]: |
| 56 | + Usable as the base for :class:`EnumVariable` validators. |
| 57 | + """ |
| 58 | + if val not in vals: |
| 59 | + msg = ( |
| 60 | + f"Invalid value for enum variable {key!r}: {val!r}. " |
| 61 | + f"Valid values are: {vals}" |
| 62 | + ) |
| 63 | + raise SCons.Errors.UserError(msg) from None |
| 64 | + |
| 65 | + |
| 66 | +# lint: W0622: Redefining built-in 'help' (redefined-builtin) |
| 67 | +# lint: W0622: Redefining built-in 'map' (redefined-builtin) |
| 68 | +def EnumVariable( |
| 69 | + key, |
| 70 | + help: str, |
| 71 | + default: str, |
| 72 | + allowed_values: List[str], |
| 73 | + map: Optional[dict] = None, |
| 74 | + ignorecase: int = 0, |
| 75 | +) -> Tuple[str, str, str, Callable, Callable]: |
60 | 76 | """Return a tuple describing an enumaration SCons Variable.
|
61 | 77 |
|
62 |
| - The input parameters describe an option with only certain values |
63 |
| - allowed. Returns A tuple including an appropriate converter and |
64 |
| - validator. The result is usable as input to :meth:`Add`. |
65 |
| -
|
66 |
| - *key* and *default* are passed directly on to :meth:`Add`. |
67 |
| -
|
68 |
| - *help* is the descriptive part of the help text, |
69 |
| - and will have the allowed values automatically appended. |
| 78 | + The input parameters describe a variable with only predefined values |
| 79 | + allowed. The value of *ignorecase* defines the behavior of the |
| 80 | + validator and converter: if ``0``, the validator/converter are |
| 81 | + case-sensitive; if ``1``, the validator/converter are case-insensitive; |
| 82 | + if ``2``, the validator/converter are case-insensitive and the |
| 83 | + converted value will always be lower-case. |
| 84 | +
|
| 85 | + Arguments: |
| 86 | + key: variable name, passed directly through to the return tuple. |
| 87 | + default: default values, passed directly through to the return tuple. |
| 88 | + help: descriptive part of the help text, |
| 89 | + will have the allowed values automatically appended. |
| 90 | + allowed_values: list of the allowed values for this variable. |
| 91 | + map: optional dictionary which may be used for converting the |
| 92 | + input value into canonical values (e.g. for aliases). |
| 93 | + ignorecase: defines the behavior of the validator and converter. |
| 94 | + validator: callback function to test whether the value is in the |
| 95 | + list of allowed values. |
| 96 | + converter: callback function to convert input values according to |
| 97 | + the given *map*-dictionary. Unmapped input values are returned |
| 98 | + unchanged. |
| 99 | +
|
| 100 | + Returns: |
| 101 | + A tuple including an appropriate converter and validator. |
| 102 | + The result is usable as input to :meth:`~SCons.Variables.Variables.Add`. |
| 103 | + and :meth:`~SCons.Variables.Variables.AddVariables`. |
| 104 | + """ |
| 105 | + # these are all inner functions so they can access EnumVariable locals. |
| 106 | + def validator_rcase(key, val, env): |
| 107 | + """Case-respecting validator.""" |
| 108 | + return _validator(key, val, env, allowed_values) |
70 | 109 |
|
71 |
| - *allowed_values* is a list of strings, which are the allowed values |
72 |
| - for this option. |
| 110 | + def validator_icase(key, val, env): |
| 111 | + """Case-ignoring validator.""" |
| 112 | + return _validator(key, val.lower(), env, allowed_values) |
73 | 113 |
|
74 |
| - The *map*-dictionary may be used for converting the input value |
75 |
| - into canonical values (e.g. for aliases). |
| 114 | + def converter_rcase(val): |
| 115 | + """Case-respecting converter.""" |
| 116 | + return map.get(val, val) |
76 | 117 |
|
77 |
| - The value of *ignorecase* defines the behaviour of the validator: |
| 118 | + def converter_icase(val): |
| 119 | + """Case-ignoring converter.""" |
| 120 | + return map.get(val.lower(), val) |
78 | 121 |
|
79 |
| - * 0: the validator/converter are case-sensitive. |
80 |
| - * 1: the validator/converter are case-insensitive. |
81 |
| - * 2: the validator/converter is case-insensitive and the |
82 |
| - converted value will always be lower-case. |
| 122 | + def converter_lcase(val): |
| 123 | + """Case-lowering converter.""" |
| 124 | + return map.get(val.lower(), val).lower() |
83 | 125 |
|
84 |
| - The *validator* tests whether the value is in the list of allowed values. |
85 |
| - The *converter* converts input values according to the given |
86 |
| - *map*-dictionary (unmapped input values are returned unchanged). |
87 |
| - """ |
| 126 | + if map is None: |
| 127 | + map = {} |
| 128 | + help = f"{help} ({'|'.join(allowed_values)})" |
88 | 129 |
|
89 |
| - help = '%s (%s)' % (help, '|'.join(allowed_values)) |
90 | 130 | # define validator
|
91 | 131 | if ignorecase:
|
92 |
| - validator = lambda key, val, env: \ |
93 |
| - _validator(key, val.lower(), env, allowed_values) |
| 132 | + validator = validator_icase |
94 | 133 | else:
|
95 |
| - validator = lambda key, val, env: \ |
96 |
| - _validator(key, val, env, allowed_values) |
| 134 | + validator = validator_rcase |
| 135 | + |
97 | 136 | # define converter
|
98 | 137 | if ignorecase == 2:
|
99 |
| - converter = lambda val: map.get(val.lower(), val).lower() |
| 138 | + converter = converter_lcase |
100 | 139 | elif ignorecase == 1:
|
101 |
| - converter = lambda val: map.get(val.lower(), val) |
| 140 | + converter = converter_icase |
102 | 141 | else:
|
103 |
| - converter = lambda val: map.get(val, val) |
104 |
| - return (key, help, default, validator, converter) |
| 142 | + converter = converter_rcase |
| 143 | + |
| 144 | + return key, help, default, validator, converter |
105 | 145 |
|
106 | 146 | # Local Variables:
|
107 | 147 | # tab-width:4
|
|
0 commit comments