style: 修复2个文件ruff告警+格式化对齐(smart_asset_selector + test_ai_service) #759

Merged
auto-approve-bot merged 1 commits from fix/ruff-alerts-2files into develop 2026-07-23 17:57:33 +08:00
2 changed files with 22 additions and 25 deletions
@@ -18,7 +18,6 @@
from __future__ import annotations
import logging
import math
from dataclasses import dataclass
logger = logging.getLogger(__name__)
@@ -278,9 +277,7 @@ class SmartAssetSelector:
# 分桶
short_bucket = [d for d in scored if d.duration is not None and d.duration < _SHORT_BUCKET_MAX]
medium_bucket = [
d
for d in scored
if d.duration is not None and _SHORT_BUCKET_MAX <= d.duration < _MEDIUM_BUCKET_MAX
d for d in scored if d.duration is not None and _SHORT_BUCKET_MAX <= d.duration < _MEDIUM_BUCKET_MAX
]
long_bucket = [d for d in scored if d.duration is not None and d.duration >= _MEDIUM_BUCKET_MAX]
unknown_bucket = [d for d in scored if d.duration is None]
@@ -295,7 +292,7 @@ class SmartAssetSelector:
selected_ids: set[str] = set()
# 先按配额从每个桶取
for bucket, name in zip(buckets, bucket_names):
for bucket, _name in zip(buckets, bucket_names, strict=False):
quota = min(base_quota, len(bucket))
if quota <= 0:
continue
+20 -20
View File
@@ -20,8 +20,8 @@ sys.path.insert(0, "apps/api")
from app.services.ai_service import ( # noqa: E402
TITLE_STYLES,
_generate_titles_fallback,
_parse_titles_from_response,
_parse_semantic_match_response,
_parse_titles_from_response,
_semantic_match_fallback,
generate_smart_titles,
semantic_match_assets,
@@ -76,7 +76,7 @@ class TestTitleParsing(unittest.TestCase):
def test_parse_markdown_code_block_json(self):
"""解析 markdown 代码块包裹的 JSON."""
content = "```json\n[\"标题1\", \"标题2\"]\n```"
content = '```json\n["标题1", "标题2"]\n```'
result = _parse_titles_from_response(content)
self.assertEqual(len(result), 2)
@@ -209,9 +209,7 @@ class TestGenerateSmartTitles(unittest.TestCase):
mock_client = MagicMock()
mock_client.is_available = True
# 返回无法解析的内容(只有一个标题且格式异常)
mock_client.chat_completion = MagicMock(
return_value="一段文字说明,不是标题列表"
)
mock_client.chat_completion = MagicMock(return_value="一段文字说明,不是标题列表")
with patch("app.services.ai_service.get_doubao_client", return_value=mock_client):
result = generate_smart_titles("测试视频", "viral", 5)
# 只有1个有效标题,不足2个触发降级
@@ -223,7 +221,7 @@ class TestTitleStyles(unittest.TestCase):
def test_all_styles_have_required_fields(self):
"""所有风格都有必要字段."""
for key, info in TITLE_STYLES.items():
for _key, info in TITLE_STYLES.items():
self.assertIn("name", info)
self.assertIn("description", info)
self.assertIn("examples", info)
@@ -310,12 +308,14 @@ class TestSemanticMatchParsing(unittest.TestCase):
def test_parse_matches_list_format(self):
"""解析 {matches: [...]} 格式."""
content = json.dumps({
"matches": [
{"asset_id": "a1", "score": 0.9},
{"asset_id": "a2", "score": 0.7},
]
})
content = json.dumps(
{
"matches": [
{"asset_id": "a1", "score": 0.9},
{"asset_id": "a2", "score": 0.7},
]
}
)
result = _parse_semantic_match_response(content, ["a1", "a2"])
self.assertIsNotNone(result)
self.assertAlmostEqual(result["a1"], 0.9)
@@ -323,10 +323,12 @@ class TestSemanticMatchParsing(unittest.TestCase):
def test_parse_array_format(self):
"""解析数组格式."""
content = json.dumps([
{"id": "x1", "score": 0.5},
{"id": "x2", "score": 0.88},
])
content = json.dumps(
[
{"id": "x1", "score": 0.5},
{"id": "x2", "score": 0.88},
]
)
result = _parse_semantic_match_response(content, ["x1", "x2"])
self.assertIsNotNone(result)
self.assertAlmostEqual(result["x1"], 0.5)
@@ -341,7 +343,7 @@ class TestSemanticMatchParsing(unittest.TestCase):
def test_parse_markdown_code_block(self):
"""解析markdown代码块."""
content = "```json\n{\"a1\": 0.7}\n```"
content = '```json\n{"a1": 0.7}\n```'
result = _parse_semantic_match_response(content, ["a1", "a2"])
# 只有1个素材评分,少于一半(需要至少1个,max(1, 2//2)=1
self.assertIsNotNone(result)
@@ -396,9 +398,7 @@ class TestSemanticMatchAssets(unittest.TestCase):
"""豆包调用成功路径."""
mock_client = MagicMock()
mock_client.is_available = True
mock_client.chat_completion = MagicMock(
return_value=json.dumps({"a1": 0.9, "a2": 0.5, "a3": 0.2})
)
mock_client.chat_completion = MagicMock(return_value=json.dumps({"a1": 0.9, "a2": 0.5, "a3": 0.2}))
with patch("app.services.ai_service.get_doubao_client", return_value=mock_client):
result = semantic_match_assets("风景视频", self._make_assets())
self.assertEqual(result["source"], "doubao")