Coverage for pyTooling/CLIAbstraction/OptionalValuedFlag.py: 96%

48 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-11 23:59 +0000

1# ==================================================================================================================== # 

2# _____ _ _ ____ _ ___ _ _ _ _ _ # 

3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / ___| | |_ _| / \ | |__ ___| |_ _ __ __ _ ___| |_(_) ___ _ __ # 

4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` || | | | | | / _ \ | '_ \/ __| __| '__/ _` |/ __| __| |/ _ \| '_ \ # 

5# | |_) | |_| || | (_) | (_) | | | | | | (_| || |___| |___ | | / ___ \| |_) \__ \ |_| | | (_| | (__| |_| | (_) | | | | # 

6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)____|_____|___/_/ \_\_.__/|___/\__|_| \__,_|\___|\__|_|\___/|_| |_| # 

7# |_| |___/ |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2017-2026 Patrick Lehmann - Bötzingen, Germany # 

15# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture # 

16# # 

17# Licensed under the Apache License, Version 2.0 (the "License"); # 

18# you may not use this file except in compliance with the License. # 

19# You may obtain a copy of the License at # 

20# # 

21# http://www.apache.org/licenses/LICENSE-2.0 # 

22# # 

23# Unless required by applicable law or agreed to in writing, software # 

24# distributed under the License is distributed on an "AS IS" BASIS, # 

25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

26# See the License for the specific language governing permissions and # 

27# limitations under the License. # 

28# # 

29# SPDX-License-Identifier: Apache-2.0 # 

30# ==================================================================================================================== # 

31# 

32""" 

33 

34Command line arguments with an optional value, like ``--width`` or ``--width=100``. 

35 

36The argument renders one of two patterns: the one with a value when a value was assigned, and the one without a value 

37otherwise - which is why an optional-valued flag carries two format strings instead of one. 

38 

39""" 

40from typing import ClassVar, Union, Iterable, Any, Optional as Nullable 

41 

42from pyTooling.Decorators import export 

43from pyTooling.MetaClasses import abstractclass 

44from pyTooling.CLIAbstraction.Argument import NamedAndValuedArgument 

45 

46 

47@export 

48@abstractclass 

49class OptionalValuedFlag(NamedAndValuedArgument[str], pattern="{0"): 

50 """ 

51 Class and base-class for all OptionalValuedFlag classes, which represents a flag argument with data. 

52 

53 An optional valued flag is a flag name followed by a value. The default delimiter sign is equal (``=``). Name and 

54 value are passed as one argument to the executable even if the delimiter sign is a whitespace character. If the value 

55 is None, no delimiter sign and value is passed. 

56 

57 Example: ``width=100`` 

58 """ 

59 _patternWithValue: ClassVar[str] #: Format string used when the flag has a value; :attr:`_pattern` is used without one. 

60 

61 def __init_subclass__(cls, *args: Any, pattern: str = "{0}", patternWithValue: str = "{0}={1}", **kwargs: Any) -> None: 

62 """ 

63 This method is called when a class is derived. 

64 

65 :param args: Any positional arguments. 

66 :param pattern: Optional, this pattern is used to format an argument without a value. |br| 

67 Default: ``"{0}"``. 

68 :param patternWithValue: Optional, this pattern is used to format an argument with a value. |br| 

69 Default: ``"{0}={1}"``. 

70 :param kwargs: Any keyword argument. 

71 """ 

72 kwargs["pattern"] = pattern 

73 super().__init_subclass__(*args, **kwargs) 

74 cls._patternWithValue = patternWithValue 

75 

76 def __init__(self, value: Nullable[str] = None) -> None: 

77 """ 

78 Initialize the flag, optionally with a value. 

79 

80 :param value: Optional, value of the flag, or ``None`` to render the flag without a value. 

81 """ 

82 self._value = value 

83 

84 @property 

85 def Value(self) -> Nullable[str]: 

86 """ 

87 Property to access the internal value (:attr:`_value`). 

88 

89 :returns: Internal value, or ``None`` if the flag is used without a value. 

90 """ 

91 return self._value 

92 

93 @Value.setter 

94 def Value(self, value: Nullable[str]) -> None: 

