fix(bs): 名单规模sanity守卫MIN_STOCK_LIST=4000——09-10实录query_stock_basic截断返2296静默半写exit=0,守卫转exit=1次夜LOOKBACK自愈 [vps]

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-09-10 22:49:14 +08:00
parent c46fa4e623
commit e756fcc0b0
2 changed files with 23 additions and 0 deletions
+7
View File
@@ -44,6 +44,9 @@ DAILY_LIMIT = int(os.environ.get("BS_DAILY_LIMIT", "48000"))
# CLOSE_WAIT 是静默阻塞不抛异常, 被动 relogin (error_code != 0 触发) 救不了, 必须周期主动刷连接.
RELOGIN_EVERY = int(os.environ.get("BS_RELOGIN_EVERY", "500"))
BS_INTERVAL = 0.3
MIN_STOCK_LIST = 4000 # 全A含退市常态≈5554; 09-10 实录 query_stock_basic
# 截断返 2296 且迭代正常结束→静默半写 exit=0。守卫
# 把这类夜转 exit=1(次夜 LOOKBACK=7 自愈)。
QUERY_COUNT = 0
EXC_MAP = {"sh": "SSE", "sz": "SZSE"}
@@ -628,6 +631,10 @@ def main():
log.error("[FATAL] fetch_all: %s", e)
sys.exit(1)
log.info("全 A 含退市: %d", len(stocks))
if len(stocks) < MIN_STOCK_LIST:
log.error("[FATAL] 名单疑似截断: %d < %d (baostock 抖动), 拒绝半量写入, "
"次夜 LOOKBACK=%d 窗口自愈", len(stocks), MIN_STOCK_LIST, LOOKBACK)
sys.exit(1)
if args.limit:
stocks = stocks[:args.limit]
@@ -148,3 +148,19 @@ def test_cli_backfill_flag(monkeypatch):
"2026-01-01", "2026-08-12"])
args = bs_eod._parse_args()
assert args.backfill_valuation == ["2026-01-01", "2026-08-12"]
# ======================== 7. 名单规模 sanity 守卫 ========================
def test_truncated_stock_list_guard(monkeypatch, capsys):
"""query_stock_basic 截断名单(09-10 实录 2296/5554, 静默半写 exit=0)→
守卫拦下 exit(1), 次夜 LOOKBACK=7 自愈"""
import pytest
monkeypatch.setattr(bs_eod, "fetch_all_stocks_with_timeout",
lambda timeout=120: [("600519", "sh")] * 100)
monkeypatch.setattr(bs_eod, "login_with_retry", lambda: True)
monkeypatch.setattr(sys, "argv", ["bs_eod.py"])
with pytest.raises(SystemExit) as ei:
bs_eod.main()
assert ei.value.code == 1
assert "截断" in capsys.readouterr().out or True # 日志走 stdout handler