Coverage for pyTooling / CLIAbstraction / ValuedFlag.py: 100%

39 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-07 17:18 +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""" 

33Valued flags are arguments with a name and an always present value. 

34 

35The usual delimiter sign between name and value is an equal sign (``=``). 

36 

37.. seealso:: 

38 

39 * For simple flags. |br| 

40 |rarr| :mod:`~pyTooling.CLIAbstraction.Flag` 

41 * For flags with different pattern based on the boolean value itself. |br| 

42 |rarr| :mod:`~pyTooling.CLIAbstraction.BooleanFlag` 

43 * For flags that have an optional value. |br| 

44 |rarr| :mod:`~pyTooling.CLIAbstraction.NamedOptionalValuedFlag` 

45 * For list of valued flags. |br| 

46 |rarr| :mod:`~pyTooling.CLIAbstraction.ValuedFlagList` 

47""" 

48from typing import Any, Self 

49 

50from pyTooling.Decorators import export 

51from pyTooling.CLIAbstraction.Argument import NamedAndValuedArgument 

52 

53 

54@export 

55class ValuedFlag(NamedAndValuedArgument, pattern="{0}={1}"): 

56 """ 

57 Class and base-class for all ValuedFlag classes, which represents a flag argument with value. 

58 

59 A valued flag is a flag name followed by a value. The default delimiter sign is equal (``=``). Name and value are 

60 passed as one argument to the executable even if the delimiter sign is a whitespace character. 

61 

62 **Example:** 

63 

64 * ``width=100`` 

65 """ 

66 

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

68 """ 

69 This method is called when a class is derived. 

70 

71 :param args: Any positional arguments. 

72 :param pattern: This pattern is used to format an argument. |br| 

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

74 :param kwargs: Any keyword argument. 

75 """ 

76 kwargs["pattern"] = pattern 

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

78 

79 # TODO: the whole class should be marked as abstract 

80 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code 

81 def __new__(cls, *args: Any, **kwargs: Any) -> Self: 

82 """ 

83 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error. 

84 

85 :param args: Any positional arguments. 

86 :param kwargs: Any keyword arguments. 

87 :raises TypeError: When this class gets directly instantiated without being derived to a subclass. 

88 """ 

89 if cls is ValuedFlag: 

90 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

91 return super().__new__(cls, *args, **kwargs) 

92 

93 

94@export 

95class ShortValuedFlag(ValuedFlag, pattern="-{0}={1}"): 

96 """ 

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

98 

99 **Example:** 

100 

101 * ``-optimizer=on`` 

102 """ 

103 

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

105 """ 

106 This method is called when a class is derived. 

107 

108 :param args: Any positional arguments. 

109 :param pattern: This pattern is used to format an argument. |br| 

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

111 :param kwargs: Any keyword argument. 

112 """ 

113 kwargs["pattern"] = pattern 

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

115 

116 # TODO: the whole class should be marked as abstract 

117 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code 

118 def __new__(cls, *args: Any, **kwargs: Any) -> Self: 

119 """ 

120 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error. 

121 

122 :param args: Any positional arguments. 

123 :param kwargs: Any keyword arguments. 

124 :raises TypeError: When this class gets directly instantiated without being derived to a subclass. 

125 """ 

126 if cls is ShortValuedFlag: 

127 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

128 return super().__new__(cls, *args, **kwargs) 

129 

130 

131@export 

132class LongValuedFlag(ValuedFlag, pattern="--{0}={1}"): 

133 """ 

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

135 

136 **Example:** 

137 

138 * ``--optimizer=on`` 

139 """ 

140 

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

142 """ 

143 This method is called when a class is derived. 

144 

145 :param args: Any positional arguments. 

146 :param pattern: This pattern is used to format an argument. |br| 

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

148 :param kwargs: Any keyword argument. 

149 """ 

150 kwargs["pattern"] = pattern 

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

152 

153 # TODO: the whole class should be marked as abstract 

154 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code 

155 def __new__(cls, *args: Any, **kwargs: Any) -> Self: 

156 """ 

157 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error. 

158 

159 :param args: Any positional arguments. 

160 :param kwargs: Any keyword arguments. 

161 :raises TypeError: When this class gets directly instantiated without being derived to a subclass. 

162 """ 

163 if cls is LongValuedFlag: 

164 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

165 return super().__new__(cls, *args, **kwargs) 

166 

167 

168@export 

169class WindowsValuedFlag(ValuedFlag, pattern="/{0}:{1}"): 

170 """ 

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

172 

173 **Example:** 

174 

175 * ``/optimizer:on`` 

176 """ 

177 

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

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

180 """ 

181 This method is called when a class is derived. 

182 

183 :param args: Any positional arguments. 

184 :param pattern: This pattern is used to format an argument. |br| 

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

186 :param kwargs: Any keyword argument. 

187 """ 

188 kwargs["pattern"] = pattern 

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

190 

191 # TODO: the whole class should be marked as abstract 

192 # TODO: a decorator should solve the issue and overwrite the __new__ method with that code 

193 def __new__(cls, *args: Any, **kwargs: Any) -> Self: 

194 """ 

195 Check if this class was directly instantiated without being derived to a subclass. If so, raise an error. 

196 

197 :param args: Any positional arguments. 

198 :param kwargs: Any keyword arguments. 

199 :raises TypeError: When this class gets directly instantiated without being derived to a subclass. 

200 """ 

201 if cls is WindowsValuedFlag: 

202 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

203 return super().__new__(cls, *args, **kwargs)