Skip to content

Commit 17183cb

Browse files
committed
Rename Bounds to Interval and upper/lower to start/end
`Bounds` will be used to represent a set of `Interval`s in the future. Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 3a4639e commit 17183cb

File tree

2 files changed

+61
-59
lines changed

2 files changed

+61
-59
lines changed

src/frequenz/core/collections.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ def __lt__(self, other: Self, /) -> bool:
2121

2222

2323
@dataclass(frozen=True)
24-
class Bounds(Generic[LessThanComparableOrNoneT]):
25-
"""A range of values with lower and upper bounds.
24+
class Interval(Generic[LessThanComparableOrNoneT]):
25+
"""An interval to test if a value is within its limits.
2626
27-
The bounds are inclusive, meaning that the lower and upper bounds are included in
28-
the range when checking if a value is within the range.
27+
The `start` and `end` are inclusive, meaning that the `start` and `end` limites are
28+
included in the range when checking if a value is contained by the interval.
2929
30-
The type stored in the bounds must be comparable, meaning that it must implement the
31-
`__lt__` method to be able to compare values.
30+
The type stored in the interval must be comparable, meaning that it must implement
31+
the `__lt__` method to be able to compare values.
3232
"""
3333

34-
lower: LessThanComparableOrNoneT
35-
"""Lower bound."""
34+
start: LessThanComparableOrNoneT
35+
"""The start of the interval."""
3636

37-
upper: LessThanComparableOrNoneT
38-
"""Upper bound."""
37+
end: LessThanComparableOrNoneT
38+
"""The end of the interval."""
3939

4040
def __contains__(self, item: LessThanComparableOrNoneT) -> bool:
4141
"""
@@ -51,20 +51,20 @@ def __contains__(self, item: LessThanComparableOrNoneT) -> bool:
5151
return False
5252
casted_item = cast(LessThanComparable, item)
5353

54-
if self.lower is None and self.upper is None:
54+
if self.start is None and self.end is None:
5555
return True
56-
if self.lower is None:
57-
upper = cast(LessThanComparable, self.upper)
58-
return not casted_item > upper
59-
if self.upper is None:
60-
return not self.lower > item
61-
# mypy seems to get confused here, not being able to narrow upper and lower to
56+
if self.start is None:
57+
start = cast(LessThanComparable, self.end)
58+
return not casted_item > start
59+
if self.end is None:
60+
return not self.start > item
61+
# mypy seems to get confused here, not being able to narrow start and end to
6262
# just LessThanComparable, complaining with:
6363
# error: Unsupported left operand type for <= (some union)
6464
# But we know if they are not None, they should be LessThanComparable, and
6565
# actually mypy is being able to figure it out in the lines above, just not in
6666
# this one, so it should be safe to cast.
6767
return not (
68-
casted_item < cast(LessThanComparable, self.lower)
69-
or casted_item > cast(LessThanComparable, self.upper)
68+
casted_item < cast(LessThanComparable, self.start)
69+
or casted_item > cast(LessThanComparable, self.end)
7070
)

tests/test_collections.py

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import pytest
1010

11-
from frequenz.core.collections import Bounds, LessThanComparable
11+
from frequenz.core.collections import Interval, LessThanComparable
1212

1313

1414
class CustomComparable:
@@ -34,7 +34,7 @@ def __repr__(self) -> str:
3434

3535

