Coverage for pyTooling/CLIAbstraction/ValuedFlagList.py: 97%

52 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""" 

33List of valued flags are argument lists where each item is a valued flag (See 

34:class:`~pyTooling.CLIAbstraction.ValuedFlag.ValuedFlag`). 

35 

36Each list item gets translated into a ``***ValuedFlag``, with the same flag name, but differing values. 

37 

38.. seealso:: 

39 

40 :mod:`~pyTooling.CLIAbstraction.ValuedFlag` 

41 |rarr| For single valued flags. 

42 :class:`~pyTooling.CLIAbstraction.Argument.StringListArgument` 

43 |rarr| For a list of strings. 

44 :class:`~pyTooling.CLIAbstraction.Argument.PathListArgument` 

45 |rarr| For a list of paths. 

46""" 

47from typing import Union, Iterable, cast, Any 

48from pyTooling.Decorators import export 

49from pyTooling.MetaClasses import abstractclass 

50from pyTooling.Common import getFullyQualifiedName 

51from pyTooling.CLIAbstraction.Argument import ValueT, NamedAndValuedArgument 

52 

53 

54@export 

55@abstractclass 

56class ValuedFlagList(NamedAndValuedArgument[str], pattern="{0}={1}"): 

57 """ 

58 Class and base-class for all ValuedFlagList classes, which represents a list of valued flags. 

59 

60 Each list element gets translated to a valued flag using the pattern for formatting. 

61 See :mod:`~pyTooling.CLIAbstraction.ValuedFlag` for more details on valued flags. 

62 

63 **Example:** 

64 

65 * ``file=file1.log file=file2.log`` 

66 """ 

67 

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

69 """ 

70 This method is called when a class is derived. 

71 

72 :param args: Any positional arguments. 

73 :param pattern: Optional, this pattern is used to format an argument. |br| 

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

75 :param kwargs: Any keyword argument. 

76 """ 

77 kwargs["pattern"] = pattern 

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

79 

80 def __init__(self, value: list[ValueT]) -> None: 

81 """ 

82 Initialize the argument with a list of values, each of which is rendered as its own command line element. 

83 

84 :param value: Values of the argument. 

85 """ 

86 super().__init__(list(value)) 

87 

88 @property 

89 def Value(self) -> list[str]: 

90 """ 

91 Property to access the internal list of values (:attr:`_value`). 

92 

93 .. note:: On assignment, the list object is not replaced, but cleared and then reused by adding the given elements 

94 of the iterable. 

95 

96 :returns: Internal list of values. 

97 :raises TypeError: If an assigned iterable contains elements which are not of type string. 

98 """ 

99 return self._value 

100 

101 @Value.setter 

102 def Value(self, values: Iterable[str]) -> None: 

103 innerList = cast(list[str], self._value) 

104 innerList.clear() 

105 for value in values: 

106 if not isinstance(value, str): 

107 ex = TypeError(f"Value contains elements which are not of type 'str'.") 

108 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.") 

109 raise ex 

110 innerList.append(value) 

111 

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

113 """ 

114 Render this argument as a list of command line elements, one per value. 

115 

116 :returns: The rendered command line elements. 

117 :raises ValueError: If the argument has no name. 

118 """ 

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

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

121 

122 return [self._pattern.format(self._name, value) for value in self._value] 

123 

124 def __str__(self) -> str: 

125 """ 

126 Return a string representation of this argument instance. 

127 

128 :returns: Space separated sequence of arguments formatted and each enclosed in double quotes. 

129 """ 

130 return " ".join([f"\"{value}\"" for value in self.AsArgument()]) 

131 

132 def __repr__(self) -> str: 

133 """ 

134 Return a string representation of this argument instance. 

135 

136 :returns: Comma separated sequence of arguments formatted and each enclosed in double quotes. 

137 """ 

138 return ", ".join([f"\"{value}\"" for value in self.AsArgument()]) 

139 

140 

141@export 

142@abstractclass 

143class ShortValuedFlagList(ValuedFlagList, pattern="-{0}={1}"): 

144 """ 

145 Represents a :py:class:`ValuedFlagArgument` with a single dash. 

146 

147 **Example:** 

148 

149 * ``-file=file1.log -file=file2.log`` 

150 """ 

151 

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

153 """ 

154 This method is called when a class is derived. 

155 

156 :param args: Any positional arguments. 

157 :param pattern: Optional, this pattern is used to format an argument. |br| 

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

159 :param kwargs: Any keyword argument. 

160 """ 

161 kwargs["pattern"] = pattern 

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

163 

164 

165@export 

166@abstractclass 

167class LongValuedFlagList(ValuedFlagList, pattern="--{0}={1}"): 

168 """ 

169 Represents a :py:class:`ValuedFlagArgument` with a double dash. 

170 

171 **Example:** 

172 

173 * ``--file=file1.log --file=file2.log`` 

174 """ 

175 

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

177 """ 

178 This method is called when a class is derived. 

179 

180 :param args: Any positional arguments. 

181 :param pattern: Optional, this pattern is used to format an argument. |br| 

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

183 :param kwargs: Any keyword argument. 

184 """ 

185 kwargs["pattern"] = pattern 

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

187 

188 

189@export 

190@abstractclass 

191class WindowsValuedFlagList(ValuedFlagList, pattern="/{0}:{1}"): 

192 """ 

193 Represents a :py:class:`ValuedFlagArgument` with a single slash. 

194 

195 **Example:** 

196 

197 * ``/file:file1.log /file:file2.log`` 

198 """ 

199 

200 # TODO: Is it possible to copy the doc-string from super? 

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

202 """ 

203 This method is called when a class is derived. 

204 

205 :param args: Any positional arguments. 

206 :param pattern: Optional, this pattern is used to format an argument. |br| 

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

208 :param kwargs: Any keyword argument. 

209 """ 

210 kwargs["pattern"] = pattern 

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