hikari-arc 1.2.1__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 +10 -1
- arc/__main__.py +1 -0
- arc/abc/__init__.py +2 -0
- arc/abc/client.py +239 -66
- arc/abc/command.py +15 -12
- arc/abc/error_handler.py +2 -4
- arc/abc/option.py +37 -8
- arc/abc/plugin.py +13 -17
- 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 +12 -13
- arc/context/base.py +59 -22
- arc/errors.py +18 -0
- arc/extension.py +4 -8
- arc/internal/about.py +1 -1
- 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 +1 -1
- arc/utils/ratelimiter.py +1 -1
- {hikari_arc-1.2.1.dist-info → hikari_arc-1.3.0.dist-info}/METADATA +16 -16
- hikari_arc-1.3.0.dist-info/RECORD +59 -0
- {hikari_arc-1.2.1.dist-info → hikari_arc-1.3.0.dist-info}/WHEEL +1 -1
- hikari_arc-1.2.1.dist-info/RECORD +0 -56
- {hikari_arc-1.2.1.dist-info → hikari_arc-1.3.0.dist-info}/LICENSE +0 -0
- {hikari_arc-1.2.1.dist-info → hikari_arc-1.3.0.dist-info}/top_level.txt +0 -0
arc/__init__.py
CHANGED
|
@@ -9,6 +9,7 @@ https://arc.hypergonial.com
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
11
|
from alluka import Client as Injector
|
|
12
|
+
from alluka import OverridingContext as InjectorOverridingContext
|
|
12
13
|
from alluka import inject
|
|
13
14
|
|
|
14
15
|
from arc import abc, command, ext, utils
|
|
@@ -28,8 +29,11 @@ from .command import (
|
|
|
28
29
|
AttachmentParams,
|
|
29
30
|
BoolParams,
|
|
30
31
|
ChannelParams,
|
|
32
|
+
ColorParams,
|
|
33
|
+
ColourParams,
|
|
31
34
|
FloatParams,
|
|
32
35
|
IntParams,
|
|
36
|
+
MemberParams,
|
|
33
37
|
MentionableParams,
|
|
34
38
|
MessageCommand,
|
|
35
39
|
RoleParams,
|
|
@@ -65,6 +69,7 @@ from .errors import (
|
|
|
65
69
|
MaxConcurrencyReachedError,
|
|
66
70
|
NoResponseIssuedError,
|
|
67
71
|
NotOwnerError,
|
|
72
|
+
OptionConverterFailureError,
|
|
68
73
|
ResponseAlreadyIssuedError,
|
|
69
74
|
UnderCooldownError,
|
|
70
75
|
)
|
|
@@ -113,7 +118,7 @@ __all__ = (
|
|
|
113
118
|
"AutocompleteData",
|
|
114
119
|
"Option",
|
|
115
120
|
"Context",
|
|
116
|
-
"
|
|
121
|
+
"InjectorOverridingContext",
|
|
117
122
|
"BoolParams",
|
|
118
123
|
"IntParams",
|
|
119
124
|
"StrParams",
|
|
@@ -123,6 +128,9 @@ __all__ = (
|
|
|
123
128
|
"RoleParams",
|
|
124
129
|
"MentionableParams",
|
|
125
130
|
"AttachmentParams",
|
|
131
|
+
"MemberParams",
|
|
132
|
+
"ColorParams",
|
|
133
|
+
"ColourParams",
|
|
126
134
|
"SlashCommand",
|
|
127
135
|
"SlashGroup",
|
|
128
136
|
"SlashSubCommand",
|
|
@@ -158,6 +166,7 @@ __all__ = (
|
|
|
158
166
|
"ExtensionUnloadError",
|
|
159
167
|
"HookAbortError",
|
|
160
168
|
"InteractionResponseError",
|
|
169
|
+
"OptionConverterFailureError",
|
|
161
170
|
"PluginBase",
|
|
162
171
|
"RESTPluginBase",
|
|
163
172
|
"GatewayPluginBase",
|
arc/__main__.py
CHANGED
arc/abc/__init__.py
CHANGED
|
@@ -8,6 +8,7 @@ from .hookable import Hookable, HookResult, with_hook, with_post_hook
|
|
|
8
8
|
from .limiter import LimiterProto
|
|
9
9
|
from .option import (
|
|
10
10
|
CommandOptionBase,
|
|
11
|
+
ConverterOption,
|
|
11
12
|
Option,
|
|
12
13
|
OptionBase,
|
|
13
14
|
OptionParams,
|
|
@@ -29,6 +30,7 @@ __all__ = (
|
|
|
29
30
|
"OptionBase",
|
|
30
31
|
"OptionType",
|
|
31
32
|
"CommandOptionBase",
|
|
33
|
+
"ConverterOption",
|
|
32
34
|
"OptionParams",
|
|
33
35
|
"OptionWithChoices",
|
|
34
36
|
"OptionWithChoicesParams",
|
arc/abc/client.py
CHANGED
|
@@ -22,6 +22,7 @@ from arc.command.slash import SlashCommand, SlashGroup, SlashSubCommand, SlashSu
|
|
|
22
22
|
from arc.command.user import UserCommand
|
|
23
23
|
from arc.context import AutodeferMode, Context
|
|
24
24
|
from arc.errors import ExtensionLoadError, ExtensionUnloadError
|
|
25
|
+
from arc.internal.deprecation import warn_deprecate
|
|
25
26
|
from arc.internal.sync import _sync_commands
|
|
26
27
|
from arc.internal.types import (
|
|
27
28
|
AppT,
|
|
@@ -30,11 +31,13 @@ from arc.internal.types import (
|
|
|
30
31
|
CustomLocaleRequestT,
|
|
31
32
|
ErrorHandlerCallbackT,
|
|
32
33
|
HookT,
|
|
34
|
+
InjectionHookT,
|
|
33
35
|
LifeCycleHookT,
|
|
34
36
|
OptionLocaleRequestT,
|
|
35
37
|
PostHookT,
|
|
36
38
|
ResponseBuilderT,
|
|
37
39
|
)
|
|
40
|
+
from arc.internal.version import Version
|
|
38
41
|
from arc.locale import CommandLocaleRequest, LocaleResponse, OptionLocaleRequest
|
|
39
42
|
|
|
40
43
|
if t.TYPE_CHECKING:
|
|
@@ -98,10 +101,11 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
98
101
|
"_loaded_extensions",
|
|
99
102
|
"_hooks",
|
|
100
103
|
"_post_hooks",
|
|
104
|
+
"_injection_hooks",
|
|
101
105
|
"_owner_ids",
|
|
102
106
|
"_error_handler",
|
|
103
|
-
"
|
|
104
|
-
"
|
|
107
|
+
"_startup_hooks",
|
|
108
|
+
"_shutdown_hooks",
|
|
105
109
|
"_provided_locales",
|
|
106
110
|
"_command_locale_provider",
|
|
107
111
|
"_option_locale_provider",
|
|
@@ -149,14 +153,15 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
149
153
|
self._loaded_extensions: list[str] = []
|
|
150
154
|
self._hooks: list[HookT[te.Self]] = []
|
|
151
155
|
self._post_hooks: list[PostHookT[te.Self]] = []
|
|
156
|
+
self._injection_hooks: list[InjectionHookT[te.Self]] = []
|
|
152
157
|
self._owner_ids: list[hikari.Snowflake] = []
|
|
153
158
|
self._tasks: set[asyncio.Task[t.Any]] = set()
|
|
154
159
|
self._started: asyncio.Event = asyncio.Event()
|
|
155
160
|
self._application: hikari.Application | None = None
|
|
156
161
|
self._error_handler: ErrorHandlerCallbackT[te.Self] | None = None
|
|
157
162
|
self._concurrency_limiter: ConcurrencyLimiterProto[te.Self] | None = None
|
|
158
|
-
self.
|
|
159
|
-
self.
|
|
163
|
+
self._startup_hooks: list[LifeCycleHookT[te.Self] | None] = [None]
|
|
164
|
+
self._shutdown_hooks: list[LifeCycleHookT[te.Self] | None] = [None]
|
|
160
165
|
self._command_locale_provider: CommandLocaleRequestT | None = None
|
|
161
166
|
self._option_locale_provider: OptionLocaleRequestT | None = None
|
|
162
167
|
self._custom_locale_provider: CustomLocaleRequestT | None = None
|
|
@@ -285,8 +290,13 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
285
290
|
await _sync_commands(self)
|
|
286
291
|
|
|
287
292
|
try:
|
|
288
|
-
|
|
289
|
-
|
|
293
|
+
for hook in self._startup_hooks:
|
|
294
|
+
if hook:
|
|
295
|
+
try:
|
|
296
|
+
await hook(self)
|
|
297
|
+
except Exception as e:
|
|
298
|
+
logger.error(f"Error in startup hook '{hook.__name__}': {e}")
|
|
299
|
+
traceback.print_exc()
|
|
290
300
|
finally:
|
|
291
301
|
self._started.set()
|
|
292
302
|
|
|
@@ -294,8 +304,16 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
294
304
|
"""Called when the client is shutting down.
|
|
295
305
|
Reserved for internal shutdown logic.
|
|
296
306
|
"""
|
|
297
|
-
|
|
298
|
-
|
|
307
|
+
for hook in self._shutdown_hooks:
|
|
308
|
+
if hook:
|
|
309
|
+
try:
|
|
310
|
+
await hook(self)
|
|
311
|
+
except Exception as e:
|
|
312
|
+
logger.error(f"Error in shutdown hook '{hook.__name__}': {e}")
|
|
313
|
+
traceback.print_exc()
|
|
314
|
+
|
|
315
|
+
for task in self._tasks:
|
|
316
|
+
task.cancel()
|
|
299
317
|
|
|
300
318
|
async def _on_error(self, ctx: Context[te.Self], exception: Exception) -> None:
|
|
301
319
|
if self._error_handler is not None:
|
|
@@ -311,6 +329,16 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
311
329
|
if ctx.is_valid:
|
|
312
330
|
await ctx.respond("❌ Something went wrong. Please contact the bot developer.")
|
|
313
331
|
|
|
332
|
+
async def _create_overriding_ctx_for_command(self, ctx: Context[te.Self]) -> alluka.OverridingContext:
|
|
333
|
+
inj_ctx = alluka.OverridingContext.from_client(self.injector)
|
|
334
|
+
|
|
335
|
+
for hook in self._injection_hooks:
|
|
336
|
+
if inspect.iscoroutinefunction(hook):
|
|
337
|
+
await hook(ctx, inj_ctx)
|
|
338
|
+
else:
|
|
339
|
+
hook(ctx, inj_ctx)
|
|
340
|
+
return inj_ctx
|
|
341
|
+
|
|
314
342
|
def _provide_command_locale(self, request: CommandLocaleRequest) -> LocaleResponse:
|
|
315
343
|
"""Provide a locale for a command."""
|
|
316
344
|
if self._command_locale_provider is None:
|
|
@@ -417,26 +445,24 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
417
445
|
@t.overload
|
|
418
446
|
def walk_commands(
|
|
419
447
|
self, command_type: t.Literal[hikari.CommandType.USER], *, callable_only: bool = False
|
|
420
|
-
) -> t.Iterator[UserCommand[te.Self]]:
|
|
421
|
-
...
|
|
448
|
+
) -> t.Iterator[UserCommand[te.Self]]: ...
|
|
422
449
|
|
|
423
450
|
@t.overload
|
|
424
451
|
def walk_commands(
|
|
425
452
|
self, command_type: t.Literal[hikari.CommandType.MESSAGE], *, callable_only: bool = False
|
|
426
|
-
) -> t.Iterator[MessageCommand[te.Self]]:
|
|
427
|
-
...
|
|
453
|
+
) -> t.Iterator[MessageCommand[te.Self]]: ...
|
|
428
454
|
|
|
429
455
|
@t.overload
|
|
430
456
|
def walk_commands(
|
|
431
457
|
self, command_type: t.Literal[hikari.CommandType.SLASH], *, callable_only: t.Literal[False] = False
|
|
432
|
-
) -> t.Iterator[
|
|
433
|
-
|
|
458
|
+
) -> t.Iterator[
|
|
459
|
+
SlashCommand[te.Self] | SlashSubCommand[te.Self] | SlashGroup[te.Self] | SlashSubGroup[te.Self]
|
|
460
|
+
]: ...
|
|
434
461
|
|
|
435
462
|
@t.overload
|
|
436
463
|
def walk_commands(
|
|
437
464
|
self, command_type: t.Literal[hikari.CommandType.SLASH], *, callable_only: t.Literal[True] = True
|
|
438
|
-
) -> t.Iterator[SlashCommand[te.Self] | SlashSubCommand[te.Self]]:
|
|
439
|
-
...
|
|
465
|
+
) -> t.Iterator[SlashCommand[te.Self] | SlashSubCommand[te.Self]]: ...
|
|
440
466
|
|
|
441
467
|
def walk_commands( # noqa: C901
|
|
442
468
|
self, command_type: hikari.CommandType, *, callable_only: bool = False
|
|
@@ -507,12 +533,12 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
507
533
|
yield command
|
|
508
534
|
|
|
509
535
|
@t.overload
|
|
510
|
-
def include(
|
|
511
|
-
|
|
536
|
+
def include(
|
|
537
|
+
self,
|
|
538
|
+
) -> t.Callable[[CallableCommandBase[te.Self, BuilderT]], CallableCommandBase[te.Self, BuilderT]]: ...
|
|
512
539
|
|
|
513
540
|
@t.overload
|
|
514
|
-
def include(self, command: CallableCommandBase[te.Self, BuilderT]) -> CallableCommandBase[te.Self, BuilderT]:
|
|
515
|
-
...
|
|
541
|
+
def include(self, command: CallableCommandBase[te.Self, BuilderT]) -> CallableCommandBase[te.Self, BuilderT]: ...
|
|
516
542
|
|
|
517
543
|
def include(
|
|
518
544
|
self, command: CallableCommandBase[te.Self, BuilderT] | None = None
|
|
@@ -703,12 +729,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
703
729
|
return self
|
|
704
730
|
|
|
705
731
|
@t.overload
|
|
706
|
-
def add_hook(self, hook: HookT[te.Self]) -> te.Self:
|
|
707
|
-
...
|
|
732
|
+
def add_hook(self, hook: HookT[te.Self]) -> te.Self: ...
|
|
708
733
|
|
|
709
734
|
@t.overload
|
|
710
|
-
def add_hook(self) -> t.Callable[[HookT[te.Self]], HookT[te.Self]]:
|
|
711
|
-
...
|
|
735
|
+
def add_hook(self) -> t.Callable[[HookT[te.Self]], HookT[te.Self]]: ...
|
|
712
736
|
|
|
713
737
|
def add_hook(self, hook: HookT[te.Self] | None = None) -> te.Self | t.Callable[[HookT[te.Self]], HookT[te.Self]]:
|
|
714
738
|
"""Add a pre-execution hook to this client.
|
|
@@ -739,12 +763,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
739
763
|
return decorator
|
|
740
764
|
|
|
741
765
|
@t.overload
|
|
742
|
-
def add_post_hook(self, hook: PostHookT[te.Self]) -> te.Self:
|
|
743
|
-
...
|
|
766
|
+
def add_post_hook(self, hook: PostHookT[te.Self]) -> te.Self: ...
|
|
744
767
|
|
|
745
768
|
@t.overload
|
|
746
|
-
def add_post_hook(self) -> t.Callable[[PostHookT[te.Self]], PostHookT[te.Self]]:
|
|
747
|
-
...
|
|
769
|
+
def add_post_hook(self) -> t.Callable[[PostHookT[te.Self]], PostHookT[te.Self]]: ...
|
|
748
770
|
|
|
749
771
|
def add_post_hook(
|
|
750
772
|
self, hook: PostHookT[te.Self] | None = None
|
|
@@ -780,12 +802,76 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
780
802
|
return decorator
|
|
781
803
|
|
|
782
804
|
@t.overload
|
|
783
|
-
def
|
|
784
|
-
...
|
|
805
|
+
def add_injection_hook(self, hook: InjectionHookT[te.Self]) -> te.Self: ...
|
|
785
806
|
|
|
786
807
|
@t.overload
|
|
787
|
-
def
|
|
788
|
-
|
|
808
|
+
def add_injection_hook(self) -> t.Callable[[InjectionHookT[te.Self]], InjectionHookT[te.Self]]: ...
|
|
809
|
+
|
|
810
|
+
def add_injection_hook(
|
|
811
|
+
self, hook: InjectionHookT[te.Self] | None = None
|
|
812
|
+
) -> te.Self | t.Callable[[InjectionHookT[te.Self]], InjectionHookT[te.Self]]:
|
|
813
|
+
"""Add an injection hook to this client.
|
|
814
|
+
This hook will be called when a command is called, and an OverridingContext is passed, allowing you to inject dependencies for the command call.
|
|
815
|
+
|
|
816
|
+
Parameters
|
|
817
|
+
----------
|
|
818
|
+
hook : InjectionHookT[te.Self]
|
|
819
|
+
The hook to add.
|
|
820
|
+
|
|
821
|
+
Returns
|
|
822
|
+
-------
|
|
823
|
+
te.Self
|
|
824
|
+
The client for chaining calls.
|
|
825
|
+
|
|
826
|
+
Example
|
|
827
|
+
-------
|
|
828
|
+
```py
|
|
829
|
+
@client.add_injection_hook
|
|
830
|
+
async def inject(ctx: arc.GatewayContext, inj_ctx: arc.InjectorOverridingContext) -> None:
|
|
831
|
+
foo: MyType = example_data[ctx.guild_id]
|
|
832
|
+
inj_ctx.set_type_dependency(MyType, foo)
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
See Also
|
|
836
|
+
--------
|
|
837
|
+
- [`Client.set_type_dependency`][arc.client.Client.set_type_dependency]
|
|
838
|
+
"""
|
|
839
|
+
if hook is not None:
|
|
840
|
+
self._injection_hooks.append(hook)
|
|
841
|
+
return self
|
|
842
|
+
|
|
843
|
+
def decorator(hook: InjectionHookT[te.Self]) -> InjectionHookT[te.Self]:
|
|
844
|
+
self._injection_hooks.append(hook)
|
|
845
|
+
return hook
|
|
846
|
+
|
|
847
|
+
return decorator
|
|
848
|
+
|
|
849
|
+
def remove_injection_hook(self, hook: InjectionHookT[te.Self]) -> te.Self:
|
|
850
|
+
"""Remove an injection hook from this client.
|
|
851
|
+
|
|
852
|
+
Parameters
|
|
853
|
+
----------
|
|
854
|
+
hook : InjectionHookT[te.Self]
|
|
855
|
+
The hook to remove.
|
|
856
|
+
|
|
857
|
+
Returns
|
|
858
|
+
-------
|
|
859
|
+
te.Self
|
|
860
|
+
The client for chaining calls.
|
|
861
|
+
|
|
862
|
+
Raises
|
|
863
|
+
------
|
|
864
|
+
ValueError
|
|
865
|
+
If the hook is not registered with this client.
|
|
866
|
+
"""
|
|
867
|
+
self._injection_hooks.remove(hook)
|
|
868
|
+
return self
|
|
869
|
+
|
|
870
|
+
@t.overload
|
|
871
|
+
def set_error_handler(self, handler: ErrorHandlerCallbackT[te.Self]) -> te.Self: ...
|
|
872
|
+
|
|
873
|
+
@t.overload
|
|
874
|
+
def set_error_handler(self) -> t.Callable[[ErrorHandlerCallbackT[te.Self]], te.Self]: ...
|
|
789
875
|
|
|
790
876
|
def set_error_handler(
|
|
791
877
|
self, handler: ErrorHandlerCallbackT[te.Self] | None = None
|
|
@@ -834,12 +920,104 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
834
920
|
return decorator
|
|
835
921
|
|
|
836
922
|
@t.overload
|
|
837
|
-
def
|
|
838
|
-
|
|
923
|
+
def add_startup_hook(self, hook: LifeCycleHookT[te.Self]) -> te.Self: ...
|
|
924
|
+
|
|
925
|
+
@t.overload
|
|
926
|
+
def add_startup_hook(self) -> t.Callable[[LifeCycleHookT[te.Self]], te.Self]: ...
|
|
927
|
+
|
|
928
|
+
def add_startup_hook(
|
|
929
|
+
self, hook: LifeCycleHookT[te.Self] | None = None
|
|
930
|
+
) -> te.Self | t.Callable[[LifeCycleHookT[te.Self]], te.Self]:
|
|
931
|
+
"""Decorator to add a startup hook for this client.
|
|
932
|
+
|
|
933
|
+
This will be called when the client starts up.
|
|
934
|
+
|
|
935
|
+
Parameters
|
|
936
|
+
----------
|
|
937
|
+
hook : LifeCycleHookT[te.Self]
|
|
938
|
+
The startup hook to add.
|
|
939
|
+
|
|
940
|
+
Returns
|
|
941
|
+
-------
|
|
942
|
+
te.Self
|
|
943
|
+
The client for chaining calls.
|
|
944
|
+
|
|
945
|
+
Examples
|
|
946
|
+
--------
|
|
947
|
+
```py
|
|
948
|
+
@client.add_startup_hook
|
|
949
|
+
async def startup_hook(client: arc.GatewayClient) -> None:
|
|
950
|
+
print("Client started up!")
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
Or, as a function:
|
|
954
|
+
|
|
955
|
+
```py
|
|
956
|
+
client.add_startup_hook(startup_hook)
|
|
957
|
+
```
|
|
958
|
+
"""
|
|
959
|
+
|
|
960
|
+
def decorator(handler: LifeCycleHookT[te.Self]) -> te.Self:
|
|
961
|
+
self._startup_hooks.append(handler)
|
|
962
|
+
return self
|
|
963
|
+
|
|
964
|
+
if hook is not None:
|
|
965
|
+
return decorator(hook)
|
|
966
|
+
|
|
967
|
+
return decorator
|
|
968
|
+
|
|
969
|
+
@t.overload
|
|
970
|
+
def add_shutdown_hook(self, hook: LifeCycleHookT[te.Self]) -> te.Self: ...
|
|
839
971
|
|
|
840
972
|
@t.overload
|
|
841
|
-
def
|
|
842
|
-
|
|
973
|
+
def add_shutdown_hook(self) -> t.Callable[[LifeCycleHookT[te.Self]], te.Self]: ...
|
|
974
|
+
|
|
975
|
+
def add_shutdown_hook(
|
|
976
|
+
self, hook: LifeCycleHookT[te.Self] | None = None
|
|
977
|
+
) -> te.Self | t.Callable[[LifeCycleHookT[te.Self]], te.Self]:
|
|
978
|
+
"""Decorator to add a shutdown hook for this client.
|
|
979
|
+
|
|
980
|
+
This will be called when the client shuts down.
|
|
981
|
+
|
|
982
|
+
Parameters
|
|
983
|
+
----------
|
|
984
|
+
hook : LifeCycleHookT[te.Self]
|
|
985
|
+
The shutdown hook to add.
|
|
986
|
+
|
|
987
|
+
Returns
|
|
988
|
+
-------
|
|
989
|
+
te.Self
|
|
990
|
+
The client for chaining calls.
|
|
991
|
+
|
|
992
|
+
Examples
|
|
993
|
+
--------
|
|
994
|
+
```py
|
|
995
|
+
@client.add_shutdown_hook
|
|
996
|
+
async def shutdown_hook(client: arc.GatewayClient) -> None:
|
|
997
|
+
print("Client shut down!")
|
|
998
|
+
```
|
|
999
|
+
|
|
1000
|
+
Or, as a function:
|
|
1001
|
+
|
|
1002
|
+
```py
|
|
1003
|
+
client.add_shutdown_hook(shutdown_hook)
|
|
1004
|
+
```
|
|
1005
|
+
"""
|
|
1006
|
+
|
|
1007
|
+
def decorator(handler: LifeCycleHookT[te.Self]) -> te.Self:
|
|
1008
|
+
self._shutdown_hooks.append(handler)
|
|
1009
|
+
return self
|
|
1010
|
+
|
|
1011
|
+
if hook is not None:
|
|
1012
|
+
return decorator(hook)
|
|
1013
|
+
|
|
1014
|
+
return decorator
|
|
1015
|
+
|
|
1016
|
+
@t.overload
|
|
1017
|
+
def set_startup_hook(self, hook: LifeCycleHookT[te.Self]) -> te.Self: ...
|
|
1018
|
+
|
|
1019
|
+
@t.overload
|
|
1020
|
+
def set_startup_hook(self) -> t.Callable[[LifeCycleHookT[te.Self]], te.Self]: ...
|
|
843
1021
|
|
|
844
1022
|
def set_startup_hook(
|
|
845
1023
|
self, hook: LifeCycleHookT[te.Self] | None = None
|
|
@@ -848,6 +1026,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
848
1026
|
|
|
849
1027
|
This will be called when the client starts up.
|
|
850
1028
|
|
|
1029
|
+
!!! warning "Deprecation Notice"
|
|
1030
|
+
This method is deprecated and will be removed in version `2.0.0`.
|
|
1031
|
+
Use [`Client.add_startup_hook`][arc.client.Client.add_startup_hook] instead.
|
|
1032
|
+
|
|
851
1033
|
Parameters
|
|
852
1034
|
----------
|
|
853
1035
|
hook : LifeCycleHookT[te.Self]
|
|
@@ -872,9 +1054,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
872
1054
|
client.set_startup_hook(startup_hook)
|
|
873
1055
|
```
|
|
874
1056
|
"""
|
|
1057
|
+
warn_deprecate(what="set_startup_hook", when=Version(2, 0, 0), use_instead="add_startup_hook")
|
|
875
1058
|
|
|
876
1059
|
def decorator(handler: LifeCycleHookT[te.Self]) -> te.Self:
|
|
877
|
-
self.
|
|
1060
|
+
self._startup_hooks[0] = handler
|
|
878
1061
|
return self
|
|
879
1062
|
|
|
880
1063
|
if hook is not None:
|
|
@@ -883,12 +1066,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
883
1066
|
return decorator
|
|
884
1067
|
|
|
885
1068
|
@t.overload
|
|
886
|
-
def set_shutdown_hook(self, hook: LifeCycleHookT[te.Self]) -> te.Self:
|
|
887
|
-
...
|
|
1069
|
+
def set_shutdown_hook(self, hook: LifeCycleHookT[te.Self]) -> te.Self: ...
|
|
888
1070
|
|
|
889
1071
|
@t.overload
|
|
890
|
-
def set_shutdown_hook(self) -> t.Callable[[LifeCycleHookT[te.Self]], te.Self]:
|
|
891
|
-
...
|
|
1072
|
+
def set_shutdown_hook(self) -> t.Callable[[LifeCycleHookT[te.Self]], te.Self]: ...
|
|
892
1073
|
|
|
893
1074
|
def set_shutdown_hook(
|
|
894
1075
|
self, hook: LifeCycleHookT[te.Self] | None = None
|
|
@@ -897,6 +1078,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
897
1078
|
|
|
898
1079
|
This will be called when the client shuts down.
|
|
899
1080
|
|
|
1081
|
+
!!! warning "Deprecation Notice"
|
|
1082
|
+
This method is deprecated and will be removed in version `2.0.0`.
|
|
1083
|
+
Use [`Client.add_shutdown_hook`][arc.client.Client.add_shutdown_hook] instead.
|
|
1084
|
+
|
|
900
1085
|
Parameters
|
|
901
1086
|
----------
|
|
902
1087
|
hook : LifeCycleHookT[te.Self]
|
|
@@ -921,9 +1106,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
921
1106
|
client.set_shutdown_hook(shutdown_hook)
|
|
922
1107
|
```
|
|
923
1108
|
"""
|
|
1109
|
+
warn_deprecate(what="set_shutdown_hook", when=Version(2, 0, 0), use_instead="add_shutdown_hook")
|
|
924
1110
|
|
|
925
1111
|
def decorator(handler: LifeCycleHookT[te.Self]) -> te.Self:
|
|
926
|
-
self.
|
|
1112
|
+
self._shutdown_hooks[0] = handler
|
|
927
1113
|
return self
|
|
928
1114
|
|
|
929
1115
|
if hook is not None:
|
|
@@ -932,12 +1118,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
932
1118
|
return decorator
|
|
933
1119
|
|
|
934
1120
|
@t.overload
|
|
935
|
-
def set_command_locale_provider(self, provider: CommandLocaleRequestT) -> te.Self:
|
|
936
|
-
...
|
|
1121
|
+
def set_command_locale_provider(self, provider: CommandLocaleRequestT) -> te.Self: ...
|
|
937
1122
|
|
|
938
1123
|
@t.overload
|
|
939
|
-
def set_command_locale_provider(self) -> t.Callable[[CommandLocaleRequestT], te.Self]:
|
|
940
|
-
...
|
|
1124
|
+
def set_command_locale_provider(self) -> t.Callable[[CommandLocaleRequestT], te.Self]: ...
|
|
941
1125
|
|
|
942
1126
|
def set_command_locale_provider(
|
|
943
1127
|
self, provider: CommandLocaleRequestT | None = None
|
|
@@ -981,12 +1165,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
981
1165
|
return decorator
|
|
982
1166
|
|
|
983
1167
|
@t.overload
|
|
984
|
-
def set_option_locale_provider(self, provider: OptionLocaleRequestT) -> te.Self:
|
|
985
|
-
...
|
|
1168
|
+
def set_option_locale_provider(self, provider: OptionLocaleRequestT) -> te.Self: ...
|
|
986
1169
|
|
|
987
1170
|
@t.overload
|
|
988
|
-
def set_option_locale_provider(self) -> t.Callable[[OptionLocaleRequestT], te.Self]:
|
|
989
|
-
...
|
|
1171
|
+
def set_option_locale_provider(self) -> t.Callable[[OptionLocaleRequestT], te.Self]: ...
|
|
990
1172
|
|
|
991
1173
|
def set_option_locale_provider(
|
|
992
1174
|
self, provider: OptionLocaleRequestT | None = None
|
|
@@ -1030,12 +1212,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
1030
1212
|
return decorator
|
|
1031
1213
|
|
|
1032
1214
|
@t.overload
|
|
1033
|
-
def set_custom_locale_provider(self, provider: CustomLocaleRequestT) -> te.Self:
|
|
1034
|
-
...
|
|
1215
|
+
def set_custom_locale_provider(self, provider: CustomLocaleRequestT) -> te.Self: ...
|
|
1035
1216
|
|
|
1036
1217
|
@t.overload
|
|
1037
|
-
def set_custom_locale_provider(self) -> t.Callable[[CustomLocaleRequestT], te.Self]:
|
|
1038
|
-
...
|
|
1218
|
+
def set_custom_locale_provider(self) -> t.Callable[[CustomLocaleRequestT], te.Self]: ...
|
|
1039
1219
|
|
|
1040
1220
|
def set_custom_locale_provider(
|
|
1041
1221
|
self, provider: CustomLocaleRequestT | None = None
|
|
@@ -1285,12 +1465,10 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
1285
1465
|
return self
|
|
1286
1466
|
|
|
1287
1467
|
@t.overload
|
|
1288
|
-
def get_type_dependency(self, type_: type[T]) -> T:
|
|
1289
|
-
...
|
|
1468
|
+
def get_type_dependency(self, type_: type[T]) -> T: ...
|
|
1290
1469
|
|
|
1291
1470
|
@t.overload
|
|
1292
|
-
def get_type_dependency(self, type_: type[T], *, default: DefaultT) -> T | DefaultT:
|
|
1293
|
-
...
|
|
1471
|
+
def get_type_dependency(self, type_: type[T], *, default: DefaultT) -> T | DefaultT: ...
|
|
1294
1472
|
|
|
1295
1473
|
def get_type_dependency(
|
|
1296
1474
|
self, type_: type[T], *, default: DefaultT | hikari.UndefinedType = hikari.UNDEFINED
|
|
@@ -1316,20 +1494,15 @@ class Client(t.Generic[AppT], abc.ABC):
|
|
|
1316
1494
|
If the dependency does not exist and `default` was not provided.
|
|
1317
1495
|
"""
|
|
1318
1496
|
if default is hikari.UNDEFINED:
|
|
1319
|
-
|
|
1320
|
-
if isinstance(value, alluka.abc.Undefined):
|
|
1321
|
-
raise KeyError(f"Could not resolve dependency of type {type_}.")
|
|
1322
|
-
return value
|
|
1497
|
+
return self._injector.get_type_dependency(type_)
|
|
1323
1498
|
else:
|
|
1324
1499
|
return self._injector.get_type_dependency(type_, default=default)
|
|
1325
1500
|
|
|
1326
1501
|
@t.overload
|
|
1327
|
-
def inject_dependencies(self, func: t.Callable[P, T]) -> t.Callable[P, T]:
|
|
1328
|
-
...
|
|
1502
|
+
def inject_dependencies(self, func: t.Callable[P, T]) -> t.Callable[P, T]: ...
|
|
1329
1503
|
|
|
1330
1504
|
@t.overload
|
|
1331
|
-
def inject_dependencies(self) -> t.Callable[[t.Callable[P, T]], t.Callable[P, T]]:
|
|
1332
|
-
...
|
|
1505
|
+
def inject_dependencies(self) -> t.Callable[[t.Callable[P, T]], t.Callable[P, T]]: ...
|
|
1333
1506
|
|
|
1334
1507
|
def inject_dependencies(
|
|
1335
1508
|
self, func: t.Callable[P, T] | None = None
|
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
|