3636
@pytest.mark.parametrize(
37-
"lower, upper, within, at_lower, at_upper, below_lower, above_upper",
37+
"start, end, within, at_start, at_end, before_start, after_end",
3838
[
3939
(10.0, 100.0, 50.0, 10.0, 100.0, 9.0, 101.0),
4040
(
@@ -48,26 +48,26 @@ def __repr__(self) -> str:
4848
),
4949
],
5050
)
51-
def test_bounds_contains( # pylint: disable=too-many-arguments
52-
lower: LessThanComparable,
53-
upper: LessThanComparable,
51+
def test_interval_contains( # pylint: disable=too-many-arguments
52+
start: LessThanComparable,
53+
end: LessThanComparable,
5454
within: LessThanComparable,
55-
at_lower: LessThanComparable,
56-
at_upper: LessThanComparable,
57-
below_lower: LessThanComparable,
58-
above_upper: LessThanComparable,
55+
at_start: LessThanComparable,
56+
at_end: LessThanComparable,
57+
before_start: LessThanComparable,
58+
after_end: LessThanComparable,
5959
) -> None:
60-
"""Test if a value is within the bounds."""
61-
bounds = Bounds(lower=lower, upper=upper)
62-
assert within in bounds # within
63-
assert at_lower in bounds # at lower
64-
assert at_upper in bounds # at upper
65-
assert below_lower not in bounds # below lower
66-
assert above_upper not in bounds # above upper
60+
"""Test if a value is within the interval."""
61+
interval = Interval(start=start, end=end)
62+
assert within in interval # within
63+
assert at_start in interval # at start
64+
assert at_end in interval # at end
65+
assert before_start not in interval # before start
66+
assert after_end not in interval # after end
6767

6868

6969
@pytest.mark.parametrize(
70-
"upper, within, at_upper, above_upper",
70+
"end, within, at_end, after_end",
7171
[
7272
(100.0, 50.0, 100.0, 101.0),
7373
(
@@ -78,21 +78,21 @@ def test_bounds_contains( # pylint: disable=too-many-arguments
7878
),
7979
],
8080
)
81-
def test_bounds_contains_no_lower(
82-
upper: LessThanComparable,
81+
def test_interval_contains_no_start(
82+
end: LessThanComparable,
8383
within: LessThanComparable,
84-
at_upper: LessThanComparable,
85-
above_upper: LessThanComparable,
84+
at_end: LessThanComparable,
85+
after_end: LessThanComparable,
8686
) -> None:
87-
"""Test if a value is within the bounds with no lower bound."""
88-
bounds_no_lower = Bounds(lower=None, upper=upper)
89-
assert within in bounds_no_lower # within upper
90-
assert at_upper in bounds_no_lower # at upper
91-
assert above_upper not in bounds_no_lower # above upper
87+
"""Test if a value is within the interval with no start."""
88+
interval_no_start = Interval(start=None, end=end)
89+
assert within in interval_no_start # within end
90+
assert at_end in interval_no_start # at end
91+
assert after_end not in interval_no_start # after end
9292

9393

9494
@pytest.mark.parametrize(
95-
"lower, within, at_lower, below_lower",
95+
"start, within, at_start, before_start",
9696
[
9797
(10.0, 50.0, 10.0, 9.0),
9898
(
@@ -103,17 +103,17 @@ def test_bounds_contains_no_lower(
103103
),
104104
],
105105
)
106-
def test_bounds_contains_no_upper(
107-
lower: LessThanComparable,
106+
def test_interval_contains_no_end(
107+
start: LessThanComparable,
108108
within: LessThanComparable,
109-
at_lower: LessThanComparable,
110-
below_lower: LessThanComparable,
109+
at_start: LessThanComparable,
110+
before_start: LessThanComparable,
111111
) -> None:
112-
"""Test if a value is within the bounds with no upper bound."""
113-
bounds_no_upper = Bounds(lower=lower, upper=None)
114-
assert within in bounds_no_upper # within lower
115-
assert at_lower in bounds_no_upper # at lower
116-
assert below_lower not in bounds_no_upper # below lower
112+
"""Test if a value is within the interval with no end."""
113+
interval_no_end = Interval(start=start, end=None)
114+
assert within in interval_no_end # within start
115+
assert at_start in interval_no_end # at start
116+
assert before_start not in interval_no_end # before start
117117

118118

119119
@pytest.mark.parametrize(
@@ -127,7 +127,9 @@ def test_bounds_contains_no_upper(
127127
CustomComparable(-10),
128128
],
129129
)
130-
def test_bounds_contains_no_bounds(value: LessThanComparable) -> None:
131-
"""Test if a value is within the bounds with no bounds."""
132-
bounds_no_bounds: Bounds[LessThanComparable | None] = Bounds(lower=None, upper=None)
133-
assert value in bounds_no_bounds # any value within bounds
130+
def test_interval_contains_unbound(value: LessThanComparable) -> None:
131+
"""Test if a value is within the interval with no bounds."""
132+
interval_no_bounds: Interval[LessThanComparable | None] = Interval(
133+
start=None, end=None
134+
)
135+
assert value in interval_no_bounds # any value within bounds

0 commit comments

Comments
 (0)