From d7d7ce5bdc6fc7bc26bf69fba700e54a1b5c2d1b Mon Sep 17 00:00:00 2001 From: iomgaa Date: Tue, 14 Jul 2026 06:51:50 -0400 Subject: [PATCH] feat(question_gen): register ActionRecognitionStrategy, replace temp VISUAL binding Co-Authored-By: Claude Opus 4.6 (1M context) --- app/question_gen/strategy.py | 19 ++++++++++++++++++- tests/unit/test_strategy.py | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/app/question_gen/strategy.py b/app/question_gen/strategy.py index 2a8c229..8b88257 100644 --- a/app/question_gen/strategy.py +++ b/app/question_gen/strategy.py @@ -104,7 +104,7 @@ class TaskTypeStrategy(Protocol): # 消歧绑定表:多归属题型确定性绑定到一个 family _TASK_TYPE_TO_FAMILY: dict[str, QuestionFamilySpec] = { - "Action Recognition": VISUAL_FAMILY, # Plan A 临时绑定;Plan B 替换为特化策略 + "Action Recognition": VISUAL_FAMILY, # fallback — 注册表中已被 ActionRecognitionStrategy 替换 "Object Recognition": RETRIEVAL_FAMILY, "Object Reasoning": REASONING_FAMILY, "Action Reasoning": REASONING_FAMILY, @@ -200,9 +200,14 @@ def register_strategy(strategy: TaskTypeStrategy) -> None: _STRATEGY_REGISTRY[strategy.task_type] = strategy +_BUILTIN_REGISTERED = False + + def get_strategy(task_type: str) -> TaskTypeStrategy: """获取题型策略。未注册的自动创建 BaseTaskTypeStrategy。 + 首次调用时延迟注册内建特化策略(避免循环导入)。 + 参数: task_type: 题型名。 @@ -212,6 +217,11 @@ def get_strategy(task_type: str) -> TaskTypeStrategy: 异常: KeyError: task_type 不在消歧绑定表和注册表中。 """ + global _BUILTIN_REGISTERED # noqa: PLW0603 + if not _BUILTIN_REGISTERED: + _BUILTIN_REGISTERED = True + _register_builtin_strategies() + if task_type in _STRATEGY_REGISTRY: return _STRATEGY_REGISTRY[task_type] return _build_default_strategy(task_type) @@ -231,3 +241,10 @@ def _build_default_strategy(task_type: str) -> BaseTaskTypeStrategy: """ family = _TASK_TYPE_TO_FAMILY[task_type] return BaseTaskTypeStrategy(task_type=task_type, family=family) + + +def _register_builtin_strategies() -> None: + """注册内建的特化策略。由 get_strategy 首次调用时延迟执行。""" + from app.question_gen.strategy_action_recognition import ActionRecognitionStrategy + + register_strategy(ActionRecognitionStrategy()) diff --git a/tests/unit/test_strategy.py b/tests/unit/test_strategy.py index 00ad4c2..ec94be6 100644 --- a/tests/unit/test_strategy.py +++ b/tests/unit/test_strategy.py @@ -116,3 +116,27 @@ class TestSubPattern: ) with pytest.raises(AttributeError): sp.name = "changed" + + +class TestActionRecognitionRegistration: + """AR 策略注册后 get_strategy 返回特化实例。""" + + def test_get_strategy_returns_ar_strategy(self): + """get_strategy('Action Recognition') 返回 ActionRecognitionStrategy。""" + from app.question_gen.strategy_action_recognition import ActionRecognitionStrategy + + s = get_strategy("Action Recognition") + assert isinstance(s, ActionRecognitionStrategy) + assert s.task_type == "Action Recognition" + assert s.strategy_name == "ACTION_RECOGNITION" + + def test_ar_not_base_strategy(self): + """get_strategy('Action Recognition') 不再返回 BaseTaskTypeStrategy。""" + s = get_strategy("Action Recognition") + assert not isinstance(s, BaseTaskTypeStrategy) + + def test_other_types_still_base(self): + """其他题型仍返回 BaseTaskTypeStrategy。""" + for tt in ("Object Recognition", "Temporal Reasoning", "Spatial Reasoning"): + s = get_strategy(tt) + assert isinstance(s, BaseTaskTypeStrategy), f"{tt} 应该是 BaseTaskTypeStrategy"