Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
default_install_hook_types: [pre-commit, prepare-commit-msg]
ci:
autofix_commit_msg: ":rotating_light: auto fix by pre-commit hooks"
autofix_prs: true
autoupdate_branch: master
autoupdate_schedule: monthly
autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks"
autofix_commit_msg: ':rotating_light: auto fix by pre-commit hooks'
autofix_prs: true
autoupdate_branch: master
autoupdate_schedule: monthly
autoupdate_commit_msg: ':arrow_up: auto update by pre-commit hooks'
repos:
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
stages: [pre-commit]
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
stages: [pre-commit]

- repo: https://github.com/psf/black
rev: 25.1.0
hooks:
- id: black
stages: [pre-commit]
- repo: https://github.com/psf/black
rev: 26.1.0
hooks:
- id: black
stages: [pre-commit]

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.7
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
stages: [pre-commit]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.4
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
stages: [pre-commit]
894 changes: 482 additions & 412 deletions pdm.lock

Large diffs are not rendered by default.

143 changes: 73 additions & 70 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
[project]
name = "nonebot-plugin-alconna"
description = "Alconna Adapter for Nonebot"
authors = [
{name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com"},
]
authors = [{ name = "RF-Tar-Railt", email = "rf_tar_railt@qq.com" }]
dependencies = [
"tarina<0.8.0,>=0.7.3",
"nepattern<1.0,>=0.7.7",
Expand All @@ -16,12 +14,8 @@ dependencies = [
dynamic = ["version"]
requires-python = ">=3.10"
readme = "README.md"
license = {text = "MIT"}
keywords = [
"command",
"alconna",
"nonebot",
]
license = { text = "MIT" }
keywords = ["command", "alconna", "nonebot"]
[project.urls]
homepage = "https://github.com/nonebot/plugin-alconna"
repository = "https://github.com/nonebot/plugin-alconna"
Expand Down Expand Up @@ -58,95 +52,99 @@ target-version = "py39"

[tool.ruff.lint]
select = [
"F", # pyflakes
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"E", # pycodestyle errors
"W", # pycodestyle warnings
# "I", # isort
"N", # PEP8-naming
"UP", # pyupgrade
"YTT", # flake8-2020
"ASYNC", # flake8-async
# "S", # flake8-bandit
"BLE", # flake8-blind-except
"BLE", # flake8-blind-except
# "FBT", # flake8-boolean-trap
"B", # flake8-bugbear
"A", # flake8-builtins
"COM", # flake8-commas
"C4", # flake8-comprehensions
"DTZ", # flake8-datetimez
"T10", # flake8-debugger
"B", # flake8-bugbear
"A", # flake8-builtins
"COM", # flake8-commas
"C4", # flake8-comprehensions
"DTZ", # flake8-datetimez
"T10", # flake8-debugger
# "FA", # flake8-future-annotations
"ISC", # flake8-implicit-str-concat
"ICN", # flake8-import-conventions
"PIE", # flake8-pie
"T20", # flake8-print
"PYI", # flake8-pyi
"Q", # flake8-quotes
"RSE", # flake8-raise
"RET", # flake8-return
"SLOT", # flake8-slots
"SIM", # flake8-simplify
"TID", # flake8-tidy-imports
"ISC", # flake8-implicit-str-concat
"ICN", # flake8-import-conventions
"PIE", # flake8-pie
"T20", # flake8-print
"PYI", # flake8-pyi
"Q", # flake8-quotes
"RSE", # flake8-raise
"RET", # flake8-return
"SLOT", # flake8-slots
"SIM", # flake8-simplify
"TID", # flake8-tidy-imports
# "TC", # flake8-type-checking
# "ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib
"PTH", # flake8-use-pathlib
# "ERA", # eradicate
"PD", # pandas-vet
"PGH", # pygrep-hooks
"PL", # pylint
"TRY", # tryceratops
"FLY", # flynt
"FAST", # FastAPI
"PERF", # Perflint
"FURB", # refurb
"RUF", # Ruff-specific rules
"PD", # pandas-vet
"PGH", # pygrep-hooks
"PL", # pylint
"TRY", # tryceratops
"FLY", # flynt
"FAST", # FastAPI
"PERF", # Perflint
"FURB", # refurb
"RUF", # Ruff-specific rules
]
ignore = [
"C901",
"T201",
"E731",
"PT023",
"B010", # Do not call `setattr` with a constant attribute value.
"B010", # Do not call `setattr` with a constant attribute value.
"SIM105", # Use `contextlib.suppress`
"B008", # Do not perform function call in argument defaults
"RUF100", # Unused `noqa` directive
"TC003", # Move xxx into a type-checking block
"E402", # module level import not at top of file
"E501", # 过长的行由 ruff format 处理, 剩余的都是字符串
"UP035", # pyupgrade, 但 typing.Callable 的导入会报错
"B008", # Do not perform function call in argument defaults
"RUF100", # Unused `noqa` directive
"TC003", # Move xxx into a type-checking block
"E402", # module level import not at top of file
"E501", # 过长的行由 ruff format 处理, 剩余的都是字符串
"UP035", # pyupgrade, 但 typing.Callable 的导入会报错
"TRY003",
"TRY301", # 为啥非要把 raise 丢进另外一个 inner fn 里
"BLE001", # except Exception as e
"PGH003", # 要求 `# type: ignore` 提供理由,但 pyright 和 mypy 等都不是统一标准。
"PLC0414", # 用 import-as 表示 re-export
"N818", # 要求所有自定义错误以 Error 作后缀,但我们不这么做
"RET502", # return = return None
"PLC0414", # 用 import-as 表示 re-export
"N818", # 要求所有自定义错误以 Error 作后缀,但我们不这么做
"RET502", # return = return None
"RET503", # 就要 implicit return none
"PLC0415", # 你别管我为什么不在顶层 import
"PLC0105", # 我们已经用 R 表示协变,Q 表示逆变了
"PLR0913", # 参数就那么多的,你用 builder 什么的不是更逆天?
"PLC0415", # 你别管我为什么不在顶层 import
"PLC0105", # 我们已经用 R 表示协变,Q 表示逆变了
"PLR0913", # 参数就那么多的,你用 builder 什么的不是更逆天?
"SIM108", # 迫真 simplicy
"RUF001", # String contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?
"RUF002", # Docstring contains ambiguous `,` (FULLWIDTH COMMA). Did you mean `,` (COMMA)?
"RUF009", # 我不想要额外的全局变量。
# "UP038", # instance(..., X | Y) 还是太超前了
"RUF003", # 中文注释里用全角符号怎么你了
"SLOT000", # 动态类型需求,主要是 json5 backend
"PLR0911", "PLR0912", "PLR0915", # 复杂度高点怎么你了
"PYI019", # 用 `Self` 替代 `self: T` 的 T
"PYI041", # int 和 float 在运行时的类型没有交集(互不成立 issubclass)
"RUF003", # 中文注释里用全角符号怎么你了
"SLOT000", # 动态类型需求,主要是 json5 backend
"PLR0911",
"PLR0912",
"PLR0915", # 复杂度高点怎么你了
"PYI019", # 用 `Self` 替代 `self: T` 的 T
"PYI041", # int 和 float 在运行时的类型没有交集(互不成立 issubclass)
"PLW2901", # shallow 怎么你了
"S101", # assert 怎么你了,非要 RuntimeError 吗
"S101", # assert 怎么你了,非要 RuntimeError 吗
"PLR2004", # magic number 怎么你了
"TRY004", # 我要抛啥错误我清楚
"COM812", # 强制尾随逗号
"TID252", # 相对导入
"ISC001", # format warning
"N801", # Class name should use CapWords convention
"N802", # Function name should be lowercase
"N804", # First argument of a class method should be named `cls`
"N805", # First argument of a method should be named `self`
"N806", # Variable in function should be lowercase
"TRY004", # 我要抛啥错误我清楚
"COM812", # 强制尾随逗号
"TID252", # 相对导入
"ISC001", # format warning
"N801", # Class name should use CapWords convention
"N802", # Function name should be lowercase
"N804", # First argument of a class method should be named `cls`
"N805", # First argument of a method should be named `self`
"N806", # Variable in function should be lowercase
"PLW0108",
"ASYNC240",
]
flake8-quotes = { inline-quotes = "double", multiline-quotes = "double" }

Expand All @@ -167,7 +165,11 @@ reportSelfClsParameterName = false

[tool.pdm.scripts]
test = "pytest -v -W ignore ./tests/"
format = { composite = ["isort ./src/ ./example/ ./tests/","black ./src/ ./example/ ./tests/","ruff check ./src/ ./example/ ./tests/"] }
format = { composite = [
"isort ./src/ ./example/ ./tests/",
"black ./src/ ./example/ ./tests/",
"ruff check ./src/ ./example/ ./tests/",
] }

[tool.pytest.ini_options]
asyncio_mode = "auto"
Expand All @@ -189,7 +191,7 @@ dev = [
"nonebot2[httpx,websockets]>=2.4.3",
"nonebot-adapter-console<0.10.0,>=0.9.0",
"nonebot-adapter-ding>=2.0.0a16",
"nonebot-adapter-discord>=0.1.8",
"nonebot-adapter-discord>=1.1.3",
"nonebot-adapter-dodo>=0.2.1",
"nonebot-adapter-feishu>=2.6.2",
"nonebot-adapter-kaiheila>=0.3.4",
Expand All @@ -215,6 +217,7 @@ dev = [
"nonebot-adapter-efchat>=0.1.9.post2",
"pytest-asyncio==0.26.0",
"nonebot-adapter-bilibili-live>=0.2.4",
"nonebot-adapter-yunhu>=0.1.6",
]
test = [
"nonebug>=0.4.3",
Expand Down
33 changes: 18 additions & 15 deletions src/nonebot_plugin_alconna/builtins/extensions/discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
SubCommandGroupOption,
SubCommandOption,
)
from nonebot.adapters.discord.api.types import InteractionCallbackType, MessageFlag
from nonebot.adapters.discord.api.types import UNSET, InteractionCallbackType, MessageFlag
from nonebot.adapters.discord.commands.matcher import ApplicationCommandConfig, SlashCommandMatcher, on_slash_command
from nonebot.adapters.discord.commands.storage import _application_command_storage
from nonebot.adapters.discord.event import ApplicationCommandInteractionEvent
Expand All @@ -35,7 +35,8 @@
from nonebot.typing import T_Handler, T_PermissionChecker, T_RuleChecker, T_State
from tarina import LRU, lang

from nonebot_plugin_alconna import At, Extension, Image, UniMessage, log
from nonebot_plugin_alconna import At, Extension, Image, UniMessage
from nonebot_plugin_alconna.consts import log
from nonebot_plugin_alconna.extension import cache_msg
from nonebot_plugin_alconna.matcher import _M, AlconnaMatcher

Expand All @@ -59,9 +60,7 @@ def _translate_args(args: Args) -> list[AnyCommandOption]:
name=f"{arg.name}",
description=f"{arg.notice or arg.name}",
required=not arg.optional,
choices=[
OptionChoice(name=str(x), value=x) for x in arg.value.base # type: ignore # noqa: E501
],
choices=[OptionChoice(name=str(x), value=x) for x in arg.value.base if isinstance(x, int)],
)
)
elif all(isinstance(x, float) for x in arg.value.base):
Expand All @@ -70,9 +69,7 @@ def _translate_args(args: Args) -> list[AnyCommandOption]:
name=f"{arg.name}",
description=f"{arg.notice or arg.name}",
required=not arg.optional,
choices=[
OptionChoice(name=str(x), value=x) for x in arg.value.base # type: ignore # noqa: E501
],
choices=[OptionChoice(name=str(x), value=x) for x in arg.value.base if isinstance(x, float)],
)
)
else:
Expand Down Expand Up @@ -176,7 +173,7 @@ def _translate_args(args: Args) -> list[AnyCommandOption]:
return result


