From fb9820b78ee5ff52abba09eb1b35a741768d0295 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:25:29 -0400 Subject: [PATCH] fix: review follow-ups on the shared live-card layer - The reused Vegas renderer always gets the current rankings, empty included, so ranks cleared since are not kept drawn. - render_plugin.py: --timeline refuses --no-live (a timeline shows live elements changing), --timeline/--no-live need --vegas, and the Vegas paths create the output's directory like the display path does. Co-Authored-By: Claude Opus 5.5 --- scripts/render_plugin.py | 9 +++++++++ src/common/sports_scroll.py | 6 ++++-- test/test_sports_vegas_elements.py | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/scripts/render_plugin.py b/scripts/render_plugin.py index 1a8c9e52..fc92c811 100644 --- a/scripts/render_plugin.py +++ b/scripts/render_plugin.py @@ -77,6 +77,12 @@ def main() -> int: args = parser.parse_args() + if args.timeline > 1 and args.no_live: + # A timeline shows live elements changing; plain content never does. + parser.error("--timeline shows live elements; it cannot be combined with --no-live") + if (args.timeline or args.no_live) and not args.vegas: + parser.error("--timeline and --no-live need --vegas") + if not (MIN_DIMENSION <= args.width <= MAX_DIMENSION): print(f"Error: --width must be between {MIN_DIMENSION} and {MAX_DIMENSION} (got {args.width})") raise SystemExit(1) @@ -163,6 +169,9 @@ def main() -> int: except Exception as e: logger.warning("update() raised: %s — continuing to display()", e) + if args.vegas: + Path(args.output).parent.mkdir(parents=True, exist_ok=True) + if args.vegas and args.timeline > 1: from src.plugin_system.testing.vegas import render_vegas_timeline image, rows = render_vegas_timeline( diff --git a/src/common/sports_scroll.py b/src/common/sports_scroll.py index 31d84b8c..1f95c54b 100644 --- a/src/common/sports_scroll.py +++ b/src/common/sports_scroll.py @@ -498,8 +498,10 @@ class SportsScrollDisplay: if key not in memo: memo[key] = self.make_vegas_renderer(card_width, rankings_cache) renderer = memo[key] - if rankings_cache and hasattr(renderer, 'set_rankings_cache'): - renderer.set_rankings_cache(rankings_cache) + if hasattr(renderer, 'set_rankings_cache'): + # Every time, empty included: the renderer is reused across + # slates, and ranks cleared since must not stay drawn. + renderer.set_rankings_cache(rankings_cache or {}) return renderer def build_vegas_elements( diff --git a/test/test_sports_vegas_elements.py b/test/test_sports_vegas_elements.py index a923b20c..6e07fd2b 100644 --- a/test/test_sports_vegas_elements.py +++ b/test/test_sports_vegas_elements.py @@ -405,3 +405,11 @@ def test_the_default_card_type_follows_the_game_state(state, expected): display = _display() display.build_vegas_elements([_game("1", state=state)], ["nfl"], fingerprint=_fp) assert display.renderer.calls[0][1] == expected + + +def test_ranks_cleared_since_are_not_kept_by_the_reused_renderer(): + display = _display() + display.build_vegas_elements([_game("1")], ["nfl"], {"HOM": 5}, fingerprint=_fp) + assert display.renderer.rankings == {"HOM": 5} + display.build_vegas_elements([_game("1")], ["nfl"], None, fingerprint=_fp) + assert display.renderer.rankings == {}