fix(run): _should_skip tz check uses isinstance, tolerates mock cfg

Existing lifecycle tests mock cfg via MagicMock; the attribute auto-return
made `cfg.operating_hours._tz_cache` truthy-but-not-a-tzinfo, crashing
datetime.fromtimestamp with TypeError. Guard with isinstance(tz, tzinfo)
so mock configs are silently skipped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 12:07:07 +03:00
parent 8bae507bbd
commit 40cc67b4c6

View File

@@ -8,7 +8,7 @@ import os
import sys import sys
import time import time
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime, tzinfo
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Callable, Protocol, cast from typing import TYPE_CHECKING, Any, Callable, Protocol, cast
@@ -742,8 +742,8 @@ def _should_skip(now_ts: float, state: LifecycleState, cfg, canary) -> str | Non
if oh is None or not oh.enabled: if oh is None or not oh.enabled:
return None return None
tz = getattr(oh, "_tz_cache", None) tz = getattr(oh, "_tz_cache", None)
if tz is None: if not isinstance(tz, tzinfo):
# Enabled but no tz resolved — skip the check rather than crash mid-loop. # Enabled but no tz resolved (or mock cfg in tests) — skip rather than crash.
return None return None
now_exchange = datetime.fromtimestamp(now_ts, tz=tz) now_exchange = datetime.fromtimestamp(now_ts, tz=tz)
# weekday() = 0..6 (MON..SUN). Locale-free; strftime('%a') is not. # weekday() = 0..6 (MON..SUN). Locale-free; strftime('%a') is not.