From 648c9ccfaf72f7594524e098e9cae05cda5583e9 Mon Sep 17 00:00:00 2001 From: Justin Gu <97915@qq.com> Date: Sat, 4 Jul 2026 00:17:06 +0800 Subject: [PATCH] =?UTF-8?q?style:=20ruff=20format=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E9=A2=84=E5=AD=98=E6=A0=BC=E5=BC=8F=E5=80=BA=EF=BC=88CI=20ruff?= =?UTF-8?q?=20format=20--check=20=E8=BD=AC=E7=BB=BF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1.17.2 引入的 QFQ 重算代码(adjust.py/client.py/test_mac_qfq_integration.py) 含 magic trailing comma 导致 ruff format 期望多行参数展开,CI 的 'ruff format --check src/ tests/' 自 v1.17.0 起一直失败。纯格式变更, 零逻辑改动(20 例 QFQ 测试全过)。 --- src/easy_tdx/mac/adjust.py | 6 ++- src/easy_tdx/mac/client.py | 37 +++++++++++++---- tests/unit/test_mac_qfq_integration.py | 56 ++++++++++++++++++-------- 3 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/easy_tdx/mac/adjust.py b/src/easy_tdx/mac/adjust.py index 3dec3a0..b6aa3a3 100644 --- a/src/easy_tdx/mac/adjust.py +++ b/src/easy_tdx/mac/adjust.py @@ -132,7 +132,11 @@ def apply_forward_adjust( if not np.isfinite(factor): _logger.warning( "QFQ 本地重算:事件 %s 因子非法(cum_close=%s fh=%s sz=%s pg=%s),跳过", - ed.date(), cum_close, fh, sz, pg, + ed.date(), + cum_close, + fh, + sz, + pg, ) continue arr[: cum_idx + 1] *= factor diff --git a/src/easy_tdx/mac/client.py b/src/easy_tdx/mac/client.py index 42365b1..ade8971 100644 --- a/src/easy_tdx/mac/client.py +++ b/src/easy_tdx/mac/client.py @@ -388,7 +388,10 @@ class MacClient: xd = tc.get_xdxr_info(Market(market), code) except Exception as exc: # noqa: BLE001 - 降级,不中断 kline 获取 _logger.warning( - "QFQ 本地重算:获取 %s %s XDXR 失败,降级返回服务端 QFQ:%s", market, code, exc, + "QFQ 本地重算:获取 %s %s XDXR 失败,降级返回服务端 QFQ:%s", + market, + code, + exc, ) return None if xd is None or xd.empty: @@ -422,7 +425,9 @@ class MacClient: _logger.warning("QFQ 本地重算后 %s %s 仍含非法价格,降级返回服务端 QFQ", market, code) return df _logger.warning( - "QFQ 本地重算:%s %s 服务端深层历史返回负价,已用 NONE+XDXR 重算前复权", market, code, + "QFQ 本地重算:%s %s 服务端深层历史返回负价,已用 NONE+XDXR 重算前复权", + market, + code, ) return out @@ -1342,7 +1347,10 @@ class AsyncMacClient(AsyncHeartbeatMixin): xd = tc.get_xdxr_info(Market(market), code) except Exception as exc: # noqa: BLE001 - 降级,不中断 kline 获取 _logger.warning( - "QFQ 本地重算:获取 %s %s XDXR 失败,降级返回服务端 QFQ:%s", market, code, exc, + "QFQ 本地重算:获取 %s %s XDXR 失败,降级返回服务端 QFQ:%s", + market, + code, + exc, ) return None if xd is None or xd.empty: @@ -1351,7 +1359,10 @@ class AsyncMacClient(AsyncHeartbeatMixin): return xd def _local_recompute_qfq( - self, df: pd.DataFrame, market: int, code: str, + self, + df: pd.DataFrame, + market: int, + code: str, ) -> pd.DataFrame: """对 QFQ 异常的 K 线用 NONE+XDXR 本地重算前复权(同 MacClient)。""" from .adjust import apply_forward_adjust, has_bad_prices @@ -1364,7 +1375,9 @@ class AsyncMacClient(AsyncHeartbeatMixin): _logger.warning("QFQ 本地重算后 %s %s 仍含非法价格,降级返回服务端 QFQ", market, code) return df _logger.warning( - "QFQ 本地重算:%s %s 服务端深层历史返回负价,已用 NONE+XDXR 重算前复权", market, code, + "QFQ 本地重算:%s %s 服务端深层历史返回负价,已用 NONE+XDXR 重算前复权", + market, + code, ) return out @@ -1425,8 +1438,13 @@ class AsyncMacClient(AsyncHeartbeatMixin): nps = min(count - nfetched, _KLINE_PAGE_SIZE) nb = await self._execute( SymbolBarCmd( - market=market, code=code, period=period, times=times, - start=noffset, count=nps, fq=Adjust.NONE, + market=market, + code=code, + period=period, + times=times, + start=noffset, + count=nps, + fq=Adjust.NONE, ) ) if not nb: @@ -1439,7 +1457,10 @@ class AsyncMacClient(AsyncHeartbeatMixin): if none_bars: # XDXR 获取涉及同步网络 IO,放线程执行 df = await asyncio.to_thread( - self._local_recompute_qfq, _to_df(none_bars), market, code, + self._local_recompute_qfq, + _to_df(none_bars), + market, + code, ) delta = _period_to_minutes(period, times) diff --git a/tests/unit/test_mac_qfq_integration.py b/tests/unit/test_mac_qfq_integration.py index ead1f71..99336f0 100644 --- a/tests/unit/test_mac_qfq_integration.py +++ b/tests/unit/test_mac_qfq_integration.py @@ -78,15 +78,21 @@ def test_qfq_negative_triggers_local_recompute(): def fake_execute(cmd: SymbolBarCmd) -> list[MacBar]: return _qfq_broken_bars() if cmd._fq == Adjust.QFQ else _none_bars() - with patch.object(client, "_execute", side_effect=fake_execute), patch( - "easy_tdx.client.TdxClient" - ) as MockTdx: + with ( + patch.object(client, "_execute", side_effect=fake_execute), + patch("easy_tdx.client.TdxClient") as MockTdx, + ): # 让 TdxClient 上下文返回手构 XDXR mock_inst = MockTdx.from_best_host.return_value.__enter__.return_value mock_inst.get_xdxr_info.return_value = _xdxr_df() df = client.get_stock_kline( - market=1, code="601088", period=Period.DAILY, start=0, count=4, adjust=Adjust.QFQ, + market=1, + code="601088", + period=Period.DAILY, + start=0, + count=4, + adjust=Adjust.QFQ, ) # 重算后全部为正 @@ -107,11 +113,17 @@ def test_qfq_clean_does_not_trigger_recompute(): _bar("2024-01-04", 9.0, Adjust.QFQ), ] - with patch.object(client, "_execute", return_value=clean_qfq) as mock_exec, patch( - "easy_tdx.client.TdxClient" - ) as MockTdx: + with ( + patch.object(client, "_execute", return_value=clean_qfq) as mock_exec, + patch("easy_tdx.client.TdxClient") as MockTdx, + ): df = client.get_stock_kline( - market=1, code="601088", period=Period.DAILY, start=0, count=4, adjust=Adjust.QFQ, + market=1, + code="601088", + period=Period.DAILY, + start=0, + count=4, + adjust=Adjust.QFQ, ) # QFQ 干净时不应再去拉 XDXR MockTdx.from_best_host.assert_not_called() @@ -128,15 +140,21 @@ def test_qfq_recompute_xdxr_failure_degrades_gracefully(): def fake_execute(cmd: SymbolBarCmd) -> list[MacBar]: return _qfq_broken_bars() if cmd._fq == Adjust.QFQ else _none_bars() - with patch.object(client, "_execute", side_effect=fake_execute), patch( - "easy_tdx.client.TdxClient" - ) as MockTdx: + with ( + patch.object(client, "_execute", side_effect=fake_execute), + patch("easy_tdx.client.TdxClient") as MockTdx, + ): # XDXR 抛异常 → _fetch_xdxr_records 返回 None → 降级 mock_inst = MockTdx.from_best_host.return_value.__enter__.return_value mock_inst.get_xdxr_info.side_effect = RuntimeError("host unreachable") df = client.get_stock_kline( - market=1, code="601088", period=Period.DAILY, start=0, count=4, adjust=Adjust.QFQ, + market=1, + code="601088", + period=Period.DAILY, + start=0, + count=4, + adjust=Adjust.QFQ, ) # 降级:返回 NONE 数据(apply_forward_adjust 因 xd=None 原样返回 df) @@ -148,11 +166,17 @@ def test_qfq_recompute_xdxr_failure_degrades_gracefully(): def test_none_adjust_skips_recompute(): """adjust=NONE 时完全跳过 QFQ 重算逻辑。""" client = _make_client() - with patch.object(client, "_execute", return_value=_none_bars()) as mock_exec, patch( - "easy_tdx.client.TdxClient" - ) as MockTdx: + with ( + patch.object(client, "_execute", return_value=_none_bars()) as mock_exec, + patch("easy_tdx.client.TdxClient") as MockTdx, + ): df = client.get_stock_kline( - market=1, code="601088", period=Period.DAILY, start=0, count=4, adjust=Adjust.NONE, + market=1, + code="601088", + period=Period.DAILY, + start=0, + count=4, + adjust=Adjust.NONE, ) MockTdx.from_best_host.assert_not_called()