diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 594714e0..c7d88811 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ ci: autoupdate_commit_msg: "chore: auto update by pre-commit hooks" repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.15 + rev: v0.3.1 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/bot.py b/bot.py index d3aaa23e..d3122a1c 100644 --- a/bot.py +++ b/bot.py @@ -40,9 +40,9 @@ async def handle_github_action_event(): await handle_event(bot, event) except Exception: logger.exception("处理 GitHub Action 事件时出现异常") - finally: - # 处理一次之后就退出 - driver.exit(True) + + +handle_event_task = None class Adapter(GITHUBAdapter): @@ -50,15 +50,18 @@ def _setup(self): self.driver.on_startup(self._startup) async def _startup(self): + driver = cast(Driver, self.driver) try: await super()._startup() except Exception: logger.exception("启动 GitHub 适配器时出现异常") - driver = cast(Driver, self.driver) driver.exit(True) return + # 完成启动后创建任务处理 GitHub Action 事件 - asyncio.create_task(handle_github_action_event()) + handle_event_task = asyncio.create_task(handle_github_action_event()) + # 处理完成之后就退出 + handle_event_task.add_done_callback(lambda _: driver.exit(True)) @classmethod def payload_to_event( diff --git a/pyproject.toml b/pyproject.toml index d5b48058..537152f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,8 +29,32 @@ pytest-xdist = "^3.3.1" respx = "^0.20.1" [tool.ruff] -select = ["E", "W", "F", "UP", "C", "T", "PYI", "Q"] -ignore = ["E402", "E501", "C901", "UP037"] +line-length = 88 +target-version = "py310" + +[tool.ruff.lint] +select = [ + "F", # Pyflakes + "W", # pycodestyle warnings + "E", # pycodestyle errors + "UP", # pyupgrade + "ASYNC", # flake8-async + "C4", # flake8-comprehensions + "T10", # flake8-debugger + "T20", # flake8-print + "PYI", # flake8-pyi + "PT", # flake8-pytest-style + "Q", # flake8-quotes + "RUF", # Ruff-specific rules +] +ignore = [ + "E402", # module-import-not-at-top-of-file + "E501", # line-too-long + "UP037", # quoted-annotation + "RUF001", # ambiguous-unicode-character-string + "RUF002", # ambiguous-unicode-character-docstring + "RUF003", # ambiguous-unicode-character-comment +] [tool.pyright] typeCheckingMode = "basic" diff --git a/src/plugins/publish/depends.py b/src/plugins/publish/depends.py index ea04e45a..c9822d02 100644 --- a/src/plugins/publish/depends.py +++ b/src/plugins/publish/depends.py @@ -48,7 +48,7 @@ def get_labels( | IssueCommentCreated, ): """获取议题或拉取请求的标签""" - if isinstance(event, (PullRequestClosed, PullRequestReviewSubmitted)): + if isinstance(event, PullRequestClosed | PullRequestReviewSubmitted): labels = event.payload.pull_request.labels else: labels = event.payload.issue.labels diff --git a/src/plugins/publish/render.py b/src/plugins/publish/render.py index 8a66ba0b..970c57d0 100644 --- a/src/plugins/publish/render.py +++ b/src/plugins/publish/render.py @@ -66,9 +66,9 @@ async def render_comment(result: "ValidationDict", reuse: bool = False) -> str: if result["type"] == PublishType.PLUGIN: # https://github.com/he0119/action-test/actions/runs/4469672520 if plugin_config.plugin_test_result or plugin_config.skip_plugin_test: - result["data"][ - "action_url" - ] = f"https://github.com/{plugin_config.github_repository}/actions/runs/{plugin_config.github_run_id}" + result["data"]["action_url"] = ( + f"https://github.com/{plugin_config.github_repository}/actions/runs/{plugin_config.github_run_id}" + ) template = env.get_template("comment.md.jinja") return await template.render_async( diff --git a/src/utils/plugin_test.py b/src/utils/plugin_test.py index ee402a76..22fffc8a 100644 --- a/src/utils/plugin_test.py +++ b/src/utils/plugin_test.py @@ -1,4 +1,4 @@ -""" 插件加载测试 +"""插件加载测试 测试代码修改自 ,谢谢 [Lan 佬](https://github.com/Lancercmd)。 @@ -8,7 +8,7 @@ 经测试可以直接在 Python 3.10+ 环境下运行,无需额外依赖。 """ -# ruff: noqa: T201 +# ruff: noqa: T201, ASYNC101 import json import os diff --git a/src/utils/store_test/__init__.py b/src/utils/store_test/__init__.py index cd79cce6..9833c510 100644 --- a/src/utils/store_test/__init__.py +++ b/src/utils/store_test/__init__.py @@ -1,4 +1,4 @@ -""" 测试插件商店中的插件 +"""测试插件商店中的插件 直接通过 `python -m src.utils.store_test` 运行 """ diff --git a/src/utils/store_test/validation.py b/src/utils/store_test/validation.py index 1a595677..7c864bbb 100644 --- a/src/utils/store_test/validation.py +++ b/src/utils/store_test/validation.py @@ -1,4 +1,5 @@ -""" 测试并验证插件 """ +"""测试并验证插件""" + import json import os import re diff --git a/src/utils/validation/__init__.py b/src/utils/validation/__init__.py index f9244d6a..b90fe29a 100644 --- a/src/utils/validation/__init__.py +++ b/src/utils/validation/__init__.py @@ -1,4 +1,4 @@ -""" 验证数据是否符合规范 """ +"""验证数据是否符合规范""" from typing import Any, cast diff --git a/src/utils/validation/models.py b/src/utils/validation/models.py index d99660f4..23be2ae7 100644 --- a/src/utils/validation/models.py +++ b/src/utils/validation/models.py @@ -189,7 +189,7 @@ def supported_adapters_validator( if v is None: return None - if not isinstance(v, (list, set)): + if not isinstance(v, list | set): raise PydanticCustomError("set_type", "值应该是一个集合") supported_adapters = {resolve_adapter_name(x) for x in v} diff --git a/tests/conftest.py b/tests/conftest.py index 87363c7b..14586585 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -108,15 +108,15 @@ async def app(app: App, tmp_path: Path, mocker: MockerFixture): get_pypi_data.cache_clear() -@pytest.fixture(autouse=True, scope="function") -def clear_cache(app: App): +@pytest.fixture(autouse=True) +def _clear_cache(app: App): """每次运行前都清除 cache""" from src.utils.validation.utils import check_url check_url.cache_clear() -@pytest.fixture +@pytest.fixture() def mocked_api(respx_mock: MockRouter): respx_mock.get("exception", name="exception").mock(side_effect=httpx.ConnectError) respx_mock.get( @@ -203,4 +203,4 @@ def mocked_api(respx_mock: MockRouter): }, ], ) - yield respx_mock + return respx_mock diff --git a/tests/publish/process/test_publish_check.py b/tests/publish/process/test_publish_check.py index aea96d2b..2aa129de 100644 --- a/tests/publish/process/test_publish_check.py +++ b/tests/publish/process/test_publish_check.py @@ -1,3 +1,5 @@ +# ruff: noqa: ASYNC101 + import json from pathlib import Path from typing import Any, cast diff --git a/tests/publish/utils/test_resolve_conflict_pull_requests.py b/tests/publish/utils/test_resolve_conflict_pull_requests.py index 73d6f4db..ef8e6a76 100644 --- a/tests/publish/utils/test_resolve_conflict_pull_requests.py +++ b/tests/publish/utils/test_resolve_conflict_pull_requests.py @@ -1,3 +1,4 @@ +# ruff: noqa: ASYNC101 import json from pathlib import Path from typing import Any, cast diff --git a/tests/utils/store_test/test_store_test.py b/tests/utils/store_test/test_store_test.py index 566028a3..ecfa29aa 100644 --- a/tests/utils/store_test/test_store_test.py +++ b/tests/utils/store_test/test_store_test.py @@ -21,7 +21,7 @@ def load_json(name: str) -> dict: return json.load(f) -@pytest.fixture +@pytest.fixture() def mocked_store_data( tmp_path: Path, mocker: MockerFixture, diff --git a/tests/utils/store_test/test_utils.py b/tests/utils/store_test/test_utils.py index ec0aa427..45ce5cc2 100644 --- a/tests/utils/store_test/test_utils.py +++ b/tests/utils/store_test/test_utils.py @@ -10,17 +10,13 @@ async def test_load_json_failed(mocked_api: MockRouter): mocked_api.get(STORE_ADAPTERS_URL).respond(404) - with pytest.raises(ValueError) as e: + with pytest.raises(ValueError, match="下载文件失败:"): load_json(STORE_ADAPTERS_URL) - assert str(e.value) == "下载文件失败:" - async def test_get_pypi_data_failed(mocked_api: MockRouter): """获取 PyPI 数据失败""" from src.utils.store_test.utils import get_pypi_data - with pytest.raises(ValueError) as e: + with pytest.raises(ValueError, match="获取 PyPI 数据失败:"): get_pypi_data("project_link_failed") - - assert str(e.value) == "获取 PyPI 数据失败:"