def _translate_options(opt: Union[Option, Subcommand]) -> Union[SubCommandGroupOption, SubCommandOption]:
def _translate_options(opt: Union[Option, Subcommand]) -> AnyCommandOption:
if isinstance(opt, Option):
return SubCommandOption(
name=f"{opt.name}",
Expand All @@ -190,7 +187,9 @@ def _translate_options(opt: Union[Option, Subcommand]) -> Union[SubCommandGroupO
)
if not opt.args.empty:
return SubCommandOption(
name=f"{opt.name}", description=f"{opt.help_text}", options=_translate_args(opt.args) # type: ignore
name=f"{opt.name}",
description=f"{opt.help_text}",
options=_translate_args(opt.args), # type: ignore
)
return SubCommandGroupOption(
name=f"{opt.name}",
Expand Down Expand Up @@ -239,6 +238,10 @@ def translate(
"options": options,
**locals(),
}
if default_permission is None:
buffer.pop("default_permission")
if nsfw is None:
buffer.pop("nsfw")
buffer["_depth"] += 1
buffer.pop("alc")
return on_slash_command(**buffer)
Expand Down Expand Up @@ -316,11 +319,11 @@ def post_init(self, alc: Alconna) -> None:
name_localizations=self.name_localizations,
description=self.description or alc.meta.description,
description_localizations=self.description_localizations,
options=options, # type: ignore
options=options,
default_member_permissions=self.default_member_permissions,
dm_permission=self.dm_permission,
default_permission=self.default_permission,
nsfw=self.nsfw,
default_permission=self.default_permission if self.default_permission is not None else UNSET,
nsfw=self.nsfw if self.nsfw is not None else UNSET,
)
_application_command_storage[self.internal_id or config.name] = config
self.application_command = config
Expand Down Expand Up @@ -355,12 +358,12 @@ def _handle_options(options: list[ApplicationCommandInteractionDataOption]):
ApplicationCommandOptionType.SUB_COMMAND_GROUP,
):
yield f"{opt.name}"
if opt.options:
if isinstance(opt.options, list):
yield from _handle_options(opt.options)
else:
yield f"{opt.value}"

