pythonic-fp-booleans 4.3.0__tar.gz → 5.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonic-fp-booleans
3
- Version: 4.3.0
4
- Summary: True Booleans which are subtypable.
3
+ Version: 5.0.0
4
+ Summary: Boolean like classes.
5
5
  Keywords: booleans,subtypable
6
6
  Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
7
7
  Requires-Python: >=3.14
@@ -23,7 +23,7 @@ Project-URL: Source, https://github.com/grscheller/pythonic-fp-booleans
23
23
 
24
24
  # Pythonic FP - Booleans
25
25
 
26
- Subtypable Boolean like classes.
26
+ Boolean like classes.
27
27
 
28
28
  PyPI project
29
29
  [pythonic-fp-booleans](https://pypi.org/project/pythonic-fp-booleans).
@@ -1,6 +1,6 @@
1
1
  # Pythonic FP - Booleans
2
2
 
3
- Subtypable Boolean like classes.
3
+ Boolean like classes.
4
4
 
5
5
  PyPI project
6
6
  [pythonic-fp-booleans](https://pypi.org/project/pythonic-fp-booleans).
@@ -4,10 +4,10 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "pythonic-fp-booleans"
7
- version = "4.3.0"
8
- description = "True Booleans which are subtypable."
7
+ version = "5.0.0"
8
+ description = "Boolean like classes."
9
9
  readme = "README.md"
10
- requires-python = ">=3.14" # floor: PEP 649/749 deferred annotations — class-level self-reference (SBool in its own ClassVar annotation) NameErrors on <3.14
10
+ requires-python = ">=3.14" # floor: PEP 649/749 deferred annotations — class-level self-reference NameErrors on <3.14
11
11
  authors = [
12
12
  { name = "Geoffrey R. Scheller", email = "geoffrey@scheller.com" },
13
13
  ]
@@ -51,6 +51,11 @@ name = "pythonic_fp.booleans"
51
51
  exclude = [
52
52
  "docs/",
53
53
  "tests/",
54
+ "**/.mypy_cache/",
55
+ "**/.ruff_cache/",
56
+ "**/.pytest_cache/",
57
+ "**/__pycache__/",
58
+ "**/.dmypy.json",
54
59
  ]
55
60
 
56
61
  [tool.pytest]
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2025 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -26,5 +26,5 @@ Booleans
26
26
  """
27
27
 
28
28
  __author__ = 'Geoffrey R. Scheller'
29
- __copyright__ = 'Copyright (c) 2025-2026 Geoffrey R. Scheller'
29
+ __copyright__ = 'Copyright (c) 2023-2026 Geoffrey R. Scheller'
30
30
  __license__ = 'Apache License 2.0'
@@ -86,6 +86,18 @@ class FBool(SBool):
86
86
  self._flavor = flavor
87
87
 
88
88
  def __and__(self, other: int) -> int:
89
+ """
90
+ .. admonition:: bitwise and operator
91
+
92
+ Overloading ``&`` to perform Boolean "and" if ``other`` is
93
+ another FBool of the same flavor.
94
+
95
+ :param other: Any object derived from int.
96
+ :returns: Boolean "and" if other is an FBool of the same
97
+ flavor, otherwise returns bitwise "and".
98
+ :raises: ValueError if other is an FBool of a different flavor.
99
+
100
+ """
89
101
  if type(other) is type(self):
90
102
  if other.flavor() != self._flavor:
91
103
  msg = 'Error: diffent flavored booleans compared with & operator'
@@ -97,6 +109,18 @@ class FBool(SBool):
97
109
  return super().__and__(other)
98
110
 
99
111
  def __or__(self, other: int) -> int:
112
+ """
113
+ .. admonition:: bitwise or operator
114
+
115
+ Overloading ``|`` to perform Boolean "or" if ``other`` is
116
+ another FBool of the same flavor.
117
+
118
+ :param other: Any object derived from int.
119
+ :returns: Boolean "or" if other is an FBool of the same
120
+ flavor, otherwise returns bitwise "or".
121
+ :raises: ValueError if other is an FBool of a different flavor.
122
+
123
+ """
100
124
  if type(other) is type(self):
101
125
  if other.flavor() != self.flavor():
102
126
  msg = 'Error: diffent flavored booleans compared with | operator'
@@ -108,6 +132,18 @@ class FBool(SBool):
108
132
  return super().__or__(other)
109
133
 
110
134
  def __xor__(self, other: int) -> int:
135
+ """
136
+ .. admonition:: bitwise xor operator
137
+
138
+ Overloading ``^`` to perform Boolean "xor" if ``other`` is
139
+ another FBool of the same flavor.
140
+
141
+ :param other: Any object derived from int.
142
+ :returns: Boolean "xor" if other is an FBool of the same
143
+ flavor, otherwise returns bitwise "or".
144
+ :raises: ValueError if other is an FBool of a different flavor.
145
+
146
+ """
111
147
  if type(other) is type(self):
112
148
  if other.flavor() != self._flavor:
113
149
  msg = 'Error: diffent flavored booleans compared with ^ operator'
@@ -160,7 +196,7 @@ class FBool(SBool):
160
196
 
161
197
  Get the flavor of the ``FBool``, a hashable value.
162
198
 
163
- :returns: The flavor.
199
+ :returns: The flavor of the FBool.
164
200
 
165
201
  """
166
202
  return self._flavor
@@ -1,4 +1,4 @@
1
- # Copyright 2023-2025 Geoffrey R. Scheller
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -91,7 +91,7 @@ class SBool(int):
91
91
  .. admonition:: new
92
92
 
93
93
  :param witness: Determines truthiness of the ``SBool``.
94
- :param flavor: Ignored
94
+ :param flavor: Ignored, here for Liskov substitution principle
95
95
  :returns: The truthy or falsy ``SBool`` class instance.
96
96
 
97
97
  """
@@ -128,11 +128,32 @@ class SBool(int):
128
128
  self._flavor: Hashable | NoValue = NoValue()
129
129
 
130
130
  def __invert__(self) -> int:
131
+ """
132
+ .. admonition:: bitwise invert operator
133
+
134
+ Inverts the value of an SBool.
135
+
136
+ :returns: The inverted value of the SBool.
137
+
138
+ """
131
139
  if self:
132
140
  return type(self)(False, self._flavor)
133
141
  return type(self)(True, self._flavor)
134
142
 
135
143
  def __and__(self, other: int) -> int:
144
+ """
145
+ .. admonition:: bitwise and operator
146
+
147
+ Overloading ``&`` to perform Boolean "and" if ``other``
148
+ is another ``SBool``.
149
+
150
+ :param other: Any object derived from int.
151
+ :returns: Boolean "and" if other is an SBool
152
+ otherwise returns bitwise "and".
153
+ :rtype: First common ancestor of the types of self and other
154
+ if both of type SBool, otherwise int.
155
+
156
+ """
136
157
  base_class = fca(type(self), type(other))
137
158
 
138
159
  if issubclass(base_class, SBool):
@@ -148,6 +169,19 @@ class SBool(int):
148
169
  return int(self) & int(other)
149
170
 
150
171
  def __or__(self, other: int) -> int:
172
+ """
173
+ .. admonition:: bitwise or operator
174
+
175
+ Overloading ``|`` to perform Boolean "or" if ``other``
176
+ is another ``SBool``.
177
+
178
+ :param other: Any object derived from int.
179
+ :returns: Boolean "and" if other is an SBool
180
+ otherwise returns bitwise "and".
181
+ :rtype: First common ancestor of the types of self and other
182
+ if both of type SBool, otherwise int.
183
+
184
+ """
151
185
  base_class = fca(type(self), type(other))
152
186
  if issubclass(base_class, SBool):
153
187
  if self._flavor == cast(SBool, other)._flavor:
@@ -162,6 +196,19 @@ class SBool(int):
162
196
  return int(self) | int(other)
163
197
 
164
198
  def __xor__(self, other: int) -> int:
199
+ """
200
+ .. admonition:: bitwise xor operator
201
+
202
+ Overloading ``^`` to perform Boolean "xor" if ``other``
203
+ is another ``SBool``.
204
+
205
+ :param other: Any object derived from int.
206
+ :returns: Boolean "and" if other is an SBool
207
+ otherwise returns bitwise "and".
208
+ :rtype: First common ancestor of the types of self and other
209
+ if both of type SBool, otherwise int.
210
+
211
+ """
165
212
  base_class = fca(type(self), type(other))
166
213
 
167
214
  if issubclass(base_class, SBool):
@@ -181,10 +228,9 @@ class SBool(int):
181
228
  """
182
229
  .. admonition:: repr string
183
230
 
184
- - 'SBool(True)' if truthy
185
- - 'SBool(False)' if falsy
231
+ A string to reproduce the ``SBool``.
186
232
 
187
- :returns: A string to reproduce the ``SBool``.
233
+ :returns: 'SBool(True)' if truthy, 'SBool(False)' if falsy.
188
234
 
189
235
  """
190
236
  if self:
@@ -196,10 +242,9 @@ class SBool(int):
196
242
  """
197
243
  .. admonition:: user string
198
244
 
199
- - 'TRUTH' if truthy
200
- - 'LIE' if falsy
245
+ A string meaningful to an end user.
201
246
 
202
- :returns: A string meaningful to an end user.
247
+ :returns: 'TRUTH' if truthy, 'LIE' if falsy.
203
248
 
204
249
  """
205
250
  if self:
@@ -0,0 +1,285 @@
1
+ # Copyright 2023-2026 Geoffrey R. Scheller
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from collections.abc import Hashable
16
+ from threading import Lock
17
+ from typing import ClassVar, Final, Self, cast, final
18
+
19
+ from .subtypable import SBool
20
+
21
+ __all__ = [
22
+ 'TF_Bool',
23
+ 'T_Bool',
24
+ 'F_Bool',
25
+ 'ALWAYS',
26
+ 'NEVER',
27
+ ]
28
+
29
+
30
+ class TF_Bool(SBool):
31
+ """
32
+ .. admonition:: Truthy-Falsy Booleans
33
+
34
+ A Boolean implementation whose distinct truthy and falsy
35
+ values are distinct singleton subclasses, not just
36
+ distinct singleton values.
37
+
38
+ .. important::
39
+
40
+ Do not subclass ``TF_Bool`` itself. Subclassing it is
41
+ designed to fail at runtime.
42
+
43
+ .. tip::
44
+
45
+ Logically combine these using Python's bitwise operators.
46
+
47
+ .. warning::
48
+
49
+ Although these datastructures are completely compatible
50
+ with Python shortcut evaluation, care needs to be taken
51
+ when using them with the ``and``, ``or``, and ``not`` builtins.
52
+
53
+ For example:
54
+
55
+ - ``~ALWAYS is NEVER``
56
+ - ``not ALWAYS is False``
57
+ - ``(ALWAYS and False) is False``
58
+ - ``(ALWAYS or False) is ALWAYS``
59
+
60
+ """
61
+
62
+ def __new__(cls, witness: object, flavor: Hashable = None) -> Self:
63
+ """
64
+ .. admonition:: new
65
+
66
+ :param witness: Determines which subtype,
67
+ ``T_Bool`` or ``F_Bool``,
68
+ of ``TF_Bool`` to return.
69
+ :param flavor: Ignored parameter, only two flavors,
70
+ one truthy and one falsy.
71
+ :returns: The singleton truthy or singleton falsy instance.
72
+
73
+ """
74
+ if witness:
75
+ return cast(Self, T_Bool())
76
+ return cast(Self, F_Bool())
77
+
78
+ def __init_subclass__(cls, **kwargs: object) -> None:
79
+ super().__init_subclass__(**kwargs)
80
+ if TF_Bool in cls.__bases__ and cls.__module__ != TF_Bool.__module__:
81
+ msg = 'TF_Bool is sealed'
82
+ raise TypeError(msg)
83
+
84
+ def __invert__(self) -> TF_Bool:
85
+ """
86
+ .. admonition:: bitwise invert operator
87
+
88
+ Inverts the value of an TF_Bool.
89
+
90
+ :returns: The inverted value of the SBool.
91
+
92
+ """
93
+ if self:
94
+ return F_Bool()
95
+ return T_Bool()
96
+
97
+ def __repr__(self) -> str:
98
+ """
99
+ .. admonition:: repr string
100
+
101
+ A string to reproduce the TF_Bool.
102
+
103
+ :returns: 'T_Bool()' if truthy, otherwise `F_Bool()`
104
+
105
+ """
106
+ if self:
107
+ return 'T_Bool()'
108
+ return 'F_Bool()'
109
+
110
+ def __str__(self) -> str:
111
+ """
112
+ .. admonition:: user string
113
+
114
+ A string meaningful to an end user.
115
+
116
+ :returns: 'ALWAYS' if truthy, otherwise 'NEVER'
117
+
118
+ """
119
+ if self:
120
+ return 'ALWAYS'
121
+ return 'NEVER'
122
+
123
+
124
+ @final
125
+ class T_Bool(TF_Bool):
126
+ """
127
+ .. admonition:: Truthy TF_Bool subclass
128
+
129
+ Type of the truthy singleton TF_Bool instance.
130
+ A distinct type from F_Bool.
131
+
132
+ """
133
+
134
+ _lock: ClassVar[Lock] = Lock()
135
+
136
+ def __new__(cls, witness: object = None, flavor: Hashable = None) -> Self:
137
+ """
138
+ .. admonition:: new
139
+
140
+ :param witness: Ignored parameter, a T_Bool or T_Bool subtype is always truthy.
141
+ :param flavor: Ignored parameter, only one truthy "flavor" for each T_Bool subtype.
142
+ :returns: The truthy T_Bool or T_Bool subtype singleton instance.
143
+
144
+ """
145
+ inst = cls.__dict__.get('_truthy')
146
+ if inst is None:
147
+ with T_Bool._lock:
148
+ inst = cls.__dict__.get('_truthy')
149
+ if inst is None:
150
+ inst = super(SBool, cls).__new__(cls, 1)
151
+ cls._truthy = inst
152
+ return cast(Self, inst)
153
+
154
+ def __init_subclass__(cls, **kwargs: object) -> None:
155
+ super().__init_subclass__(**kwargs)
156
+ if T_Bool in cls.__bases__ and cls.__module__ != T_Bool.__module__:
157
+ msg = 'T_Bool is final'
158
+ raise TypeError(msg)
159
+
160
+ def __and__(self, other: int) -> int:
161
+ """
162
+ .. admonition:: bitwise and operator
163
+
164
+ Overloading ``&`` to perform Boolean "and" if ``other``
165
+ is another ``TF_Bool``.
166
+
167
+ :param other: Any object derived from int.
168
+ :returns: Boolean "and" if other is an SBool
169
+ otherwise returns bitwise "and".
170
+ :rtype: First common ancestor of the types of self and other
171
+ if both of type SBool, otherwise int.
172
+
173
+ """
174
+ if isinstance(other, TF_Bool):
175
+ return other
176
+ return super().__and__(other)
177
+
178
+ def __or__(self, other: int) -> int:
179
+ """
180
+ .. admonition:: bitwise or operator
181
+
182
+ Overloading ``|`` to perform Boolean "or" if ``other``
183
+ is another ``TF_Bool``.
184
+
185
+ :param other: Any object derived from int.
186
+ :returns: Boolean "or" if other is an SBool
187
+ otherwise returns bitwise "or".
188
+ :rtype: First common ancestor of the types of self and other
189
+ if both of type SBool, otherwise int.
190
+
191
+ """
192
+ if isinstance(other, TF_Bool):
193
+ return self
194
+ return super().__or__(other)
195
+
196
+ def __xor__(self, other: int) -> int:
197
+ """
198
+ .. admonition:: bitwise xor operator
199
+
200
+ Overloading ``^`` to perform Boolean "xor" if ``other``
201
+ is another ``TF_Bool``.
202
+
203
+ :param other: Any object derived from int.
204
+ :returns: Boolean "xor" if other is an SBool
205
+ otherwise returns bitwise "xor".
206
+ :rtype: First common ancestor of the types of self and other
207
+ if both of type SBool, otherwise int.
208
+
209
+ """
210
+ if isinstance(other, TF_Bool):
211
+ if other:
212
+ return ~self
213
+ return self
214
+ return super().__xor__(other)
215
+
216
+
217
+ @final
218
+ class F_Bool(TF_Bool):
219
+ """
220
+ .. admonition:: Falsy TF_Bool subclass
221
+
222
+ Type of the falsy singleton TF_Bool instance.
223
+ A distinct type from T_Bool.
224
+
225
+ """
226
+
227
+ _lock: ClassVar[Lock] = Lock()
228
+
229
+ def __new__(cls, witness: object = None, flavor: Hashable = None) -> Self:
230
+ """
231
+ .. admonition:: new
232
+
233
+ :param witness: Ignored parameter, an F_Bool or F_Bool subtype is always truthy.
234
+ :param flavor: Ignored parameter, only one truthy "flavor" for each F_Bool subtype.
235
+ :returns: The truthy F_Bool or F_Bool subtype singleton instance.
236
+
237
+ """
238
+ inst = cls.__dict__.get('_falsy')
239
+ if inst is None:
240
+ with T_Bool._lock:
241
+ inst = cls.__dict__.get('_falsy')
242
+ if inst is None:
243
+ inst = super(SBool, cls).__new__(cls, 0)
244
+ cls._falsy = inst
245
+ return cast(Self, inst)
246
+
247
+ def __init_subclass__(cls, **kwargs: object) -> None:
248
+ super().__init_subclass__(**kwargs)
249
+ if F_Bool in cls.__bases__ and cls.__module__ != F_Bool.__module__:
250
+ msg = 'F_Bool is final'
251
+ raise TypeError(msg)
252
+
253
+ def __and__(self, other: int) -> int:
254
+ if issubclass(type(other), TF_Bool):
255
+ return self
256
+ return super().__and__(other)
257
+
258
+ def __or__(self, other: int) -> int:
259
+ if issubclass(type(other), TF_Bool):
260
+ return other
261
+ return super().__or__(other)
262
+
263
+ def __xor__(self, other: int) -> int:
264
+ if issubclass(type(other), TF_Bool):
265
+ if other:
266
+ return other
267
+ return self
268
+ return super().__xor__(other)
269
+
270
+
271
+ ALWAYS: Final[TF_Bool] = T_Bool()
272
+ """
273
+ .. admonition:: ALWAYS
274
+
275
+ :var ALWAYS: The truthy singleton TF_Bool subtyped instance.
276
+
277
+ """
278
+
279
+ NEVER: Final[TF_Bool] = F_Bool()
280
+ """
281
+ .. admonition:: NEVER
282
+
283
+ :var NEVER: The falsy singleton TF_Bool subtyped instance.
284
+
285
+ """
@@ -1,229 +0,0 @@
1
- # Copyright 2023-2026 Geoffrey R. Scheller
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from collections.abc import Hashable
16
- from threading import Lock
17
- from typing import ClassVar, Final, Self, cast
18
-
19
- from pythonic_fp.gadgets.sentinels.novalue import NoValue
20
-
21
- from .subtypable import SBool
22
-
23
- __all__ = [
24
- 'TF_Bool',
25
- 'T_Bool',
26
- 'F_Bool',
27
- 'ALWAYS',
28
- 'NEVER',
29
- ]
30
-
31
-
32
- class TF_Bool(SBool):
33
- """
34
- .. admonition:: Truthy-Falsy Booleans
35
-
36
- A Boolean implementation whose distinct truthy and falsy
37
- values are distinct singleton subclasses, not just
38
- distinct singleton values.
39
-
40
- A subtype of SBool.
41
-
42
- .. tip::
43
-
44
- Logically combine these using Python's bitwise operators.
45
-
46
- .. warning::
47
-
48
- Although these datastructures are completely compatible
49
- with Python shortcut evaluation, care needs to be taken when
50
- using them with the "and", "or", and "not" builtins.
51
-
52
- For example, ``~ALWAYS is NEVER`` but ``not ALWAYS is False``
53
- because ``ALWAYS`` is truthy.
54
-
55
- Similarly, ``(ALWAYS and False) is False`` while
56
- ``(ALWAYS or False) is ALWAYS``.
57
-
58
- """
59
-
60
- no_value = NoValue()
61
-
62
- def __new__(
63
- cls,
64
- witness: object,
65
- flavor: Hashable = no_value,
66
- ) -> Self:
67
- """
68
- .. admonition:: new
69
-
70
- :param witness: Determines which subtype, T_Bool or F_Bool to return.
71
- :param flavor: Ignored parameter, only two flavors, one truthy and one falsy.
72
- :returns: The singleton truthy or singleton falsy instances.
73
-
74
- """
75
- if witness:
76
- return cast(Self, T_Bool())
77
- return cast(Self, F_Bool())
78
-
79
- def __invert__(self) -> TF_Bool:
80
- if self:
81
- return F_Bool()
82
- return T_Bool()
83
-
84
- def __repr__(self) -> str:
85
- """
86
- .. admonition:: repr string
87
-
88
- - if truthy return 'TF_Bool(True)'
89
- - if falsy return 'TF_Bool(False)'
90
-
91
- :returns: A string to reproduce the TF_Bool.
92
-
93
- """
94
- if self:
95
- return 'TF_Bool(True)'
96
- return 'TF_Bool(False)'
97
-
98
- def __str__(self) -> str:
99
- """
100
- .. admonition:: user string
101
-
102
- - if truthy return 'ALWAYS'
103
- - if falsy return 'NEVER'
104
-
105
- :returns: A string meaningful to an end user.
106
-
107
- """
108
- if self:
109
- return 'ALWAYS'
110
- return 'NEVER'
111
-
112
-
113
- class T_Bool(TF_Bool):
114
- """
115
- .. admonition:: Truthy TF_Bool subclass
116
-
117
- Type of the truthy singleton TS_Bool instance.
118
- A distinct type from F_Bool.
119
-
120
- """
121
-
122
- no_value = NoValue()
123
-
124
- _truthy: ClassVar[T_Bool | NoValue] = no_value
125
- _lock: ClassVar[Lock] = Lock()
126
-
127
- def __new__(
128
- cls,
129
- witness: object = no_value,
130
- flavor: Hashable | NoValue = no_value,
131
- ) -> Self:
132
- """
133
- .. admonition:: new
134
-
135
- :param witness: Ignored parameter, a T_Bool is always truthy.
136
- :param flavor: Ignored parameter, only one truthy "flavor".
137
- :returns: The truthy T_Bool singleton instance.
138
-
139
- """
140
- if cls._truthy is (no_value := NoValue()):
141
- with cls._lock:
142
- if cls._truthy is no_value:
143
- cls._truthy = super(SBool, cls).__new__(cls, 1)
144
- return cast(Self, cls._truthy)
145
-
146
- def __and__(self, other: int) -> int:
147
- if isinstance(other, TF_Bool):
148
- return other
149
- return super().__and__(other)
150
-
151
- def __or__(self, other: int) -> int:
152
- if isinstance(other, TF_Bool):
153
- return self
154
- return super().__or__(other)
155
-
156
- def __xor__(self, other: int) -> int:
157
- if isinstance(other, TF_Bool):
158
- if other:
159
- return ~self
160
- return self
161
- return super().__xor__(other)
162
-
163
-
164
- class F_Bool(TF_Bool):
165
- """
166
- .. admonition:: Falsy TF_Bool subclass
167
-
168
- Type of the falsy singleton TS_Bool instance.
169
- A distinct type from T_Bool.
170
-
171
- """
172
-
173
- no_value = NoValue()
174
-
175
- _falsy: ClassVar[F_Bool | NoValue] = no_value
176
- _lock: ClassVar[Lock] = Lock()
177
-
178
- def __new__(
179
- cls,
180
- witness: object = NoValue(),
181
- flavor: Hashable | NoValue = no_value,
182
- ) -> Self:
183
- """
184
- .. admonition:: new
185
-
186
- :param witness: Parameter ignored, an F_Bool is always falsy.
187
- :param flavor: Parameter ignored, only one falsy "flavor".
188
- :returns: The falsy F_Bool singleton instance.
189
-
190
- """
191
- if cls._falsy is (no_value := NoValue()):
192
- with cls._lock:
193
- if cls._falsy is no_value:
194
- cls._falsy = super(SBool, cls).__new__(cls, 0)
195
- return cast(Self, cls._falsy)
196
-
197
- def __and__(self, other: int) -> int:
198
- if issubclass(type(other), TF_Bool):
199
- return self
200
- return super().__and__(other)
201
-
202
- def __or__(self, other: int) -> int:
203
- if issubclass(type(other), TF_Bool):
204
- return other
205
- return super().__or__(other)
206
-
207
- def __xor__(self, other: int) -> int:
208
- if issubclass(type(other), TF_Bool):
209
- if other:
210
- return other
211
- return self
212
- return super().__xor__(other)
213
-
214
-
215
- ALWAYS: Final[TF_Bool] = T_Bool()
216
- """
217
- .. admonition:: ALWAYS
218
-
219
- :var ALWAYS: The truthy singleton TF_Bool subtyped instance.
220
-
221
- """
222
-
223
- NEVER: Final[TF_Bool] = F_Bool()
224
- """
225
- .. admonition:: Never
226
-
227
- :var NEVER: The falsy singleton TF_Bool subtyped instance.
228
-
229
- """