From 6b2618dab46289f732476f6be0210abdf60bd55b Mon Sep 17 00:00:00 2001 From: Afonso Coutinho Date: Wed, 3 Jun 2026 00:59:30 +0100 Subject: [PATCH] fix: logs CLI _resolve crashes on a non-string name (#1631) --- scripts/odysseus-logs | 2 ++ tests/test_logs_cli_resolve_nonstring.py | 25 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/test_logs_cli_resolve_nonstring.py diff --git a/scripts/odysseus-logs b/scripts/odysseus-logs index cb55c7b..bb2aa41 100755 --- a/scripts/odysseus-logs +++ b/scripts/odysseus-logs @@ -58,6 +58,8 @@ def _resolve(name: str) -> Path | None: """Match a log by exact filename, basename-without-extension, or substring. Returns the most-recently-modified match if there are ties.""" + if not isinstance(name, str): + return None candidates = [] for base in (_APP_LOGS, _TMUX_LOGS): if not base.is_dir(): diff --git a/tests/test_logs_cli_resolve_nonstring.py b/tests/test_logs_cli_resolve_nonstring.py new file mode 100644 index 0000000..5c7d87c --- /dev/null +++ b/tests/test_logs_cli_resolve_nonstring.py @@ -0,0 +1,25 @@ +"""Regression: logs CLI _resolve must tolerate a non-string name. + +`_resolve` did `name in p.name` and `p.name == name`; a non-string `name` +(e.g. None) raised TypeError once any *.log file existed. Non-strings now +return None (no match). +""" +import importlib.machinery +import importlib.util +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + + +def _load(): + loader = importlib.machinery.SourceFileLoader("odysseus_logs_cli", str(ROOT / "scripts" / "odysseus-logs")) + spec = importlib.util.spec_from_loader(loader.name, loader) + m = importlib.util.module_from_spec(spec) + loader.exec_module(m) + return m + + +def test_non_string_name_returns_none(): + cli = _load() + assert cli._resolve(None) is None + assert cli._resolve(123) is None