Skip to content

Commit ce585be

Browse files
committed
extra overload for VisibletimeRanges and accompanying tests
1 parent 440fa22 commit ce585be

File tree

4 files changed

+127
-23
lines changed

4 files changed

+127
-23
lines changed

docs/content/reference/migration/migration-0-23.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,29 @@ After:
240240
#
241241
overrides={
242242
"helix/structure/scaffolding/beads": rrb.VisibleTimeRanges(
243+
timeline="stable_time",
244+
start=rrb.TimeRangeBoundary.cursor_relative(seconds=-0.3),
245+
end=rrb.TimeRangeBoundary.cursor_relative(seconds=0.3)
246+
),
247+
}
248+
#
249+
```
250+
… or respectively for multiple timelines:
251+
```py
252+
#
253+
overrides={
254+
"helix/structure/scaffolding/beads": rrb.VisibleTimeRanges([
255+
rrb.VisibleTimeRange(
256+
timeline="stable_time",
257+
start=rrb.TimeRangeBoundary.cursor_relative(seconds=-0.3),
258+
end=rrb.TimeRangeBoundary.cursor_relative(seconds=0.3)
259+
),
243260
rrb.VisibleTimeRange(
244-
timelines="stable_time",
245-
starts=rrb.TimeRangeBoundary.cursor_relative(seconds=-0.3),
246-
ends=rrb.TimeRangeBoundary.cursor_relative(seconds=0.3),
261+
timeline="index",
262+
start=rrb.TimeRangeBoundary.absolute(seq=10),
263+
end=rrb.TimeRangeBoundary.absolute(seq=100)
247264
),
248-
),
265+
])
249266
}
250267
#
251268
```
252-

examples/python/dna/dna.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,9 @@ def main() -> None:
7878
origin="/",
7979
overrides={
8080
"helix/structure/scaffolding/beads": rrb.VisibleTimeRanges(
81-
rrb.VisibleTimeRange(
82-
timeline="stable_time",
83-
start=rrb.TimeRangeBoundary.cursor_relative(seconds=-0.3),
84-
end=rrb.TimeRangeBoundary.cursor_relative(seconds=0.3),
85-
),
81+
timeline="stable_time",
82+
start=rrb.TimeRangeBoundary.cursor_relative(seconds=-0.3),
83+
end=rrb.TimeRangeBoundary.cursor_relative(seconds=0.3),
8684
),
8785
},
8886
),
Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from __future__ import annotations
22

3-
from typing import Any
3+
from typing import Any, overload
4+
5+
from rerun.datatypes.visible_time_range import VisibleTimeRange
46

57
from ... import datatypes
68
from ...error_utils import _send_warning_or_raise, catch_and_log_exceptions
@@ -9,32 +11,83 @@
911
class VisibleTimeRangesExt:
1012
"""Extension for [VisibleTimeRanges][rerun.blueprint.archetypes.VisibleTimeRanges]."""
1113

12-
def __init__(self: Any, ranges: datatypes.VisibleTimeRangeArrayLike) -> None:
14+
@overload
15+
def __init__(self: Any, ranges: datatypes.VisibleTimeRangeArrayLike) -> None: ...
16+
17+
@overload
18+
def __init__(
19+
self: Any,
20+
*,
21+
timeline: datatypes.Utf8Like,
22+
range: datatypes.TimeRangeLike,
23+
) -> None: ...
24+
25+
@overload
26+
def __init__(
27+
self: Any,
28+
*,
29+
timeline: datatypes.Utf8Like,
30+
start: datatypes.TimeRangeBoundary,
31+
end: datatypes.TimeRangeBoundary,
32+
) -> None: ...
33+
34+
def __init__(
35+
self: Any,
36+
ranges: datatypes.VisibleTimeRangeArrayLike | None = None,
37+
*,
38+
timeline: datatypes.Utf8Like | None = None,
39+
range: datatypes.TimeRangeLike | None = None,
40+
start: datatypes.TimeRangeBoundary | None = None,
41+
end: datatypes.TimeRangeBoundary | None = None,
42+
) -> None:
1343
"""
1444
Create a new instance of the VisibleTimeRanges archetype.
1545
46+
Either from a list of `VisibleTimeRange` objects, or from a single `timeline`-name plus either `range` or `start` & `end`.
47+
1648
Parameters
1749
----------
1850
ranges:
1951
The time ranges to show for each timeline unless specified otherwise on a per-entity basis.
2052
2153
If a timeline is listed twice, a warning will be issued and the first entry will be used.
2254
55+
timeline:
56+
The name of the timeline to show.
57+
Mutually exclusive with `ranges`.
58+
range:
59+
The range of the timeline to show.
60+
Requires `timeline` to be set. Mutually exclusive with `start` & `end`.
61+
start:
62+
The start of the timeline to show.
63+
Requires `timeline` to be set. Mutually exclusive with `range`.
64+
end:
65+
The end of the timeline to show.
66+
Requires `timeline` to be set. Mutually exclusive with `range`.
67+
2368
"""
2469

25-
if isinstance(ranges, datatypes.VisibleTimeRange):
26-
ranges = [ranges]
70+
with catch_and_log_exceptions(context=self.__class__.__name__):
71+
if timeline is not None:
72+
if ranges is not None:
73+
raise ValueError("`timeline` and `ranges` are mutually exclusive.")
74+
ranges = [VisibleTimeRange(timeline=timeline, range=range, start=start, end=end)]
75+
elif ranges is None:
76+
raise ValueError("Either `ranges` or `timeline` must be set.")
2777

28-
timelines = set()
29-
for range in ranges:
30-
if range.timeline in timelines:
31-
_send_warning_or_raise(
32-
f"Warning: Timeline {range.timeline} is listed twice in the list of visible time ranges. Only the first entry will be used.",
33-
1,
34-
)
35-
timelines.add(range.timeline)
78+
if isinstance(ranges, datatypes.VisibleTimeRange):
79+
ranges = [ranges]
80+
81+
timelines = set()
82+
for visible_time_range in ranges:
83+
if visible_time_range.timeline in timelines:
84+
_send_warning_or_raise(
85+
f"Warning: Timeline {visible_time_range.timeline} is listed twice in the list of visible time ranges. Only the first entry will be used.",
86+
1,
87+
)
88+
timelines.add(visible_time_range.timeline)
3689

37-
with catch_and_log_exceptions(context=self.__class__.__name__):
3890
self.__attrs_init__(ranges=ranges)
3991
return
92+
4093
self.__attrs_clear__()

rerun_py/tests/unit/test_visible_time_ranges.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,40 @@ def test_visible_time_ranges_from_single() -> None:
2727
assert rr.blueprint.archetypes.VisibleTimeRanges(time_range) == rr.blueprint.archetypes.VisibleTimeRanges([
2828
time_range,
2929
])
30+
31+
assert rr.blueprint.archetypes.VisibleTimeRanges(time_range) == rr.blueprint.archetypes.VisibleTimeRanges(
32+
timeline="timeline",
33+
start=rr.TimeRangeBoundary.cursor_relative(),
34+
end=rr.TimeRangeBoundary.absolute(seconds=1.0),
35+
)
36+
37+
assert rr.blueprint.archetypes.VisibleTimeRanges(time_range) == rr.blueprint.archetypes.VisibleTimeRanges(
38+
timeline="timeline",
39+
range=rr.TimeRange(rr.TimeRangeBoundary.cursor_relative(), rr.TimeRangeBoundary.absolute(seconds=1.0)),
40+
)
41+
42+
43+
def test_visible_time_ranges_invalid_parameters() -> None:
44+
time_range = rr.VisibleTimeRange(
45+
"timeline",
46+
start=rr.TimeRangeBoundary.cursor_relative(),
47+
end=rr.TimeRangeBoundary.absolute(seconds=1.0),
48+
)
49+
50+
with pytest.raises(ValueError):
51+
# Numpy correctly flags this as an invalid overload, make sure it also throws.
52+
rr.blueprint.archetypes.VisibleTimeRanges(
53+
ranges=[time_range],
54+
timeline="timeline",
55+
start=rr.TimeRangeBoundary.cursor_relative(),
56+
end=rr.TimeRangeBoundary.absolute(seconds=1.0),
57+
) # type: ignore[call-overload]
58+
59+
with pytest.raises(ValueError):
60+
# Numpy correctly flags this as an invalid overload, make sure it also throws.
61+
rr.blueprint.archetypes.VisibleTimeRanges(
62+
timeline="timeline",
63+
start=rr.TimeRangeBoundary.cursor_relative(),
64+
end=rr.TimeRangeBoundary.absolute(seconds=1.0),
65+
range=rr.TimeRange(rr.TimeRangeBoundary.cursor_relative(), rr.TimeRangeBoundary.absolute(seconds=1.0)),
66+
) # type: ignore[call-overload]

0 commit comments

Comments
 (0)