Skip to content

Commit 436500c

Browse files
committed
fix: resolve ASYNC230 and ASYNC240 without ignores
1 parent c5109d0 commit 436500c

61 files changed

Lines changed: 844 additions & 688 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

astrbot/core/agent/runners/coze/coze_api_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import io
33
import json
44
from collections.abc import AsyncGenerator
5+
from pathlib import Path
56
from typing import Any
67

78
import aiohttp
@@ -294,8 +295,7 @@ async def test_coze_api_client() -> None:
294295
client = CozeAPIClient(api_key=api_key)
295296

296297
try:
297-
with open("README.md", "rb") as f:
298-
file_data = f.read()
298+
file_data = await asyncio.to_thread(Path("README.md").read_bytes)
299299
file_id = await client.upload_file(file_data)
300300
print(f"Uploaded file_id: {file_id}")
301301
async for event in client.chat_messages(

astrbot/core/agent/runners/dify/dify_api_client.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import asyncio
12
import codecs
23
import json
34
from collections.abc import AsyncGenerator
5+
from pathlib import Path
46
from typing import Any
57

68
from aiohttp import ClientResponse, ClientSession, FormData
@@ -134,14 +136,13 @@ async def file_upload(
134136
# 使用文件路径
135137
import os
136138

137-
with open(file_path, "rb") as f:
138-
file_content = f.read()
139-
form.add_field(
140-
"file",
141-
file_content,
142-
filename=os.path.basename(file_path),
143-
content_type=mime_type or "application/octet-stream",
144-
)
139+
file_content = await asyncio.to_thread(Path(file_path).read_bytes)
140+
form.add_field(
141+
"file",
142+
file_content,
143+
filename=os.path.basename(file_path),
144+
content_type=mime_type or "application/octet-stream",
145+
)
145146
else:
146147
raise ValueError("file_path 和 file_data 不能同时为 None")
147148

astrbot/core/astr_agent_run_util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44
import traceback
55
from collections.abc import AsyncGenerator
6+
from pathlib import Path
67

78
from astrbot.core import logger
89
from astrbot.core.agent.message import Message
@@ -509,8 +510,7 @@ async def _simulated_stream_tts(
509510
audio_path = await tts_provider.get_audio(text)
510511

511512
if audio_path:
512-
with open(audio_path, "rb") as f:
513-
audio_data = f.read()
513+
audio_data = await asyncio.to_thread(Path(audio_path).read_bytes)
514514
await audio_queue.put((text, audio_data))
515515
except Exception as e:
516516
logger.error(

astrbot/core/astr_main_agent_resources.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import base64
23
import json
34
import os
@@ -241,7 +242,7 @@ async def _resolve_path_from_sandbox(
241242
242243
bool: indicates whether the file was downloaded from sandbox.
243244
"""
244-
if os.path.exists(path):
245+
if await asyncio.to_thread(os.path.exists, path):
245246
return path, False
246247

247248
# Try to check if the file exists in the sandbox

astrbot/core/backup/exporter.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
导出格式为 JSON,这是数据库无关的方案,支持未来向 MySQL/PostgreSQL 迁移。
55
"""
66

7+
import asyncio
78
import hashlib
89
import json
910
import os
@@ -83,7 +84,7 @@ async def export_all(
8384
output_dir = get_astrbot_backups_path()
8485

8586
# 确保输出目录存在
86-
Path(output_dir).mkdir(parents=True, exist_ok=True)
87+
await asyncio.to_thread(Path(output_dir).mkdir, parents=True, exist_ok=True)
8788

8889
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
8990
zip_filename = f"astrbot_backup_{timestamp}.zip"
@@ -160,9 +161,10 @@ async def export_all(
160161
# 3. 导出配置文件
161162
if progress_callback:
162163
await progress_callback("config", 0, 100, "正在导出配置文件...")
163-
if os.path.exists(self.config_path):
164-
with open(self.config_path, encoding="utf-8") as f:
165-
config_content = f.read()
164+
if await asyncio.to_thread(os.path.exists, self.config_path):
165+
config_content = await asyncio.to_thread(
166+
Path(self.config_path).read_text, encoding="utf-8"
167+
)
166168
zf.writestr("config/cmd_config.json", config_content)
167169
self._add_checksum("config/cmd_config.json", config_content)
168170
if progress_callback:
@@ -199,7 +201,7 @@ async def export_all(
199201
except Exception as e:
200202
logger.error(f"备份导出失败: {e}")
201203
# 清理失败的文件
202-
if os.path.exists(zip_path):
204+
if await asyncio.to_thread(os.path.exists, zip_path):
203205
os.remove(zip_path)
204206
raise
205207

@@ -317,7 +319,7 @@ async def _export_directories(
317319

318320
for dir_name, dir_path in backup_directories.items():
319321
full_path = Path(dir_path)
320-
if not full_path.exists():
322+
if not await asyncio.to_thread(full_path.exists):
321323
logger.debug(f"目录不存在,跳过: {full_path}")
322324
continue
323325

@@ -362,7 +364,7 @@ async def _export_attachments(
362364
for attachment in attachments:
363365
try:
364366
file_path = attachment.get("path", "")
365-
if file_path and os.path.exists(file_path):
367+
if file_path and await asyncio.to_thread(os.path.exists, file_path):
366368
# 使用 attachment_id 作为文件名
367369
attachment_id = attachment.get("attachment_id", "")
368370
ext = os.path.splitext(file_path)[1]

astrbot/core/backup/importer.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- 版本匹配时也需要用户确认
88
"""
99

10+
import asyncio
1011
import json
1112
import os
1213
import shutil
@@ -364,7 +365,7 @@ async def import_all(
364365
"""
365366
result = ImportResult()
366367

367-
if not os.path.exists(zip_path):
368+
if not await asyncio.to_thread(os.path.exists, zip_path):
368369
result.add_error(f"备份文件不存在: {zip_path}")
369370
return result
370371

@@ -446,12 +447,13 @@ async def import_all(
446447
try:
447448
config_content = zf.read("config/cmd_config.json")
448449
# 备份现有配置
449-
if os.path.exists(self.config_path):
450+
if await asyncio.to_thread(os.path.exists, self.config_path):
450451
backup_path = f"{self.config_path}.bak"
451452
shutil.copy2(self.config_path, backup_path)
452453

453-
with open(self.config_path, "wb") as f:
454-
f.write(config_content)
454+
await asyncio.to_thread(
455+
Path(self.config_path).write_bytes, config_content
456+
)
455457
result.imported_files["config"] = 1
456458
except Exception as e:
457459
result.add_warning(f"导入配置文件失败: {e}")
@@ -753,8 +755,8 @@ async def _import_knowledge_bases(
753755
if faiss_path in zf.namelist():
754756
try:
755757
target_path = kb_dir / "index.faiss"
756-
with zf.open(faiss_path) as src, open(target_path, "wb") as dst:
757-
dst.write(src.read())
758+
with zf.open(faiss_path) as src:
759+
await asyncio.to_thread(target_path.write_bytes, src.read())
758760
except Exception as e:
759761
result.add_warning(f"导入知识库 {kb_id} 的 FAISS 索引失败: {e}")
760762

@@ -766,8 +768,8 @@ async def _import_knowledge_bases(
766768
rel_path = name[len(media_prefix) :]
767769
target_path = kb_dir / rel_path
768770
target_path.parent.mkdir(parents=True, exist_ok=True)
769-
with zf.open(name) as src, open(target_path, "wb") as dst:
770-
dst.write(src.read())
771+
with zf.open(name) as src:
772+
await asyncio.to_thread(target_path.write_bytes, src.read())
771773
except Exception as e:
772774
result.add_warning(f"导入媒体文件 {name} 失败: {e}")
773775

@@ -828,8 +830,8 @@ async def _import_attachments(
828830
target_path = attachments_dir / os.path.basename(name)
829831

830832
target_path.parent.mkdir(parents=True, exist_ok=True)
831-
with zf.open(name) as src, open(target_path, "wb") as dst:
832-
dst.write(src.read())
833+
with zf.open(name) as src:
834+
await asyncio.to_thread(target_path.write_bytes, src.read())
833835
count += 1
834836
except Exception as e:
835837
logger.warning(f"导入附件 {name} 失败: {e}")
@@ -885,15 +887,15 @@ async def _import_directories(
885887
continue
886888

887889
# 备份现有目录(如果存在)
888-
if target_dir.exists():
890+
if await asyncio.to_thread(target_dir.exists):
889891
backup_path = Path(f"{target_dir}.bak")
890-
if backup_path.exists():
892+
if await asyncio.to_thread(backup_path.exists):
891893
shutil.rmtree(backup_path)
892894
shutil.move(str(target_dir), str(backup_path))
893895
logger.debug(f"已备份现有目录 {target_dir}{backup_path}")
894896

895897
# 创建目标目录
896-
target_dir.mkdir(parents=True, exist_ok=True)
898+
await asyncio.to_thread(target_dir.mkdir, parents=True, exist_ok=True)
897899

898900
# 解压文件
899901
for name in dir_files:
@@ -906,8 +908,8 @@ async def _import_directories(
906908
target_path = target_dir / rel_path
907909
target_path.parent.mkdir(parents=True, exist_ok=True)
908910

909-
with zf.open(name) as src, open(target_path, "wb") as dst:
910-
dst.write(src.read())
911+
with zf.open(name) as src:
912+
await asyncio.to_thread(target_path.write_bytes, src.read())
911913
file_count += 1
912914
except Exception as e:
913915
result.add_warning(f"导入文件 {name} 失败: {e}")

astrbot/core/computer/booters/boxlite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import random
3+
from pathlib import Path
34
from typing import Any
45

56
import aiohttp
@@ -46,8 +47,7 @@ async def upload_file(self, path: str, remote_path: str) -> dict:
4647

4748
try:
4849
# Read file content
49-
with open(path, "rb") as f:
50-
file_content = f.read()
50+
file_content = await asyncio.to_thread(Path(path).read_bytes)
5151

5252
# Create multipart form data
5353
data = aiohttp.FormData()

astrbot/core/computer/booters/shipyard_neo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import annotations
22

3+
import asyncio
34
import os
45
import shlex
6+
from pathlib import Path
57
from typing import Any, cast
68

79
from astrbot.api import logger
@@ -468,8 +470,7 @@ def browser(self) -> BrowserComponent:
468470
async def upload_file(self, path: str, file_name: str) -> dict:
469471
if self._sandbox is None:
470472
raise RuntimeError("ShipyardNeoBooter is not initialized.")
471-
with open(path, "rb") as f:
472-
content = f.read()
473+
content = await asyncio.to_thread(Path(path).read_bytes)
473474
remote_path = file_name.lstrip("/")
474475
await self._sandbox.filesystem.upload(remote_path, content)
475476
logger.info("[Computer] File uploaded to Neo sandbox: %s", remote_path)
@@ -486,8 +487,7 @@ async def download_file(self, remote_path: str, local_path: str) -> None:
486487
local_dir = os.path.dirname(local_path)
487488
if local_dir:
488489
os.makedirs(local_dir, exist_ok=True)
489-
with open(local_path, "wb") as f:
490-
f.write(cast(bytes, content))
490+
await asyncio.to_thread(Path(local_path).write_bytes, cast(bytes, content))
491491
logger.info(
492492
"[Computer] File downloaded from Neo sandbox: %s -> %s",
493493
remote_path,

astrbot/core/computer/computer_client.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import json
23
import os
34
import shutil
@@ -372,12 +373,12 @@ async def _sync_skills_to_sandbox(booter: ComputerBooter) -> None:
372373
splitting into `apply` and `scan` phases.
373374
"""
374375
skills_root = Path(get_astrbot_skills_path())
375-
if not skills_root.is_dir():
376+
if not await asyncio.to_thread(skills_root.is_dir):
376377
return
377378
local_skill_dirs = _list_local_skill_dirs(skills_root)
378379

379380
temp_dir = Path(get_astrbot_temp_path())
380-
temp_dir.mkdir(parents=True, exist_ok=True)
381+
await asyncio.to_thread(temp_dir.mkdir, parents=True, exist_ok=True)
381382
zip_base = temp_dir / "skills_bundle"
382383
zip_path = zip_base.with_suffix(".zip")
383384

astrbot/core/computer/tools/fs.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import asyncio
12
import os
23
import uuid
34
from dataclasses import dataclass, field
@@ -111,10 +112,10 @@ async def call(
111112
)
112113
try:
113114
# Check if file exists
114-
if not os.path.exists(local_path):
115+
if not await asyncio.to_thread(os.path.exists, local_path):
115116
return f"Error: File does not exist: {local_path}"
116117

117-
if not os.path.isfile(local_path):
118+
if not await asyncio.to_thread(os.path.isfile, local_path):
118119
return f"Error: Path is not a file: {local_path}"
119120

120121
# Use basename if sandbox_filename is not provided

0 commit comments

Comments
 (0)