Coverage for pyTooling/CLIAbstraction/BooleanFlag.py: 97%
59 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-25 22:22 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-25 22:22 +0000
1# ==================================================================================================================== #
2# _____ _ _ ____ _ ___ _ _ _ _ _ #
3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / ___| | |_ _| / \ | |__ ___| |_ _ __ __ _ ___| |_(_) ___ _ __ #
4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` || | | | | | / _ \ | '_ \/ __| __| '__/ _` |/ __| __| |/ _ \| '_ \ #
5# | |_) | |_| || | (_) | (_) | | | | | | (_| || |___| |___ | | / ___ \| |_) \__ \ |_| | | (_| | (__| |_| | (_) | | | | #
6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)____|_____|___/_/ \_\_.__/|___/\__|_| \__,_|\___|\__|_|\___/|_| |_| #
7# |_| |___/ |___/ #
8# ==================================================================================================================== #
9# Authors: #
10# Patrick Lehmann #
11# #
12# License: #
13# ==================================================================================================================== #
14# Copyright 2017-2025 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"""
33Boolean flags are arguments with a name and different pattern for a positive (``True``) and negative (``False``) value.
35.. seealso::
37 * For simple flags. |br|
38 |rarr| :mod:`~pyTooling.CLIAbstraction.Flag`
39 * For flags with a value. |br|
40 |rarr| :mod:`~pyTooling.CLIAbstraction.ValuedFlag`
41 * For flags that have an optional value. |br|
42 |rarr| :mod:`~pyTooling.CLIAbstraction.NamedOptionalValuedFlag`
43"""
44from typing import ClassVar, Union, Iterable, Any, Optional as Nullable
46try:
47 from pyTooling.Decorators import export
48 from pyTooling.CLIAbstraction.Argument import NamedArgument, ValuedArgument
49except (ImportError, ModuleNotFoundError): # pragma: no cover
50 print("[pyTooling.Versioning] Could not import from 'pyTooling.*'!")
52 try:
53 from Decorators import export
54 from CLIAbstraction.Argument import NamedArgument, ValuedArgument
55 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover
56 print("[pyTooling.Versioning] Could not import directly!")
57 raise ex
60@export
61class BooleanFlag(NamedArgument, ValuedArgument):
62 """
63 Class and base-class for all BooleanFlag classes, which represents a flag argument with different pattern for an
64 enabled/positive (``True``) or disabled/negative (``False``) state.
66 When deriving a subclass from an abstract BooleanFlag class, the parameters ``pattern`` and ``falsePattern`` are
67 expected.
69 **Example:**
71 * True: ``with-checks``
72 * False: ``without-checks``
73 """
75 _falsePattern: ClassVar[str]
77 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "with-{0}", falsePattern: str = "without-{0}", **kwargs: Any):
78 """This method is called when a class is derived.
80 :param args: Any positional arguments.
81 :param pattern: This pattern is used to format an argument when the value is ``True``.
82 :param falsePattern: This pattern is used to format an argument when the value is ``False``.
83 :param kwargs: Any keyword argument.
84 """
85 kwargs["name"] = name
86 kwargs["pattern"] = pattern
87 super().__init_subclass__(*args, **kwargs)
88 del kwargs["name"]
89 del kwargs["pattern"]
90 ValuedArgument.__init_subclass__(*args, **kwargs)
92 cls._falsePattern = falsePattern
94 def __new__(cls, *args: Any, **kwargs: Any):
95 if cls is BooleanFlag:
96 raise TypeError(f"Class '{cls.__name__}' is abstract.")
97 return super().__new__(cls, *args, **kwargs)
99 def __init__(self, value: bool) -> None:
100 """Initializes a BooleanFlag instance.
102 :param value: Initial value set for this argument instance.
103 """
104 ValuedArgument.__init__(self, value)
106 def AsArgument(self) -> Union[str, Iterable[str]]:
107 """Convert this argument instance to a string representation with proper escaping using the matching pattern based
108 on the internal name and value.
110 :return: Formatted argument.
111 :raises ValueError: If internal name is None.
112 """
113 if self._name is None: 113 ↛ 114line 113 didn't jump to line 114 because the condition on line 113 was never true
114 raise ValueError(f"Internal value '_name' is None.")
116 pattern = self._pattern if self._value is True else self._falsePattern
117 return pattern.format(self._name)
120@export
121class ShortBooleanFlag(BooleanFlag, pattern="-with-{0}", falsePattern="-without-{0}"):
122 """Represents a :py:class:`BooleanFlag` with a single dash.
124 **Example:**
126 * True: ``-with-checks``
127 * False: ``-without-checks``
128 """
130 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "-with-{0}", falsePattern: str = "-without-{0}", **kwargs: Any):
131 """This method is called when a class is derived.
133 :param args: Any positional arguments.
134 :param pattern: This pattern is used to format an argument when the value is ``True``.
135 :param falsePattern: This pattern is used to format an argument when the value is ``False``.
136 :param kwargs: Any keyword argument.
137 """
138 kwargs["name"] = name
139 kwargs["pattern"] = pattern
140 kwargs["falsePattern"] = falsePattern
141 super().__init_subclass__(*args, **kwargs)
143 def __new__(cls, *args: Any, **kwargs: Any):
144 if cls is ShortBooleanFlag:
145 raise TypeError(f"Class '{cls.__name__}' is abstract.")
146 return super().__new__(cls, *args, **kwargs)
149@export
150class LongBooleanFlag(BooleanFlag, pattern="--with-{0}", falsePattern="--without-{0}"):
151 """Represents a :py:class:`BooleanFlag` with a double dash.
153 **Example:**
155 * True: ``--with-checks``
156 * False: ``--without-checks``
157 """
159 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "--with-{0}", falsePattern: str = "--without-{0}", **kwargs: Any):
160 """This method is called when a class is derived.
162 :param args: Any positional arguments.
163 :param pattern: This pattern is used to format an argument when the value is ``True``.
164 :param falsePattern: This pattern is used to format an argument when the value is ``False``.
165 :param kwargs: Any keyword argument.
166 """
167 kwargs["name"] = name
168 kwargs["pattern"] = pattern
169 kwargs["falsePattern"] = falsePattern
170 super().__init_subclass__(*args, **kwargs)
172 def __new__(cls, *args: Any, **kwargs: Any):
173 if cls is LongBooleanFlag:
174 raise TypeError(f"Class '{cls.__name__}' is abstract.")
175 return super().__new__(cls, *args, **kwargs)
178@export
179class WindowsBooleanFlag(BooleanFlag, pattern="/with-{0}", falsePattern="/without-{0}"):
180 """Represents a :py:class:`BooleanFlag` with a slash.
182 **Example:**
184 * True: ``/with-checks``
185 * False: ``/without-checks``
186 """
188 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "/with-{0}", falsePattern: str = "/without-{0}", **kwargs: Any):
189 """This method is called when a class is derived.
191 :param args: Any positional arguments.
192 :param pattern: This pattern is used to format an argument when the value is ``True``.
193 :param falsePattern: This pattern is used to format an argument when the value is ``False``.
194 :param kwargs: Any keyword argument.
195 """
196 kwargs["name"] = name
197 kwargs["pattern"] = pattern
198 kwargs["falsePattern"] = falsePattern
199 super().__init_subclass__(*args, **kwargs)
201 def __new__(cls, *args: Any, **kwargs: Any):
202 if cls is WindowsBooleanFlag:
203 raise TypeError(f"Class '{cls.__name__}' is abstract.")
204 return super().__new__(cls, *args, **kwargs)