Skip to content

Commit 38dd0dc

Browse files
committed
Ensure @OverRide is added to every overriding method/property
Add @OverRide decorators and test that enforces decorator on overriding methods/properties
1 parent 1e960ff commit 38dd0dc

14 files changed

+566
-10
lines changed

src/spellbind/actions.py

Lines changed: 87 additions & 1 deletion
Large diffs are not rendered by default.

src/spellbind/bool_values.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from abc import ABC
55
from typing import TypeVar, Generic, overload, TYPE_CHECKING, TypeAlias, Callable, Iterable
66

7+
from typing_extensions import override
8+
79
from spellbind.values import Value, OneToOneValue, Constant, SimpleVariable, TwoToOneValue, \
810
ManyToSameValue, ThreeToOneValue
911

@@ -137,12 +139,14 @@ def create(transformer: Callable[[Iterable[bool]], bool], values: Iterable[BoolL
137139

138140
class BoolConstant(BoolValue, Constant[bool]):
139141
@classmethod
142+
@override
140143
def of(cls, value: bool) -> BoolConstant:
141144
if value:
142145
return TRUE
143146
return FALSE
144147

145148
@property
149+
@override
146150
def logical_not(self) -> BoolConstant:
147151
return BoolConstant.of(not self.value)
148152

@@ -153,6 +157,7 @@ class BoolVariable(SimpleVariable[bool], BoolValue):
153157

154158
class ThreeToBoolValue(ThreeToOneValue[_S, _T, _U, bool], BoolValue):
155159
@staticmethod
160+
@override
156161
def create(transformer: Callable[[_S, _T, _U], bool],
157162
first: _S | Value[_S], second: _T | Value[_T], third: _U | Value[_U]) -> BoolValue:
158163
return ThreeToBoolValue(transformer, first, second, third)

src/spellbind/event.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Callable, TypeVar, Generic, Iterable, Sequence
1+
from typing import Callable, TypeVar, Generic, Iterable, Sequence, override
22

33
from spellbind.emitters import Emitter, TriEmitter, BiEmitter, ValueEmitter, ValuesEmitter
44
from spellbind.observables import Observable, ValueObservable, BiObservable, TriObservable, Observer, \
@@ -12,17 +12,21 @@
1212

1313

1414
class Event(_BaseObservable[Observer], Observable, Emitter):
15+
@override
1516
def _get_parameter_count(self) -> int:
1617
return 0
1718

19+
@override
1820
def __call__(self) -> None:
1921
self._emit_nothing()
2022

2123

2224
class ValueEvent(Generic[_S], _SingleBaseObservable[Observer | ValueObserver[_S]], ValueObservable[_S], ValueEmitter[_S]):
25+
@override
2326
def _get_parameter_count(self) -> int:
2427
return 1
2528

29+
@override
2630
def __call__(self, value: _S) -> None:
2731
self._emit_single(value)
2832

@@ -31,9 +35,11 @@ def emit_lazy(self, func: Callable[[], _S]) -> None:
3135

3236

3337
class BiEvent(Generic[_S, _T], _BaseObservable[Observer | ValueObserver[_S] | BiObserver[_S, _T]], BiObservable[_S, _T], BiEmitter[_S, _T]):
38+
@override
3439
def _get_parameter_count(self) -> int:
3540
return 2
3641

42+
@override
3743
def __call__(self, value_0: _S, value_1: _T) -> None:
3844
self._emit_n((value_0, value_1))
3945

@@ -42,14 +48,17 @@ class TriEvent(Generic[_S, _T, _U],
4248
_BaseObservable[Observer | ValueObserver[_S] | BiObserver[_S, _T] | TriObserver[_S, _T, _U]],
4349
TriObservable[_S, _T, _U],
4450
TriEmitter[_S, _T, _U]):
51+
@override
4552
def _get_parameter_count(self) -> int:
4653
return 3
4754

55+
@override
4856
def __call__(self, value_0: _S, value_1: _T, value_2: _U) -> None:
4957
self._emit_n((value_0, value_1, value_2))
5058

5159

5260
class ValuesEvent(Generic[_S], _BaseValuesObservable[Observer | ValuesObserver[_S]], ValuesObservable[_S], ValuesEmitter[_S]):
61+
@override
5362
def __call__(self, value: Iterable[_S]) -> None:
5463
self._emit_single(value)
5564

src/spellbind/float_values.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import math
44
import operator
55
from abc import ABC
6-
from typing import Generic, Callable, Sequence, TypeVar, overload
6+
from typing import Generic, Callable, Sequence, TypeVar, overload, override
77

88
from typing_extensions import Self
99
from typing_extensions import TYPE_CHECKING
@@ -206,17 +206,20 @@ class FloatConstant(FloatValue, Constant[float]):
206206
_cache: dict[float, FloatConstant] = {}
207207

208208
@classmethod
209+
@override
209210
def of(cls, value: float) -> FloatConstant:
210211
try:
211212
return FloatConstant._cache[value]
212213
except KeyError:
213214
return FloatConstant(value)
214215

216+
@override
215217
def __abs__(self):
216218
if self.value >= 0:
217219
return self
218220
return FloatConstant.of(-self.value)
219221

222+
@override
220223
def __neg__(self):
221224
return FloatConstant.of(-self.value)
222225

@@ -245,9 +248,11 @@ def __init__(self, transformer: Callable[[float], _S], of: FloatLike):
245248
super().__init__(*[v for v in (of,) if isinstance(v, Value)])
246249

247250
@property
251+
@override
248252
def value(self) -> _S:
249253
return self._value
250254

255+
@override
251256
def _calculate_value(self) -> _S:
252257
return self._transformer(self._getter())
253258

@@ -277,12 +282,14 @@ def __init__(self, transformer: Callable[[Sequence[float]], _S], *values: FloatL
277282
self._transformer = transformer
278283
super().__init__(*[v for v in self._input_values if isinstance(v, Value)])
279284

285+
@override
280286
def _calculate_value(self) -> _S:
281287
gotten_values = [getter() for getter in self._value_getters]
282288
return self._transformer(gotten_values)
283289

284290

285291
class ManyFloatsToFloatValue(ManyFloatsToOneValue[float], FloatValue):
292+
@override
286293
def decompose_float_operands(self, operator_: Callable) -> Sequence[FloatLike]:
287294
if self._transformer == operator_:
288295
return self._input_values
@@ -299,11 +306,13 @@ def __init__(self, transformer: Callable[[float, float], _S],
299306
self._second_getter = _create_float_getter(second)
300307
super().__init__(*[v for v in (first, second) if isinstance(v, Value)])
301308

309+
@override
302310
def _calculate_value(self) -> _S:
303311
return self._transformer(self._first_getter(), self._second_getter())
304312

305313

306314
class TwoFloatsToFloatsValue(TwoFloatsToOneValue[float], FloatValue):
315+
@override
307316
def decompose_float_operands(self, operator_: Callable) -> Sequence[FloatLike]:
308317
if self._transformer == operator_:
309318
return self._of_first, self._of_second
@@ -322,11 +331,13 @@ def __init__(self, transformer: Callable[[float, float, float], _S],
322331
self._third_getter = _create_float_getter(third)
323332
super().__init__(*[v for v in (first, second, third) if isinstance(v, Value)])
324333

334+
@override
325335
def _calculate_value(self) -> _S:
326336
return self._transformer(self._first_getter(), self._second_getter(), self._third_getter())
327337

328338

329339
class ThreeFloatToFloatValue(ThreeFloatToOneValue[float], FloatValue):
340+
@override
330341
def decompose_float_operands(self, operator_: Callable) -> Sequence[FloatLike]:
331342
if self._transformer == operator_:
332343
return self._of_first, self._of_second, self._of_third
@@ -335,6 +346,7 @@ def decompose_float_operands(self, operator_: Callable) -> Sequence[FloatLike]:
335346

336347
class ThreeToFloatValue(ThreeToOneValue[_S, _T, _U, float], FloatValue):
337348
@classmethod
349+
@override
338350
def create(cls, transformer: Callable[[_S, _T, _U], float],
339351
first: _S | Value[_S], second: _T | Value[_T], third: _U | Value[_U]) -> FloatValue:
340352
return ThreeToFloatValue(transformer, first, second, third)
@@ -344,6 +356,7 @@ class AbsFloatValue(OneFloatToOneValue[float], FloatValue):
344356
def __init__(self, value: FloatLike):
345357
super().__init__(abs, value)
346358

359+
@override
347360
def __abs__(self) -> Self:
348361
return self
349362

@@ -352,6 +365,7 @@ class NegateFloatValue(OneFloatToFloatValue, FloatValue):
352365
def __init__(self, value: FloatLike):
353366
super().__init__(operator.neg, value)
354367

368+
@override
355369
def __neg__(self) -> FloatValue:
356370
of = self._of
357371
if isinstance(of, FloatValue):

src/spellbind/int_collections.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import operator
44
from abc import ABC, abstractmethod
55
from functools import cached_property
6-
from typing import Iterable, Callable, Any
6+
from typing import Iterable, Callable, Any, override
77

88
from typing_extensions import TypeIs
99

@@ -66,6 +66,7 @@ def __init__(self, sequence: IntValueSequence):
6666

6767
class IntValueSequence(ValueSequence[int], IntValueCollection, ABC):
6868
@cached_property
69+
@override
6970
def unboxed(self) -> ObservableIntSequence:
7071
return UnboxedIntValueSequence(self)
7172

src/spellbind/int_values.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import operator
44
from abc import ABC
5-
from typing import overload, Generic, Callable, Iterable
5+
from typing import overload, Generic, Callable, Iterable, override
66

77
from typing_extensions import Self, TypeVar
88

@@ -197,6 +197,7 @@ class TwoToIntValue(Generic[_S, _T], TwoToOneValue[_S, _T, int], IntValue):
197197

198198
class ThreeToIntValue(Generic[_S, _T, _U], ThreeToOneValue[_S, _T, _U, int], IntValue):
199199
@staticmethod
200+
@override
200201
def create(transformer: Callable[[_S, _T, _U], int], first: _S | Value[_S], second: _T | Value[_T], third: _U | Value[_U]) -> IntValue:
201202
return ThreeToIntValue(transformer, first, second, third)
202203

@@ -205,17 +206,20 @@ class IntConstant(IntValue, Constant[int]):
205206
_cache: dict[int, IntConstant] = {}
206207

207208
@classmethod
209+
@override
208210
def of(cls, value: int) -> IntConstant:
209211
try:
210212
return cls._cache[value]
211213
except KeyError:
212214
return IntConstant(value)
213215

216+
@override
214217
def __abs__(self):
215218
if self.value >= 0:
216219
return self
217220
return IntConstant.of(-self.value)
218221

222+
@override
219223
def __neg__(self):
220224
return IntConstant.of(-self.value)
221225

@@ -239,6 +243,7 @@ class AbsIntValue(OneToOneValue[int, int], IntValue):
239243
def __init__(self, value: Value[int]):
240244
super().__init__(abs, value)
241245

246+
@override
242247
def __abs__(self) -> Self:
243248
return self
244249

@@ -247,6 +252,7 @@ class NegateIntValue(OneToOneValue[int, int], IntValue):
247252
def __init__(self, value: Value[int]):
248253
super().__init__(operator.neg, value)
249254

255+
@override
250256
def __neg__(self) -> IntValue:
251257
of = self._of
252258
if isinstance(of, IntValue):

src/spellbind/observable_collections.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import functools
44
from abc import ABC, abstractmethod
5-
from typing import TypeVar, Generic, Collection, Callable, Iterable, Iterator
5+
from typing import TypeVar, Generic, Collection, Callable, Iterable, Iterator, override
66

77
from spellbind.actions import CollectionAction, DeltaAction, DeltasAction, ClearAction
88
from spellbind.event import BiEvent
@@ -29,6 +29,7 @@ def delta_observable(self) -> ValuesObservable[DeltaAction[_S_co]]: ...
2929
@abstractmethod
3030
def length_value(self) -> IntValue: ...
3131

32+
@override
3233
def __len__(self) -> int:
3334
return self.length_value.value
3435

@@ -115,19 +116,23 @@ def _set_value(self, value: _S):
115116
self._on_change(value, old_value)
116117

117118
@property
119+
@override
118120
def value(self) -> _S:
119121
return self._value
120122

121123
@property
124+
@override
122125
def observable(self) -> BiObservable[_S, _S]:
123126
return self._on_change
124127

125128
@property
129+
@override
126130
def derived_from(self) -> frozenset[Value]:
127131
return EMPTY_FROZEN_SET
128132

129133

130134
class ValueCollection(ObservableCollection[Value[_S]], Generic[_S], ABC):
135+
@override
131136
def reduce_to_int(self,
132137
add_reducer: Callable[[int, Value[_S]], int],
133138
remove_reducer: Callable[[int, Value[_S]], int],
@@ -156,6 +161,7 @@ def __init__(self, collection: ObservableCollection[_T], combiner: Callable[[Ite
156161
self._on_change: BiEvent[_S, _S] = BiEvent[_S, _S]()
157162

158163
@property
164+
@override
159165
def observable(self) -> BiObservable[_S, _S]:
160166
return self._on_change
161167

@@ -166,9 +172,11 @@ def _recalculate_value(self):
166172
self._on_change(self._value, old_value)
167173

168174
@property
175+
@override
169176
def value(self) -> _S:
170177
return self._value
171178

172179
@property
180+
@override
173181
def derived_from(self) -> frozenset[Value]:
174182
return EMPTY_FROZEN_SET

0 commit comments

Comments
 (0)