From 8247670ff573cf6f64a24ecee8b17f9e3d429fc8 Mon Sep 17 00:00:00 2001 From: Elaine Hale Date: Thu, 30 Apr 2026 16:55:33 -0600 Subject: [PATCH] Truncate timestamp mismatch error message. `check_timestamp_lists` previously dumped full sets of missing and extra timestamps, which could flood the console with thousands of entries on a length mismatch. Sort each set and summarize as `head ... tail` (5+5 by default) and prefix the count, so the message stays readable while still identifying the gap. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/chronify/time_series_checker.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/chronify/time_series_checker.py b/src/chronify/time_series_checker.py index 53c36f1..e2b6ffa 100644 --- a/src/chronify/time_series_checker.py +++ b/src/chronify/time_series_checker.py @@ -234,14 +234,20 @@ def check_timestamp_lists( expected: list[pd.Timestamp] | list[datetime], msg_prefix: str = "", ) -> None: - match = actual == expected + if actual == expected: + return msg = msg_prefix - if not match: - if len(actual) != len(expected): - msg += f"Mismatch number of timestamps: actual: {len(actual)} vs. expected: {len(expected)}\n" - missing = set(expected).difference(set(actual)) - extra = set(actual).difference(set(expected)) - msg += "Actual timestamps do not match expected timestamps. \n" - msg += f"Missing: {missing} \n" - msg += f"Extra: {extra}" - raise InvalidTable(msg) + if len(actual) != len(expected): + msg += f"Mismatch number of timestamps: actual: {len(actual)} vs. expected: {len(expected)}\n" + missing = sorted(set(expected).difference(actual)) + extra = sorted(set(actual).difference(expected)) + msg += "Actual timestamps do not match expected timestamps.\n" + msg += f"Missing ({len(missing)}): {_summarize_timestamps(missing)}\n" + msg += f"Extra ({len(extra)}): {_summarize_timestamps(extra)}" + raise InvalidTable(msg) + + +def _summarize_timestamps(items: list, head: int = 5, tail: int = 5) -> list: + if len(items) <= head + tail: + return items + return list(items[:head]) + ["..."] + list(items[-tail:])