95 self._value = value 

96 

97 def AsArgument(self) -> Union[str, Iterable[str]]: 

98 """ 

99 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

100 the internal name and optional value. 

101 

102 :returns: Formatted argument. 

103 :raises ValueError: If internal name is None. 

104 """ 

105 if self._name is None: 105 ↛ 106line 105 didn't jump to line 106 because the condition on line 105 was never true

106 raise ValueError(f"Internal value '_name' is None.") 

107 

108 pattern = self._pattern if self._value is None else self._patternWithValue 

109 return pattern.format(self._name, self._value) 

110 

111 def __str__(self) -> str: 

112 """ 

113 Return the argument as a quoted string, ready to be pasted into a shell. 

114 

115 :returns: The rendered argument, in double quotes. 

116 """ 

117 return f"\"{self.AsArgument()}\"" 

118 

119 __repr__ = __str__ 

120 

121 

122@export 

123@abstractclass 

124class ShortOptionalValuedFlag(OptionalValuedFlag, pattern="-{0}", patternWithValue="-{0}={1}"): 

125 """ 

126 Represents a :py:class:`OptionalValuedFlag` with a single dash. 

127 

128 Example: ``-optimizer=on`` 

129 """ 

130 def __init_subclass__(cls, *args: Any, pattern: str = "-{0}", patternWithValue: str = "-{0}={1}", **kwargs: Any) -> None: 

131 """ 

132 This method is called when a class is derived. 

133 

134 :param args: Any positional arguments. 

135 :param pattern: Optional, this pattern is used to format an argument without a value. |br| 

136 Default: ``"-{0}"``. 

137 :param patternWithValue: Optional, this pattern is used to format an argument with a value. |br| 

138 Default: ``"-{0}={1}"``. 

139 :param kwargs: Any keyword argument. 

140 """ 

141 kwargs["pattern"] = pattern 

142 kwargs["patternWithValue"] = patternWithValue 

143 super().__init_subclass__(*args, **kwargs) 

144 

145 

146@export 

147@abstractclass 

148class LongOptionalValuedFlag(OptionalValuedFlag, pattern="--{0}", patternWithValue="--{0}={1}"): 

149 """ 

150 Represents a :py:class:`OptionalValuedFlag` with a double dash. 

151 

152 Example: ``--optimizer=on`` 

153 """ 

154 def __init_subclass__(cls, *args: Any, pattern: str = "--{0}", patternWithValue: str = "--{0}={1}", **kwargs: Any) -> None: 

155 """ 

156 This method is called when a class is derived. 

157 

158 :param args: Any positional arguments. 

159 :param pattern: Optional, this pattern is used to format an argument without a value. |br| 

160 Default: ``"--{0}"``. 

161 :param patternWithValue: Optional, this pattern is used to format an argument with a value. |br| 

162 Default: ``"--{0}={1}"``. 

163 :param kwargs: Any keyword argument. 

164 """ 

165 kwargs["pattern"] = pattern 

166 kwargs["patternWithValue"] = patternWithValue 

167 super().__init_subclass__(*args, **kwargs) 

168 

169 

170@export 

171@abstractclass 

172class WindowsOptionalValuedFlag(OptionalValuedFlag, pattern="/{0}", patternWithValue="/{0}:{1}"): 

173 """ 

174 Represents a :py:class:`OptionalValuedFlag` with a single slash. 

175 

176 Example: ``/optimizer:on`` 

177 """ 

178 def __init_subclass__(cls, *args: Any, pattern: str = "/{0}", patternWithValue: str = "/{0}:{1}", **kwargs: Any) -> None: 

179 """ 

180 This method is called when a class is derived. 

181 

182 :param args: Any positional arguments. 

183 :param pattern: Optional, this pattern is used to format an argument without a value. |br| 

184 Default: ``"/{0}"``. 

185 :param patternWithValue: Optional, this pattern is used to format an argument with a value. |br| 

186 Default: ``"/{0}:{1}"``. 

187 :param kwargs: Any keyword argument. 

188 """ 

189 kwargs["pattern"] = pattern 

190 kwargs["patternWithValue"] = patternWithValue 

191 super().__init_subclass__(*args, **kwargs)