hikari-arc 1.2.0__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arc/__init__.py +12 -1
- arc/__main__.py +1 -0
- arc/abc/__init__.py +2 -0
- arc/abc/client.py +246 -70
- arc/abc/command.py +15 -12
- arc/abc/error_handler.py +2 -4
- arc/abc/option.py +37 -8
- arc/abc/plugin.py +20 -21
- arc/client.py +1 -2
- arc/command/__init__.py +12 -0
- arc/command/option/__init__.py +7 -0
- arc/command/option/attachment.py +4 -1
- arc/command/option/bool.py +4 -1
- arc/command/option/channel.py +4 -1
- arc/command/option/custom/__init__.py +4 -0
- arc/command/option/custom/color.py +106 -0
- arc/command/option/custom/member.py +98 -0
- arc/command/option/float.py +4 -1
- arc/command/option/int.py +4 -1
- arc/command/option/mentionable.py +4 -1
- arc/command/option/role.py +4 -1
- arc/command/option/str.py +4 -1
- arc/command/option/user.py +4 -1
- arc/command/slash.py +17 -20
- arc/context/base.py +66 -29
- arc/errors.py +18 -0
- arc/extension.py +4 -8
- arc/internal/about.py +2 -2
- arc/internal/options.py +9 -4
- arc/internal/sigparse.py +19 -5
- arc/internal/sync.py +3 -3
- arc/internal/types.py +3 -1
- arc/utils/concurrency_limiter.py +9 -4
- arc/utils/ratelimiter.py +1 -1
- {hikari_arc-1.2.0.dist-info → hikari_arc-1.3.0.dist-info}/METADATA +17 -17
- hikari_arc-1.3.0.dist-info/RECORD +59 -0
- {hikari_arc-1.2.0.dist-info → hikari_arc-1.3.0.dist-info}/WHEEL +1 -1
- hikari_arc-1.2.0.dist-info/RECORD +0 -56
- {hikari_arc-1.2.0.dist-info → hikari_arc-1.3.0.dist-info}/LICENSE +0 -0
- {hikari_arc-1.2.0.dist-info → hikari_arc-1.3.0.dist-info}/top_level.txt +0 -0
arc/abc/command.py
CHANGED
|
@@ -361,7 +361,7 @@ class CommandBase(
|
|
|
361
361
|
async def _handle_exception(self, ctx: Context[ClientT], exc: Exception) -> None:
|
|
362
362
|
try:
|
|
363
363
|
if self.error_handler is not None:
|
|
364
|
-
await self.error_handler
|
|
364
|
+
await ctx._injection_ctx.call_with_async_di(self.error_handler, ctx, exc)
|
|
365
365
|
else:
|
|
366
366
|
raise exc
|
|
367
367
|
except Exception as exc:
|
|
@@ -402,12 +402,12 @@ class CommandBase(
|
|
|
402
402
|
return None
|
|
403
403
|
|
|
404
404
|
def _resolve_hooks(self) -> list[HookT[ClientT]]:
|
|
405
|
-
|
|
406
|
-
return
|
|
405
|
+
upstream_hooks = self.plugin._resolve_hooks() if self.plugin else self.client._hooks
|
|
406
|
+
return upstream_hooks + self._hooks
|
|
407
407
|
|
|
408
408
|
def _resolve_post_hooks(self) -> list[PostHookT[ClientT]]:
|
|
409
|
-
|
|
410
|
-
return
|
|
409
|
+
upstream_hooks = self.plugin._resolve_post_hooks() if self.plugin else self.client._post_hooks
|
|
410
|
+
return upstream_hooks + self._post_hooks
|
|
411
411
|
|
|
412
412
|
async def publish(self, guild: hikari.SnowflakeishOr[hikari.PartialGuild] | None = None) -> hikari.PartialCommand:
|
|
413
413
|
"""Publish this command to the given guild, or globally if no guild is provided.
|
|
@@ -549,10 +549,10 @@ class CommandBase(
|
|
|
549
549
|
try:
|
|
550
550
|
hooks = command._resolve_hooks()
|
|
551
551
|
for hook in hooks:
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
res =
|
|
552
|
+
if inspect.iscoroutinefunction(hook):
|
|
553
|
+
res = await ctx._injection_ctx.call_with_async_di(hook, ctx)
|
|
554
|
+
else:
|
|
555
|
+
res = ctx._injection_ctx.call_with_di(hook, ctx)
|
|
556
556
|
|
|
557
557
|
res = t.cast(HookResult | None, res)
|
|
558
558
|
|
|
@@ -570,9 +570,9 @@ class CommandBase(
|
|
|
570
570
|
post_hooks = command._resolve_post_hooks()
|
|
571
571
|
for hook in post_hooks:
|
|
572
572
|
if inspect.iscoroutinefunction(hook):
|
|
573
|
-
await hook
|
|
573
|
+
await ctx._injection_ctx.call_with_async_di(hook, ctx)
|
|
574
574
|
else:
|
|
575
|
-
hook
|
|
575
|
+
ctx._injection_ctx.call_with_di(hook, ctx)
|
|
576
576
|
except Exception as e:
|
|
577
577
|
await command._handle_exception(ctx, e)
|
|
578
578
|
finally:
|
|
@@ -585,6 +585,9 @@ class CommandBase(
|
|
|
585
585
|
"""Handle the callback of a command. Invoke all hooks and the callback, and handle any exceptions."""
|
|
586
586
|
# If hook aborted, stop invocation
|
|
587
587
|
|
|
588
|
+
injection_ctx = await self.client._create_overriding_ctx_for_command(ctx)
|
|
589
|
+
ctx._injection_ctx = injection_ctx
|
|
590
|
+
|
|
588
591
|
max_concurrency = command._resolve_concurrency_limiter()
|
|
589
592
|
|
|
590
593
|
if max_concurrency is not None and max_concurrency.is_exhausted(ctx):
|
|
@@ -599,7 +602,7 @@ class CommandBase(
|
|
|
599
602
|
if await self._handle_pre_hooks(command, ctx):
|
|
600
603
|
return
|
|
601
604
|
|
|
602
|
-
await
|
|
605
|
+
await injection_ctx.call_with_async_di(command.callback, ctx, *args, **kwargs)
|
|
603
606
|
|
|
604
607
|
except Exception as e:
|
|
605
608
|
ctx._has_command_failed = True
|
arc/abc/error_handler.py
CHANGED
|
@@ -27,12 +27,10 @@ class HasErrorHandler(abc.ABC, t.Generic[ClientT]):
|
|
|
27
27
|
@t.overload
|
|
28
28
|
def set_error_handler(
|
|
29
29
|
self, callback: None = ...
|
|
30
|
-
) -> t.Callable[[ErrorHandlerCallbackT[ClientT]], ErrorHandlerCallbackT[ClientT]]:
|
|
31
|
-
...
|
|
30
|
+
) -> t.Callable[[ErrorHandlerCallbackT[ClientT]], ErrorHandlerCallbackT[ClientT]]: ...
|
|
32
31
|
|
|
33
32
|
@t.overload
|
|
34
|
-
def set_error_handler(self, callback: ErrorHandlerCallbackT[ClientT]) -> ErrorHandlerCallbackT[ClientT]:
|
|
35
|
-
...
|
|
33
|
+
def set_error_handler(self, callback: ErrorHandlerCallbackT[ClientT]) -> ErrorHandlerCallbackT[ClientT]: ...
|
|
36
34
|
|
|
37
35
|
def set_error_handler(
|
|
38
36
|
self, callback: ErrorHandlerCallbackT[ClientT] | None = None
|
arc/abc/option.py
CHANGED
|
@@ -3,7 +3,6 @@ from __future__ import annotations
|
|
|
3
3
|
import abc
|
|
4
4
|
import enum
|
|
5
5
|
import typing as t
|
|
6
|
-
from typing import Any
|
|
7
6
|
|
|
8
7
|
import attr
|
|
9
8
|
import hikari
|
|
@@ -24,10 +23,12 @@ __all__ = (
|
|
|
24
23
|
"OptionWithChoicesParams",
|
|
25
24
|
"OptionBase",
|
|
26
25
|
"CommandOptionBase",
|
|
26
|
+
"ConverterOption",
|
|
27
27
|
"OptionType",
|
|
28
28
|
)
|
|
29
29
|
|
|
30
30
|
T = t.TypeVar("T")
|
|
31
|
+
OriginT = t.TypeVar("OriginT")
|
|
31
32
|
|
|
32
33
|
Option = t.Annotated
|
|
33
34
|
"""Alias for typing.Annotated.
|
|
@@ -49,8 +50,9 @@ arc.Option[int, arc.IntParams(...)]
|
|
|
49
50
|
class OptionType(enum.IntEnum):
|
|
50
51
|
"""The type of a command option.
|
|
51
52
|
|
|
52
|
-
This
|
|
53
|
-
|
|
53
|
+
This includes all hikari option types along with some custom ones.
|
|
54
|
+
|
|
55
|
+
Custom arc-specific options start with 10k.
|
|
54
56
|
"""
|
|
55
57
|
|
|
56
58
|
SUB_COMMAND = 1
|
|
@@ -92,6 +94,14 @@ class OptionType(enum.IntEnum):
|
|
|
92
94
|
ATTACHMENT = 11
|
|
93
95
|
"""Denotes a command option where the value will be an attachment."""
|
|
94
96
|
|
|
97
|
+
# Custom optiontypes are 10k+
|
|
98
|
+
|
|
99
|
+
MEMBER = 10001
|
|
100
|
+
"""Denotes a command option where the value will be resolved to a member."""
|
|
101
|
+
|
|
102
|
+
COLOR = 10002
|
|
103
|
+
"""Denotes a command option where the value will be a color."""
|
|
104
|
+
|
|
95
105
|
@classmethod
|
|
96
106
|
def from_hikari(cls, option_type: hikari.OptionType) -> OptionType:
|
|
97
107
|
"""Convert a hikari.OptionType to an OptionType."""
|
|
@@ -99,10 +109,13 @@ class OptionType(enum.IntEnum):
|
|
|
99
109
|
|
|
100
110
|
def to_hikari(self) -> hikari.OptionType:
|
|
101
111
|
"""Convert an OptionType to a hikari.OptionType."""
|
|
102
|
-
|
|
103
|
-
|
|
112
|
+
if self.value < 10000:
|
|
113
|
+
return hikari.OptionType(self.value)
|
|
104
114
|
|
|
105
|
-
|
|
115
|
+
if self is OptionType.MEMBER:
|
|
116
|
+
return hikari.OptionType.USER
|
|
117
|
+
else:
|
|
118
|
+
return hikari.OptionType.STRING
|
|
106
119
|
|
|
107
120
|
|
|
108
121
|
class OptionParams(t.Generic[T]):
|
|
@@ -273,15 +286,22 @@ class CommandOptionBase(OptionBase[T], t.Generic[T, ClientT, ParamsT]):
|
|
|
273
286
|
is_required: bool = True
|
|
274
287
|
"""Whether the option is required."""
|
|
275
288
|
|
|
289
|
+
arg_name: str
|
|
290
|
+
"""The name of the parameter this option represents.
|
|
291
|
+
This is going to be the same as `name` unless `name` was overriden.
|
|
292
|
+
"""
|
|
293
|
+
|
|
276
294
|
@classmethod
|
|
277
295
|
@abc.abstractmethod
|
|
278
|
-
def _from_params(cls, *, name: str, is_required: bool, params: ParamsT, **kwargs: t.Any) -> te.Self:
|
|
296
|
+
def _from_params(cls, *, name: str, arg_name: str, is_required: bool, params: ParamsT, **kwargs: t.Any) -> te.Self:
|
|
279
297
|
"""Construct a new Option instance from the given parameters object.
|
|
280
298
|
|
|
281
299
|
Parameters
|
|
282
300
|
----------
|
|
283
301
|
name : str
|
|
284
302
|
The name of the option
|
|
303
|
+
arg_name : str
|
|
304
|
+
The name of the parameter this option represents
|
|
285
305
|
is_required : bool
|
|
286
306
|
Whether the option is required
|
|
287
307
|
params : ParamsT
|
|
@@ -290,10 +310,19 @@ class CommandOptionBase(OptionBase[T], t.Generic[T, ClientT, ParamsT]):
|
|
|
290
310
|
Any additional keyword arguments to pass to the constructor
|
|
291
311
|
"""
|
|
292
312
|
|
|
293
|
-
def _to_dict(self) -> dict[str, Any]:
|
|
313
|
+
def _to_dict(self) -> dict[str, t.Any]:
|
|
294
314
|
return {**super()._to_dict(), "is_required": self.is_required}
|
|
295
315
|
|
|
296
316
|
|
|
317
|
+
@attr.define(slots=True, kw_only=True)
|
|
318
|
+
class ConverterOption(CommandOptionBase[T, ClientT, ParamsT], t.Generic[T, ClientT, ParamsT, OriginT]):
|
|
319
|
+
"""An option with a built-in converter."""
|
|
320
|
+
|
|
321
|
+
@abc.abstractmethod
|
|
322
|
+
def _convert_value(self, value: OriginT) -> T:
|
|
323
|
+
"""Convert the value to the desired type."""
|
|
324
|
+
|
|
325
|
+
|
|
297
326
|
@attr.define(slots=True, kw_only=True)
|
|
298
327
|
class OptionWithChoices(CommandOptionBase[ChoiceT, ClientT, ParamsT]):
|
|
299
328
|
"""An option that can have choices or be autocompleted."""
|
arc/abc/plugin.py
CHANGED
|
@@ -8,7 +8,7 @@ import typing as t
|
|
|
8
8
|
|
|
9
9
|
import hikari
|
|
10
10
|
|
|
11
|
-
from arc.abc.command import _CommandSettings
|
|
11
|
+
from arc.abc.command import CallableCommandBase, _CommandSettings
|
|
12
12
|
from arc.abc.concurrency_limiting import ConcurrencyLimiterProto, HasConcurrencyLimiter
|
|
13
13
|
from arc.abc.error_handler import HasErrorHandler
|
|
14
14
|
from arc.abc.hookable import Hookable
|
|
@@ -155,7 +155,7 @@ class PluginBase(HasErrorHandler[ClientT], Hookable[ClientT], HasConcurrencyLimi
|
|
|
155
155
|
async def _handle_exception(self, ctx: Context[ClientT], exc: Exception) -> None:
|
|
156
156
|
try:
|
|
157
157
|
if self.error_handler is not None:
|
|
158
|
-
await self.error_handler
|
|
158
|
+
await ctx._injection_ctx.call_with_async_di(self.error_handler, ctx, exc)
|
|
159
159
|
else:
|
|
160
160
|
raise exc
|
|
161
161
|
except Exception as exc:
|
|
@@ -209,16 +209,19 @@ class PluginBase(HasErrorHandler[ClientT], Hookable[ClientT], HasConcurrencyLimi
|
|
|
209
209
|
raise TypeError(f"Unknown command type '{type(command).__name__}'.")
|
|
210
210
|
|
|
211
211
|
@t.overload
|
|
212
|
-
def include(
|
|
213
|
-
|
|
212
|
+
def include(
|
|
213
|
+
self,
|
|
214
|
+
) -> t.Callable[[CallableCommandBase[ClientT, BuilderT]], CallableCommandBase[ClientT, BuilderT]]: ...
|
|
214
215
|
|
|
215
216
|
@t.overload
|
|
216
|
-
def include(self, command:
|
|
217
|
-
...
|
|
217
|
+
def include(self, command: CallableCommandBase[ClientT, BuilderT]) -> CallableCommandBase[ClientT, BuilderT]: ...
|
|
218
218
|
|
|
219
219
|
def include(
|
|
220
|
-
self, command:
|
|
221
|
-
) ->
|
|
220
|
+
self, command: CallableCommandBase[ClientT, BuilderT] | None = None
|
|
221
|
+
) -> (
|
|
222
|
+
CallableCommandBase[ClientT, BuilderT]
|
|
223
|
+
| t.Callable[[CallableCommandBase[ClientT, BuilderT]], CallableCommandBase[ClientT, BuilderT]]
|
|
224
|
+
):
|
|
222
225
|
"""Add a command to this plugin.
|
|
223
226
|
|
|
224
227
|
!!! note
|
|
@@ -235,7 +238,7 @@ class PluginBase(HasErrorHandler[ClientT], Hookable[ClientT], HasConcurrencyLimi
|
|
|
235
238
|
If the command is already included in this plugin.
|
|
236
239
|
"""
|
|
237
240
|
|
|
238
|
-
def decorator(command:
|
|
241
|
+
def decorator(command: CallableCommandBase[ClientT, BuilderT]) -> CallableCommandBase[ClientT, BuilderT]:
|
|
239
242
|
if command.plugin is not None:
|
|
240
243
|
raise ValueError(f"Command '{command.name}' is already registered with plugin '{command.plugin.name}'.")
|
|
241
244
|
|
|
@@ -320,12 +323,10 @@ class PluginBase(HasErrorHandler[ClientT], Hookable[ClientT], HasConcurrencyLimi
|
|
|
320
323
|
return group
|
|
321
324
|
|
|
322
325
|
@t.overload
|
|
323
|
-
def inject_dependencies(self, func: t.Callable[P, T]) -> t.Callable[P, T]:
|
|
324
|
-
...
|
|
326
|
+
def inject_dependencies(self, func: t.Callable[P, T]) -> t.Callable[P, T]: ...
|
|
325
327
|
|
|
326
328
|
@t.overload
|
|
327
|
-
def inject_dependencies(self) -> t.Callable[[t.Callable[P, T]], t.Callable[P, T]]:
|
|
328
|
-
...
|
|
329
|
+
def inject_dependencies(self) -> t.Callable[[t.Callable[P, T]], t.Callable[P, T]]: ...
|
|
329
330
|
|
|
330
331
|
def inject_dependencies(
|
|
331
332
|
self, func: t.Callable[P, T] | None = None
|
|
@@ -401,26 +402,24 @@ class PluginBase(HasErrorHandler[ClientT], Hookable[ClientT], HasConcurrencyLimi
|
|
|
401
402
|
@t.overload
|
|
402
403
|
def walk_commands(
|
|
403
404
|
self, command_type: t.Literal[hikari.CommandType.USER], *, callable_only: bool = False
|
|
404
|
-
) -> t.Iterator[UserCommand[ClientT]]:
|
|
405
|
-
...
|
|
405
|
+
) -> t.Iterator[UserCommand[ClientT]]: ...
|
|
406
406
|
|
|
407
407
|
@t.overload
|
|
408
408
|
def walk_commands(
|
|
409
409
|
self, command_type: t.Literal[hikari.CommandType.MESSAGE], *, callable_only: bool = False
|
|
410
|
-
) -> t.Iterator[MessageCommand[ClientT]]:
|
|
411
|
-
...
|
|
410
|
+
) -> t.Iterator[MessageCommand[ClientT]]: ...
|
|
412
411
|
|
|
413
412
|
@t.overload
|
|
414
413
|
def walk_commands(
|
|
415
414
|
self, command_type: t.Literal[hikari.CommandType.SLASH], *, callable_only: t.Literal[False]
|
|
416
|
-
) -> t.Iterator[
|
|
417
|
-
|
|
415
|
+
) -> t.Iterator[
|
|
416
|
+
SlashCommand[ClientT] | SlashSubCommand[ClientT] | SlashGroup[ClientT] | SlashSubGroup[ClientT]
|
|
417
|
+
]: ...
|
|
418
418
|
|
|
419
419
|
@t.overload
|
|
420
420
|
def walk_commands(
|
|
421
421
|
self, command_type: t.Literal[hikari.CommandType.SLASH], *, callable_only: t.Literal[True]
|
|
422
|
-
) -> t.Iterator[SlashCommand[ClientT] | SlashSubCommand[ClientT]]:
|
|
423
|
-
...
|
|
422
|
+
) -> t.Iterator[SlashCommand[ClientT] | SlashSubCommand[ClientT]]: ...
|
|
424
423
|
|
|
425
424
|
def walk_commands( # noqa: C901
|
|
426
425
|
self, command_type: hikari.CommandType, *, callable_only: bool = False
|
arc/client.py
CHANGED
|
@@ -18,8 +18,7 @@ if t.TYPE_CHECKING:
|
|
|
18
18
|
import typing_extensions as te
|
|
19
19
|
|
|
20
20
|
from arc import AutodeferMode
|
|
21
|
-
|
|
22
|
-
from .internal.types import EventCallbackT, EventT, ResponseBuilderT
|
|
21
|
+
from arc.internal.types import EventCallbackT, EventT, ResponseBuilderT
|
|
23
22
|
|
|
24
23
|
__all__ = (
|
|
25
24
|
"GatewayClientBase",
|
arc/command/__init__.py
CHANGED
|
@@ -6,10 +6,16 @@ from .option import (
|
|
|
6
6
|
BoolParams,
|
|
7
7
|
ChannelOption,
|
|
8
8
|
ChannelParams,
|
|
9
|
+
ColorOption,
|
|
10
|
+
ColorParams,
|
|
11
|
+
ColourOption,
|
|
12
|
+
ColourParams,
|
|
9
13
|
FloatOption,
|
|
10
14
|
FloatParams,
|
|
11
15
|
IntOption,
|
|
12
16
|
IntParams,
|
|
17
|
+
MemberOption,
|
|
18
|
+
MemberParams,
|
|
13
19
|
MentionableOption,
|
|
14
20
|
MentionableParams,
|
|
15
21
|
RoleOption,
|
|
@@ -56,6 +62,12 @@ __all__ = (
|
|
|
56
62
|
"MentionableParams",
|
|
57
63
|
"AttachmentOption",
|
|
58
64
|
"AttachmentParams",
|
|
65
|
+
"MemberOption",
|
|
66
|
+
"MemberParams",
|
|
67
|
+
"ColorOption",
|
|
68
|
+
"ColorParams",
|
|
69
|
+
"ColourOption",
|
|
70
|
+
"ColourParams",
|
|
59
71
|
"UserCommand",
|
|
60
72
|
"user_command",
|
|
61
73
|
"MessageCommand",
|
arc/command/option/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from .attachment import AttachmentOption, AttachmentParams
|
|
2
2
|
from .bool import BoolOption, BoolParams
|
|
3
3
|
from .channel import ChannelOption, ChannelParams
|
|
4
|
+
from .custom import ColorOption, ColorParams, ColourOption, ColourParams, MemberOption, MemberParams
|
|
4
5
|
from .float import FloatOption, FloatParams
|
|
5
6
|
from .int import IntOption, IntParams
|
|
6
7
|
from .mentionable import MentionableOption, MentionableParams
|
|
@@ -27,6 +28,12 @@ __all__ = (
|
|
|
27
28
|
"MentionableParams",
|
|
28
29
|
"AttachmentOption",
|
|
29
30
|
"AttachmentParams",
|
|
31
|
+
"MemberOption",
|
|
32
|
+
"MemberParams",
|
|
33
|
+
"ColorOption",
|
|
34
|
+
"ColorParams",
|
|
35
|
+
"ColourOption",
|
|
36
|
+
"ColourParams",
|
|
30
37
|
)
|
|
31
38
|
|
|
32
39
|
# MIT License
|
arc/command/option/attachment.py
CHANGED
|
@@ -52,9 +52,12 @@ class AttachmentOption(CommandOptionBase[hikari.Attachment, ClientT, AttachmentP
|
|
|
52
52
|
return OptionType.ATTACHMENT
|
|
53
53
|
|
|
54
54
|
@classmethod
|
|
55
|
-
def _from_params(
|
|
55
|
+
def _from_params(
|
|
56
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: AttachmentParams, **kwargs: t.Any
|
|
57
|
+
) -> te.Self:
|
|
56
58
|
return cls(
|
|
57
59
|
name=name,
|
|
60
|
+
arg_name=arg_name,
|
|
58
61
|
description=params.description,
|
|
59
62
|
is_required=is_required,
|
|
60
63
|
name_localizations=params.name_localizations,
|
arc/command/option/bool.py
CHANGED
|
@@ -51,9 +51,12 @@ class BoolOption(CommandOptionBase[bool, ClientT, BoolParams]):
|
|
|
51
51
|
return OptionType.BOOLEAN
|
|
52
52
|
|
|
53
53
|
@classmethod
|
|
54
|
-
def _from_params(
|
|
54
|
+
def _from_params(
|
|
55
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: BoolParams, **kwargs: t.Any
|
|
56
|
+
) -> te.Self:
|
|
55
57
|
return cls(
|
|
56
58
|
name=name,
|
|
59
|
+
arg_name=arg_name,
|
|
57
60
|
description=params.description,
|
|
58
61
|
is_required=is_required,
|
|
59
62
|
name_localizations=params.name_localizations,
|
arc/command/option/channel.py
CHANGED
|
@@ -63,10 +63,13 @@ class ChannelOption(CommandOptionBase[hikari.PartialChannel, ClientT, ChannelPar
|
|
|
63
63
|
return OptionType.CHANNEL
|
|
64
64
|
|
|
65
65
|
@classmethod
|
|
66
|
-
def _from_params(
|
|
66
|
+
def _from_params(
|
|
67
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: ChannelParams, **kwargs: t.Any
|
|
68
|
+
) -> te.Self:
|
|
67
69
|
channel_types = kwargs.pop("channel_types")
|
|
68
70
|
return cls(
|
|
69
71
|
name=name,
|
|
72
|
+
arg_name=arg_name,
|
|
70
73
|
description=params.description,
|
|
71
74
|
is_required=is_required,
|
|
72
75
|
name_localizations=params.name_localizations,
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
import attr
|
|
6
|
+
import hikari
|
|
7
|
+
|
|
8
|
+
from arc.abc.option import ConverterOption, OptionParams, OptionType
|
|
9
|
+
from arc.errors import OptionConverterFailureError
|
|
10
|
+
from arc.internal.types import ClientT
|
|
11
|
+
|
|
12
|
+
if t.TYPE_CHECKING:
|
|
13
|
+
import typing_extensions as te
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("ColorOption", "ColorParams", "ColourOption", "ColourParams")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@t.final
|
|
20
|
+
class ColorParams(OptionParams[hikari.Color]):
|
|
21
|
+
"""The parameters for a color option.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
description : str
|
|
26
|
+
The description of the option
|
|
27
|
+
|
|
28
|
+
Other Parameters
|
|
29
|
+
----------------
|
|
30
|
+
name : str
|
|
31
|
+
The name of the option. If not provided, the name of the parameter will be used.
|
|
32
|
+
name_localizations : Mapping[hikari.Locale, str] | None
|
|
33
|
+
The name of the option in different locales
|
|
34
|
+
description_localizations : Mapping[hikari.Locale, str] | None
|
|
35
|
+
The description of the option in different locales
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
__slots__ = ()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@attr.define(slots=True, kw_only=True)
|
|
42
|
+
class ColorOption(ConverterOption[hikari.Color, ClientT, ColorParams, str]):
|
|
43
|
+
"""A slash command option that represents a color.
|
|
44
|
+
|
|
45
|
+
??? hint
|
|
46
|
+
To add an option of this type to your command, add an argument to your command function with the following type hint:
|
|
47
|
+
```py
|
|
48
|
+
opt_name: arc.Option[hikari.Color, ColorParams(...)]
|
|
49
|
+
```
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def option_type(self) -> OptionType:
|
|
54
|
+
return OptionType.COLOR
|
|
55
|
+
|
|
56
|
+
def _convert_value(self, value: str) -> hikari.Color:
|
|
57
|
+
try:
|
|
58
|
+
return hikari.Color.of(value)
|
|
59
|
+
except ValueError as exc:
|
|
60
|
+
raise OptionConverterFailureError(
|
|
61
|
+
self, value, f"Option '{self.name}' expected a valid color, got {value!r}."
|
|
62
|
+
) from exc
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def _from_params(
|
|
66
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: ColorParams, **kwargs: t.Any
|
|
67
|
+
) -> te.Self:
|
|
68
|
+
return cls(
|
|
69
|
+
name=name,
|
|
70
|
+
arg_name=arg_name,
|
|
71
|
+
description=params.description,
|
|
72
|
+
is_required=is_required,
|
|
73
|
+
name_localizations=params.name_localizations,
|
|
74
|
+
description_localizations=params.description_localizations,
|
|
75
|
+
**kwargs,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
# God save the queen
|
|
80
|
+
ColourParams = ColorParams
|
|
81
|
+
"""An alias for `ColorParams`."""
|
|
82
|
+
|
|
83
|
+
ColourOption = ColorOption
|
|
84
|
+
"""An alias for `ColorOption`."""
|
|
85
|
+
|
|
86
|
+
# MIT License
|
|
87
|
+
#
|
|
88
|
+
# Copyright (c) 2023-present hypergonial
|
|
89
|
+
#
|
|
90
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
91
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
92
|
+
# in the Software without restriction, including without limitation the rights
|
|
93
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
94
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
95
|
+
# furnished to do so, subject to the following conditions:
|
|
96
|
+
#
|
|
97
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
98
|
+
# copies or substantial portions of the Software.
|
|
99
|
+
#
|
|
100
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
101
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
102
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
103
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
104
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
105
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
106
|
+
# SOFTWARE.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import typing as t
|
|
4
|
+
|
|
5
|
+
import attr
|
|
6
|
+
import hikari
|
|
7
|
+
|
|
8
|
+
from arc.abc.option import ConverterOption, OptionParams, OptionType
|
|
9
|
+
from arc.errors import OptionConverterFailureError
|
|
10
|
+
from arc.internal.types import ClientT
|
|
11
|
+
|
|
12
|
+
if t.TYPE_CHECKING:
|
|
13
|
+
import typing_extensions as te
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
__all__ = ("MemberOption", "MemberParams")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@t.final
|
|
20
|
+
class MemberParams(OptionParams[hikari.InteractionMember]):
|
|
21
|
+
"""The parameters for a member option.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
description : str
|
|
26
|
+
The description of the option
|
|
27
|
+
|
|
28
|
+
Other Parameters
|
|
29
|
+
----------------
|
|
30
|
+
name : str
|
|
31
|
+
The name of the option. If not provided, the name of the parameter will be used.
|
|
32
|
+
name_localizations : Mapping[hikari.Locale, str] | None
|
|
33
|
+
The name of the option in different locales
|
|
34
|
+
description_localizations : Mapping[hikari.Locale, str] | None
|
|
35
|
+
The description of the option in different locales
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
__slots__ = ()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@attr.define(slots=True, kw_only=True)
|
|
42
|
+
class MemberOption(ConverterOption[hikari.InteractionMember, ClientT, MemberParams, hikari.User]):
|
|
43
|
+
"""A slash command option that represents a member.
|
|
44
|
+
|
|
45
|
+
??? hint
|
|
46
|
+
To add an option of this type to your command, add an argument to your command function with the following type hint:
|
|
47
|
+
```py
|
|
48
|
+
opt_name: arc.Option[hikari.Member, MemberParams(...)]
|
|
49
|
+
```
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def option_type(self) -> OptionType:
|
|
54
|
+
return OptionType.MEMBER
|
|
55
|
+
|
|
56
|
+
def _convert_value(self, value: hikari.User) -> hikari.InteractionMember:
|
|
57
|
+
if isinstance(value, hikari.InteractionMember):
|
|
58
|
+
return value
|
|
59
|
+
raise OptionConverterFailureError(
|
|
60
|
+
self, value, f"Option '{self.name}' expected an InteractionMember, got {value!r}."
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
@classmethod
|
|
64
|
+
def _from_params(
|
|
65
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: MemberParams, **kwargs: t.Any
|
|
66
|
+
) -> te.Self:
|
|
67
|
+
return cls(
|
|
68
|
+
name=name,
|
|
69
|
+
arg_name=arg_name,
|
|
70
|
+
description=params.description,
|
|
71
|
+
is_required=is_required,
|
|
72
|
+
name_localizations=params.name_localizations,
|
|
73
|
+
description_localizations=params.description_localizations,
|
|
74
|
+
**kwargs,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# MIT License
|
|
79
|
+
#
|
|
80
|
+
# Copyright (c) 2023-present hypergonial
|
|
81
|
+
#
|
|
82
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
83
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
84
|
+
# in the Software without restriction, including without limitation the rights
|
|
85
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
86
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
87
|
+
# furnished to do so, subject to the following conditions:
|
|
88
|
+
#
|
|
89
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
90
|
+
# copies or substantial portions of the Software.
|
|
91
|
+
#
|
|
92
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
93
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
94
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
95
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
96
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
97
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
98
|
+
# SOFTWARE.
|
arc/command/option/float.py
CHANGED
|
@@ -103,9 +103,12 @@ class FloatOption(OptionWithChoices[float, ClientT, FloatParams[ClientT]]):
|
|
|
103
103
|
return OptionType.FLOAT
|
|
104
104
|
|
|
105
105
|
@classmethod
|
|
106
|
-
def _from_params(
|
|
106
|
+
def _from_params(
|
|
107
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: FloatParams[ClientT], **kwargs: t.Any
|
|
108
|
+
) -> te.Self:
|
|
107
109
|
return cls(
|
|
108
110
|
name=name,
|
|
111
|
+
arg_name=arg_name,
|
|
109
112
|
description=params.description,
|
|
110
113
|
is_required=is_required,
|
|
111
114
|
min=params.min,
|
arc/command/option/int.py
CHANGED
|
@@ -103,9 +103,12 @@ class IntOption(OptionWithChoices[int, ClientT, IntParams[ClientT]]):
|
|
|
103
103
|
return OptionType.INTEGER
|
|
104
104
|
|
|
105
105
|
@classmethod
|
|
106
|
-
def _from_params(
|
|
106
|
+
def _from_params(
|
|
107
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: IntParams[ClientT], **kwargs: t.Any
|
|
108
|
+
) -> te.Self:
|
|
107
109
|
return cls(
|
|
108
110
|
name=name,
|
|
111
|
+
arg_name=arg_name,
|
|
109
112
|
description=params.description,
|
|
110
113
|
is_required=is_required,
|
|
111
114
|
min=params.min,
|
|
@@ -53,9 +53,12 @@ class MentionableOption(CommandOptionBase[hikari.Role | hikari.User, ClientT, Me
|
|
|
53
53
|
return OptionType.MENTIONABLE
|
|
54
54
|
|
|
55
55
|
@classmethod
|
|
56
|
-
def _from_params(
|
|
56
|
+
def _from_params(
|
|
57
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: MentionableParams, **kwargs: t.Any
|
|
58
|
+
) -> te.Self:
|
|
57
59
|
return cls(
|
|
58
60
|
name=name,
|
|
61
|
+
arg_name=arg_name,
|
|
59
62
|
description=params.description,
|
|
60
63
|
is_required=is_required,
|
|
61
64
|
name_localizations=params.name_localizations,
|
arc/command/option/role.py
CHANGED
|
@@ -52,9 +52,12 @@ class RoleOption(CommandOptionBase[hikari.Role, ClientT, RoleParams]):
|
|
|
52
52
|
return OptionType.ROLE
|
|
53
53
|
|
|
54
54
|
@classmethod
|
|
55
|
-
def _from_params(
|
|
55
|
+
def _from_params(
|
|
56
|
+
cls, *, name: str, arg_name: str, is_required: bool, params: RoleParams, **kwargs: t.Any
|
|
57
|
+
) -> te.Self:
|
|
56
58
|
return cls(
|
|
57
59
|
name=name,
|
|
60
|
+
arg_name=arg_name,
|
|
58
61
|
description=params.description,
|
|
59
62
|
is_required=is_required,
|
|
60
63
|
name_localizations=params.name_localizations,
|