if data.options:
if isinstance(data.options, list):
cmd += " "
cmd += " ".join(_handle_options(data.options))

Expand Down
2 changes: 1 addition & 1 deletion src/nonebot_plugin_alconna/uniseg/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def __init__(
self.private = private
self.source = source
self.self_id = self_id
self.extra = extra if extra else {}
self.extra = extra or {}
self.selector = None
if scope:
self.selector = partial(SCOPES[scope], self)
Expand Down
2 changes: 2 additions & 0 deletions tests/fake.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ def fake_discord_interaction_event(**field) -> "ApplicationCommandInteractionEve
field["application_id"] = 123456789
field["token"] = "sometoken" # noqa: S105
field["version"] = 1
field.setdefault("attachment_size_limit", 0)
field.setdefault("authorizing_integration_owners", {})

class FakeEvent(_fake):
pass
Expand Down
5 changes: 1 addition & 4 deletions tests/test_uniseg.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,11 @@ def test_persistence():
{"type": "image", "url": "https://example.com/1.jpg", "sticker": False},
{"type": "text", "text": "hello"},
]
assert (
msg.dump(json=True)
== """\
assert msg.dump(json=True) == """\
[{"type": "at", "flag": "user", "target": "123"}, \
{"type": "at", "flag": "channel", "target": "456"}, \
{"type": "image", "url": "https://example.com/1.jpg", "sticker": false}, \
{"type": "text", "text": "hello"}]"""
)

msg1 = [
{"type": "at", "flag": "user", "target": "456"},
Expand Down