fix(factor): v2b档案上线暴露的注册链缺口——composite_weighting._register_all幂等重挂fund_*_neu(reload场景registry清空后neu模块不随之重执行);测试适配新世界=计数75→75+6派生/_ALLOWED放行cs_neutralize/absent档案测试改monkeypatch模拟真档案已上线 [nas]
CI/CD / test (push) Successful in 27s
CI/CD / nas-deploy (push) Successful in 1s
CI/CD / nas-verify (push) Successful in 12s

This commit is contained in:
2026-09-11 09:29:03 +08:00
parent f7dfd14bb8
commit 0bd88b6e37
3 changed files with 16 additions and 7 deletions
+4
View File
@@ -155,6 +155,10 @@ def _register_all() -> None:
文件到位即自动注册,不 ImportError).
"""
composite_library._register_all()
# 幂等重挂 fund_*_neu(reload 场景 registry 被清后,neu 模块不会随之重执行,
# v2b 档案存在时其源必须可重建——v2b 档案上线前此缺口被 graceful 分支掩盖)
from .fundamental_neutralize import _register_all as _neu_register_all
_neu_register_all()
register_composite_from_profile(load_profile(str(_DEFAULT_PROFILE_PATH)),
_DEFAULT_COMPOSITE_NAME)
if _V2B_PROFILE_PATH.exists():
+7 -4
View File
@@ -19,8 +19,9 @@ def _ensure_fundamental_registered():
# 表达式可引用的列 = adapter 特征列 + 行情列 close(估值类 ÷ close×share_capital)
# + 表达式函数名(P1 起用到 log)
_ALLOWED = set(FEATURE_COLUMNS) | {"close", "cs_rank", "log"}
# + 表达式函数名(P1 起用到 log;v2b 起中性化因子用 cs_neutralize)
from sanguo_factor.fundamental_neutralize import FUND_NEU_SOURCES
_ALLOWED = set(FEATURE_COLUMNS) | {"close", "cs_rank", "log", "cs_neutralize"}
def _fundamental_factors() -> list[dict]:
@@ -31,7 +32,9 @@ def test_p0_32_factors_registered():
facs = _fundamental_factors()
names = {f["name"] for f in facs}
# P0 32 + P1 37(35 因子 + 2 互评变体;P1 名单见 test_fundamental_p1_library)
assert len(facs) == 75, f"P0+P1+P1-B 应为 75 个,实际 {len(facs)}"
# + v2b 中性化 6(fund_*_neu,注册链经 composite_weighting 可在场,故派生不钉死)
assert len(facs) == 75 + len(FUND_NEU_SOURCES), \
f"P0+P1+P1-B+neu 应为 {75 + len(FUND_NEU_SOURCES)} 个,实际 {len(facs)}"
# 六族代表抽查(全部名单见 fundamental_library 注释)
expect = {
"fund_roe_ttm", "fund_gp_over_assets", # A
@@ -83,4 +86,4 @@ def test_registration_idempotent():
"""重复 import 不炸(注册表防重入,同 library.py 模式)."""
import importlib
importlib.reload(fundamental_library)
assert len(_fundamental_factors()) == 75
assert len(_fundamental_factors()) == 75 + len(FUND_NEU_SOURCES)
+5 -3
View File
@@ -227,10 +227,12 @@ def test_weighting_rejects_mixed_direction_drift():
assert get_factor(name) is None
def test_v2b_profile_absent_skips_registration():
"""v2b 档案不存在(仓库当前态): _register_all 不炸、不注册 composite_all18_v2b."""
def test_v2b_profile_absent_skips_registration(tmp_path, monkeypatch):
"""v2b 档案不存在(真档案已上线,monkeypatch 指向不存在路径模拟缺席):
_register_all 不炸、不注册 composite_all18_v2b."""
_REGISTRY.pop(composite_weighting._V2B_COMPOSITE_NAME, None)
assert not composite_weighting._V2B_PROFILE_PATH.exists()
monkeypatch.setattr(composite_weighting, "_V2B_PROFILE_PATH",
tmp_path / "absent_v2b.json")
composite_weighting._register_all() # 不应 raise
assert get_factor(composite_weighting._V2B_COMPOSITE_NAME) is None