hikari-arc 1.4.0__py3-none-any.whl → 2.0.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/command/slash.py CHANGED
@@ -25,8 +25,8 @@ if t.TYPE_CHECKING:
25
25
  from arc.abc.plugin import PluginBase
26
26
 
27
27
  __all__ = (
28
- "SlashCommandLike",
29
28
  "SlashCommand",
29
+ "SlashCommandLike",
30
30
  "SlashGroup",
31
31
  "SlashSubCommand",
32
32
  "SlashSubGroup",
@@ -108,7 +108,8 @@ class SlashCommand(CallableCommandBase[ClientT, hikari.api.SlashCommandBuilder])
108
108
  id=id,
109
109
  options=[option.to_command_option() for option in self.options.values()],
110
110
  default_member_permissions=self.default_permissions,
111
- is_dm_enabled=self.is_dm_enabled,
111
+ integration_types=self.integration_types,
112
+ context_types=self.invocation_contexts,
112
113
  is_nsfw=self.is_nsfw,
113
114
  name_localizations={str(key): value for key, value in self.name_localizations.items()},
114
115
  description_localizations={str(key): value for key, value in self.description_localizations.items()},
@@ -263,7 +264,8 @@ class SlashGroup(CommandBase[ClientT, hikari.api.SlashCommandBuilder]):
263
264
  id=id,
264
265
  options=[subcmd.to_command_option() for subcmd in self.children.values()],
265
266
  default_member_permissions=self.default_permissions,
266
- is_dm_enabled=self.is_dm_enabled,
267
+ integration_types=self.integration_types,
268
+ context_types=self.invocation_contexts,
267
269
  is_nsfw=self.is_nsfw,
268
270
  name_localizations={str(key): value for key, value in self.name_localizations.items()},
269
271
  description_localizations={str(key): value for key, value in self.description_localizations.items()},
@@ -363,7 +365,7 @@ class SlashGroup(CommandBase[ClientT, hikari.api.SlashCommandBuilder]):
363
365
  opt = next(o for o in subsub.options if o.name in subsubcmd.options and o.is_focused)
364
366
  local_opt = subsubcmd.options[opt.name]
365
367
 
366
- if not isinstance(local_opt, OptionWithChoices) or not local_opt.autocomplete_with:
368
+ if not isinstance(local_opt, OptionWithChoices) or not local_opt.autocomplete_with: # pyright: ignore reportUnknownMemberType
367
369
  raise AutocompleteError(
368
370
  f"Slash option got autocomplete interaction without autocomplete callback: '{local_opt.name}'."
369
371
  )
@@ -522,7 +524,8 @@ class SlashSubGroup(SubCommandBase[ClientT, SlashGroup[ClientT]]):
522
524
  autodefer=self._autodefer,
523
525
  default_permissions=hikari.UNDEFINED,
524
526
  is_nsfw=hikari.UNDEFINED,
525
- is_dm_enabled=hikari.UNDEFINED,
527
+ integration_types=hikari.UNDEFINED,
528
+ invocation_contexts=hikari.UNDEFINED,
526
529
  )
527
530
  )
528
531
 
@@ -675,7 +678,8 @@ class SlashSubCommand(
675
678
  autodefer=self._autodefer,
676
679
  default_permissions=hikari.UNDEFINED,
677
680
  is_nsfw=hikari.UNDEFINED,
678
- is_dm_enabled=hikari.UNDEFINED,
681
+ integration_types=hikari.UNDEFINED,
682
+ invocation_contexts=hikari.UNDEFINED,
679
683
  )
680
684
  )
681
685
 
@@ -739,7 +743,8 @@ def slash_command(
739
743
  description: str = "No description provided.",
740
744
  *,
741
745
  guilds: t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType = hikari.UNDEFINED,
742
- is_dm_enabled: bool | hikari.UndefinedType = hikari.UNDEFINED,
746
+ integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
747
+ invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
743
748
  is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
744
749
  autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
745
750
  default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
@@ -756,8 +761,10 @@ def slash_command(
756
761
  The description of the command
757
762
  guilds : t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType
758
763
  The guilds this command should be enabled in, if left as undefined, the command is global
759
- is_dm_enabled : bool | hikari.UndefinedType
760
- If True, the command is usable in direct messages
764
+ integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
765
+ The integration types this command supports the installation of
766
+ invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
767
+ The context types this command can be invoked in
761
768
  is_nsfw : bool | hikari.UndefinedType
762
769
  If True, the command is only usable in NSFW channels
763
770
  autodefer : bool | AutodeferMode | hikari.UndefinedType
@@ -804,7 +811,8 @@ def slash_command(
804
811
  description_localizations=description_localizations or {},
805
812
  default_permissions=default_permissions,
806
813
  guilds=guild_ids,
807
- is_dm_enabled=is_dm_enabled,
814
+ integration_types=integration_types,
815
+ invocation_contexts=invocation_contexts,
808
816
  is_nsfw=is_nsfw,
809
817
  )
810
818
 
arc/command/user.py CHANGED
@@ -46,7 +46,8 @@ class UserCommand(CallableCommandBase[ClientT, hikari.api.ContextMenuCommandBuil
46
46
  type=self.command_type,
47
47
  id=id,
48
48
  default_member_permissions=self.default_permissions,
49
- is_dm_enabled=self.is_dm_enabled,
49
+ context_types=self.invocation_contexts,
50
+ integration_types=self.integration_types,
50
51
  is_nsfw=self.is_nsfw,
51
52
  name_localizations={str(key): value for key, value in self.name_localizations.items()},
52
53
  )
@@ -70,7 +71,8 @@ def user_command(
70
71
  name: str,
71
72
  *,
72
73
  guilds: t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType = hikari.UNDEFINED,
73
- is_dm_enabled: bool | hikari.UndefinedType = hikari.UNDEFINED,
74
+ invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
75
+ integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
74
76
  is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
75
77
  autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
76
78
  default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
@@ -87,8 +89,10 @@ def user_command(
87
89
  The name of the command.
88
90
  guilds : t.Sequence[hikari.PartialGuild | hikari.Snowflakeish] | hikari.UndefinedType
89
91
  The guilds this command should be enabled in, if left as undefined, the command is global
90
- is_dm_enabled : bool | hikari.UndefinedType
91
- Whether this command is enabled in DMs.
92
+ integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
93
+ The integration types this command supports the installation of
94
+ invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
95
+ The context types this command can be invoked in
92
96
  is_nsfw : bool | hikari.UndefinedType
93
97
  Whether this command is NSFW.
94
98
  autodefer : bool | AutodeferMode | hikari.UndefinedType
@@ -117,7 +121,8 @@ def user_command(
117
121
  name=name,
118
122
  autodefer=AutodeferMode(autodefer) if isinstance(autodefer, bool) else autodefer,
119
123
  guilds=guild_ids,
120
- is_dm_enabled=is_dm_enabled,
124
+ invocation_contexts=invocation_contexts,
125
+ integration_types=integration_types,
121
126
  is_nsfw=is_nsfw,
122
127
  default_permissions=default_permissions,
123
128
  name_localizations=name_localizations or {},
arc/context/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from .autocomplete import AutocompleteData
2
2
  from .base import AutodeferMode, Context, InteractionResponse
3
3
 
4
- __all__ = ("Context", "InteractionResponse", "AutocompleteData", "AutodeferMode")
4
+ __all__ = ("AutocompleteData", "AutodeferMode", "Context", "InteractionResponse")
5
5
 
6
6
  # MIT License
7
7
  #
@@ -51,7 +51,7 @@ class AutocompleteData(t.Generic[ClientT, ChoiceT]):
51
51
  """
52
52
  if self.focused_option is None:
53
53
  return None
54
- return t.cast(ChoiceT | str, self.focused_option.value)
54
+ return t.cast("ChoiceT | str", self.focused_option.value)
55
55
 
56
56
  @property
57
57
  def guild_id(self) -> hikari.Snowflake | None:
@@ -68,19 +68,33 @@ class AutocompleteData(t.Generic[ClientT, ChoiceT]):
68
68
  """The member that triggered the interaction."""
69
69
  return self.interaction.member
70
70
 
71
+ @property
72
+ def invocation_context(self) -> hikari.ApplicationContextType:
73
+ """The context in which the interaction was invoked."""
74
+ return self.interaction.context
75
+
76
+ @property
77
+ def authorizing_integration_owners(self) -> t.Mapping[hikari.ApplicationIntegrationType, hikari.Snowflake]:
78
+ """Includes details about the authorizing user or server for the installation(s) relevant to the interaction.
79
+
80
+ For apps installed to a user, it can be used to tell the difference between the authorizing user
81
+ and the user that triggered an interaction (like a message component).
82
+ """
83
+ return self.interaction.authorizing_integration_owners
84
+
71
85
  @property
72
86
  def user(self) -> hikari.User:
73
87
  """The user that triggered the interaction."""
74
88
  return self.interaction.user
75
89
 
90
+ @property
91
+ def channel(self) -> hikari.InteractionChannel:
92
+ return self.interaction.channel
93
+
76
94
  def get_guild(self) -> hikari.Guild | None:
77
95
  """Get the guild that triggered the interaction."""
78
96
  return self.interaction.get_guild()
79
97
 
80
- def get_channel(self) -> hikari.TextableGuildChannel | None:
81
- """Get the channel that triggered the interaction."""
82
- return self.interaction.get_channel()
83
-
84
98
 
85
99
  # MIT License
86
100
  #
arc/context/base.py CHANGED
@@ -11,7 +11,7 @@ import alluka
11
11
  import attr
12
12
  import hikari
13
13
 
14
- from arc.abc.option import OptionType # noqa: TCH001 Needed for tests
14
+ from arc.abc.option import OptionType # noqa: TC001 Needed for tests
15
15
  from arc.errors import NoResponseIssuedError, ResponseAlreadyIssuedError
16
16
  from arc.internal.options import OPTIONTYPE_TO_TYPE, resolve_snowflake_value
17
17
  from arc.internal.types import ClientT, ResponseBuilderT
@@ -20,7 +20,7 @@ from arc.locale import CustomLocaleRequest
20
20
  if t.TYPE_CHECKING:
21
21
  from arc.abc.command import CallableCommandProto
22
22
 
23
- __all__ = ("Context", "InteractionResponse", "AutodeferMode")
23
+ __all__ = ("AutodeferMode", "Context", "InteractionResponse")
24
24
 
25
25
  logger = logging.getLogger(__name__)
26
26
 
@@ -105,7 +105,7 @@ class InteractionResponse:
105
105
  when a message response is issued.
106
106
  """
107
107
 
108
- __slots__ = ("_context", "_message", "_delete_after_task")
108
+ __slots__ = ("_context", "_delete_after_task", "_message")
109
109
 
110
110
  def __init__(self, context: Context[t.Any], message: hikari.Message | None = None) -> None:
111
111
  self._context: Context[t.Any] = context
@@ -247,18 +247,18 @@ class Context(t.Generic[ClientT]):
247
247
  """A context object that is proxying a Discord command interaction."""
248
248
 
249
249
  __slots__ = (
250
+ "_autodefer_task",
250
251
  "_client",
251
252
  "_command",
252
- "_interaction",
253
- "_responses",
254
- "_resp_builder",
255
- "_issued_response",
256
- "_response_lock",
257
- "_autodefer_task",
258
253
  "_created_at",
259
254
  "_has_command_failed",
260
- "_options",
261
255
  "_injection_ctx",
256
+ "_interaction",
257
+ "_issued_response",
258
+ "_options",
259
+ "_resp_builder",
260
+ "_response_lock",
261
+ "_responses",
262
262
  )
263
263
 
264
264
  def __init__(
@@ -341,11 +341,69 @@ class Context(t.Generic[ClientT]):
341
341
  """The ID of the channel the context represents."""
342
342
  return self._interaction.channel_id
343
343
 
344
+ @property
345
+ def channel(self) -> hikari.InteractionChannel:
346
+ """The channel the context represents."""
347
+ return self._interaction.channel
348
+
344
349
  @property
345
350
  def guild_id(self) -> hikari.Snowflake | None:
346
351
  """The ID of the guild the context represents. Will be None in DMs."""
347
352
  return self._interaction.guild_id
348
353
 
354
+ @property
355
+ def invocation_context(self) -> hikari.ApplicationContextType:
356
+ """The context in which the interaction was invoked.
357
+
358
+ This can be used to determine if the command was invoked in DMs, a guild, or a group DM.
359
+ """
360
+ return self._interaction.context
361
+
362
+ @property
363
+ def authorizing_integration_owners(self) -> t.Mapping[hikari.ApplicationIntegrationType, hikari.Snowflake]:
364
+ """Includes details about the authorizing user or guild for the installation(s) relevant to the interaction.
365
+
366
+ For apps installed to a user, it can be used to tell the difference between the authorizing user
367
+ and the user that triggered an interaction.
368
+ """
369
+ return self._interaction.authorizing_integration_owners
370
+
371
+ @property
372
+ def authorizing_guild_id(self) -> hikari.Snowflake | None:
373
+ """The ID of the guild that this command was installed in.
374
+
375
+ This will be `None` if the command was not installed in the guild.
376
+
377
+ This is a shorthand for
378
+
379
+ ```
380
+ authorizing_integration_owners.get(hikari.ApplicationIntegrationType.GUILD_INSTALL)
381
+ ```
382
+
383
+ !!! note
384
+ It is possible for both this value and `authorizing_user_id` to not be `None`, if the command is installed
385
+ in both a guild and by a user.
386
+ """
387
+ return self._interaction.authorizing_integration_owners.get(hikari.ApplicationIntegrationType.GUILD_INSTALL)
388
+
389
+ @property
390
+ def authorizing_user_id(self) -> hikari.Snowflake | None:
391
+ """The ID of the user that installed this command.
392
+
393
+ This will be `None` if the command was not installed by a user.
394
+
395
+ This is a shorthand for
396
+
397
+ ```
398
+ authorizing_integration_owners.get(hikari.ApplicationIntegrationType.USER_INSTALL)
399
+ ```
400
+
401
+ !!! note
402
+ It is possible for both this value and `authorizing_guild_id` to not be `None`, if the command is installed
403
+ in both a guild and by a user.
404
+ """
405
+ return self._interaction.authorizing_integration_owners.get(hikari.ApplicationIntegrationType.USER_INSTALL)
406
+
349
407
  @property
350
408
  def is_valid(self) -> bool:
351
409
  """Returns if the underlying interaction expired or not.
@@ -414,10 +472,6 @@ class Context(t.Generic[ClientT]):
414
472
  """Gets the guild this context represents, if any. Requires application cache."""
415
473
  return self._interaction.get_guild()
416
474
 
417
- def get_channel(self) -> hikari.TextableGuildChannel | None:
418
- """Gets the channel this context represents, None if in a DM. Requires application cache."""
419
- return self._interaction.get_channel()
420
-
421
475
  @t.overload
422
476
  def get_option(self, name: str, opt_type: t.Literal[OptionType.EMOJI]) -> hikari.Emoji | None: ...
423
477
 
arc/internal/__init__.py CHANGED
@@ -1,16 +1,7 @@
1
- from .about import __author__, __author_email__, __maintainer__, __version__
2
1
  from .deprecation import warn_deprecate
3
2
  from .version import CURRENT_VERSION, Version
4
3
 
5
- __all__ = (
6
- "warn_deprecate",
7
- "Version",
8
- "CURRENT_VERSION",
9
- "__author__",
10
- "__author_email__",
11
- "__maintainer__",
12
- "__version__",
13
- )
4
+ __all__ = ("CURRENT_VERSION", "Version", "warn_deprecate")
14
5
 
15
6
  # MIT License
16
7
  #
arc/internal/about.py CHANGED
@@ -1,11 +1,6 @@
1
1
  import typing as t
2
2
 
3
- __author__: t.Final[str] = "hypergonial"
4
- __author_email__: t.Final[str] = "git@hypergonial.com"
5
- __maintainer__: t.Final[str] = "hypergonial"
6
- __license__: t.Final[str] = "MIT"
7
- __url__: t.Final[str] = "https://github.com/hypergonial/hikari-arc"
8
- __version__: t.Final[str] = "1.4.0"
3
+ __version__: t.Final[str] = "2.0.0"
9
4
 
10
5
  # MIT License
11
6
  #
arc/internal/sync.py CHANGED
@@ -50,8 +50,9 @@ def _rebuild_hikari_command(
50
50
  description=command.description,
51
51
  options=list(command.options) if command.options else [],
52
52
  default_member_permissions=command.default_member_permissions,
53
- is_dm_enabled=command.is_dm_enabled,
54
53
  is_nsfw=command.is_nsfw,
54
+ integration_types=command.integration_types,
55
+ context_types=command.context_types,
55
56
  name_localizations=command.name_localizations,
56
57
  description_localizations=command.description_localizations,
57
58
  )
@@ -61,8 +62,9 @@ def _rebuild_hikari_command(
61
62
  id=command.id,
62
63
  type=command.type,
63
64
  default_member_permissions=command.default_member_permissions,
64
- is_dm_enabled=command.is_dm_enabled,
65
65
  is_nsfw=command.is_nsfw,
66
+ integration_types=command.integration_types,
67
+ context_types=command.context_types,
66
68
  name_localizations=command.name_localizations,
67
69
  )
68
70
  else:
@@ -93,7 +95,8 @@ def _compare_commands(arc_command: CommandBase[t.Any, t.Any], hk_command: hikari
93
95
  and arc_command.name == hk_command.name
94
96
  and cmd_dict.get("description") == getattr(hk_command, "description", None)
95
97
  and arc_command.is_nsfw == hk_command.is_nsfw
96
- and arc_command.is_dm_enabled == hk_command.is_dm_enabled
98
+ and set(arc_command.invocation_contexts) == set(hk_command.context_types)
99
+ and set(arc_command.integration_types) == set(hk_command.integration_types)
97
100
  and (
98
101
  hk_command.guild_id in arc_command.guilds
99
102
  if hk_command.guild_id is not None and arc_command.guilds is not hikari.UNDEFINED
arc/internal/version.py CHANGED
@@ -9,7 +9,7 @@ if t.TYPE_CHECKING:
9
9
  import typing_extensions as te
10
10
 
11
11
 
12
- __all__ = ("Version", "CURRENT_VERSION")
12
+ __all__ = ("CURRENT_VERSION", "Version")
13
13
 
14
14
 
15
15
  @total_ordering
arc/locale.py CHANGED
@@ -14,12 +14,12 @@ if t.TYPE_CHECKING:
14
14
  from arc.context.base import Context
15
15
 
16
16
  __all__ = (
17
- "LocaleRequestType",
17
+ "CommandLocaleRequest",
18
+ "CustomLocaleRequest",
18
19
  "LocaleRequest",
20
+ "LocaleRequestType",
19
21
  "LocaleResponse",
20
- "CommandLocaleRequest",
21
22
  "OptionLocaleRequest",
22
- "CustomLocaleRequest",
23
23
  )
24
24
 
25
25
 
arc/plugin.py CHANGED
@@ -11,7 +11,7 @@ from arc.internal.types import EventCallbackT, EventT, GatewayClientT, RESTClien
11
11
  if t.TYPE_CHECKING:
12
12
  from arc.context.base import AutodeferMode
13
13
 
14
- __all__ = ("RESTPluginBase", "GatewayPluginBase")
14
+ __all__ = ("GatewayPluginBase", "RESTPluginBase")
15
15
 
16
16
  P = t.ParamSpec("P")
17
17
  T = t.TypeVar("T")
@@ -33,8 +33,11 @@ class RESTPluginBase(PluginBase[RESTClientT]):
33
33
  autodefer : bool | AutodeferMode
34
34
  If True, all commands in this plugin will automatically defer if it is taking longer than 2 seconds to respond.
35
35
  This can be overridden on a per-command basis.
36
- is_dm_enabled : bool | hikari.UndefinedType
37
- Whether commands in this plugin are enabled in DMs
36
+ integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
37
+ The integration types that commands will support the installation of
38
+ This can be overridden on a per-command basis.
39
+ invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
40
+ The context types that commands can be invoked in
38
41
  This can be overridden on a per-command basis.
39
42
  default_permissions : hikari.Permissions | hikari.UndefinedType
40
43
  The default permissions for this plugin
@@ -81,8 +84,11 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
81
84
  autodefer : bool | AutodeferMode
82
85
  If True, all commands in this plugin will automatically defer if it is taking longer than 2 seconds to respond.
83
86
  This can be overridden on a per-command basis.
84
- is_dm_enabled : bool | hikari.UndefinedType
85
- Whether commands in this plugin are enabled in DMs
87
+ integration_types : t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType
88
+ The integration types that commands will support the installation of
89
+ This can be overridden on a per-command basis.
90
+ invocation_contexts : t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType
91
+ The context types that commands can be invoked in
86
92
  This can be overridden on a per-command basis.
87
93
  default_permissions : hikari.Permissions | hikari.UndefinedType
88
94
  The default permissions for this plugin
@@ -115,7 +121,8 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
115
121
  default_enabled_guilds: t.Sequence[hikari.Snowflakeish | hikari.PartialGuild]
116
122
  | hikari.UndefinedType = hikari.UNDEFINED,
117
123
  autodefer: bool | AutodeferMode | hikari.UndefinedType = hikari.UNDEFINED,
118
- is_dm_enabled: bool | hikari.UndefinedType = hikari.UNDEFINED,
124
+ integration_types: t.Sequence[hikari.ApplicationIntegrationType] | hikari.UndefinedType = hikari.UNDEFINED,
125
+ invocation_contexts: t.Sequence[hikari.ApplicationContextType] | hikari.UndefinedType = hikari.UNDEFINED,
119
126
  default_permissions: hikari.Permissions | hikari.UndefinedType = hikari.UNDEFINED,
120
127
  is_nsfw: bool | hikari.UndefinedType = hikari.UNDEFINED,
121
128
  ) -> None:
@@ -123,7 +130,8 @@ class GatewayPluginBase(PluginBase[GatewayClientT]):
123
130
  name=name,
124
131
  default_enabled_guilds=default_enabled_guilds,
125
132
  autodefer=autodefer,
126
- is_dm_enabled=is_dm_enabled,
133
+ integration_types=integration_types,
134
+ invocation_contexts=invocation_contexts,
127
135
  default_permissions=default_permissions,
128
136
  is_nsfw=is_nsfw,
129
137
  )
arc/utils/__init__.py CHANGED
@@ -26,32 +26,32 @@ from .loops import CronLoop, IntervalLoop, cron_loop, interval_loop
26
26
  from .ratelimiter import RateLimiter, RateLimiterExhaustedError
27
27
 
28
28
  __all__ = (
29
- "guild_only",
30
- "owner_only",
31
- "dm_only",
32
- "has_permissions",
33
- "bot_has_permissions",
34
- "global_limiter",
35
- "guild_limiter",
36
- "user_limiter",
37
- "member_limiter",
38
- "channel_limiter",
39
- "custom_limiter",
29
+ "CommandConcurrencyLimiter",
30
+ "ConcurrencyLimiter",
31
+ "CronLoop",
32
+ "IntervalLoop",
40
33
  "LimiterHook",
41
34
  "RateLimiter",
42
35
  "RateLimiterExhaustedError",
43
- "IntervalLoop",
44
- "interval_loop",
45
- "CronLoop",
36
+ "bot_has_permissions",
37
+ "channel_concurrency",
38
+ "channel_limiter",
46
39
  "cron_loop",
47
- "CommandConcurrencyLimiter",
48
- "ConcurrencyLimiter",
40
+ "custom_concurrency",
41
+ "custom_limiter",
42
+ "dm_only",
49
43
  "global_concurrency",
44
+ "global_limiter",
50
45
  "guild_concurrency",
51
- "channel_concurrency",
52
- "user_concurrency",
46
+ "guild_limiter",
47
+ "guild_only",
48
+ "has_permissions",
49
+ "interval_loop",
53
50
  "member_concurrency",
54
- "custom_concurrency",
51
+ "member_limiter",
52
+ "owner_only",
53
+ "user_concurrency",
54
+ "user_limiter",
55
55
  )
56
56
 
57
57
  # MIT License
@@ -9,14 +9,14 @@ from arc.context.base import Context
9
9
  from arc.internal.types import ClientT
10
10
 
11
11
  __all__ = (
12
- "ConcurrencyLimiter",
13
12
  "CommandConcurrencyLimiter",
13
+ "ConcurrencyLimiter",
14
+ "channel_concurrency",
15
+ "custom_concurrency",
14
16
  "global_concurrency",
15
17
  "guild_concurrency",
16
- "channel_concurrency",
17
- "user_concurrency",
18
18
  "member_concurrency",
19
- "custom_concurrency",
19
+ "user_concurrency",
20
20
  )
21
21
 
22
22
  KeyT = t.TypeVar("KeyT")
@@ -32,7 +32,7 @@ class _BoundedSemaphore(asyncio.BoundedSemaphore):
32
32
  class _Bucket(t.Generic[KeyT]):
33
33
  """Handles the concurrency limiting of a single item. (E.g. a single user or a channel)."""
34
34
 
35
- __slots__ = ("_key", "_max_concurrent", "_semaphore", "_limiter")
35
+ __slots__ = ("_key", "_limiter", "_max_concurrent", "_semaphore")
36
36
 
37
37
  def __init__(self, key: str, max_concurrent: int, limiter: ConcurrencyLimiter[KeyT]) -> None:
38
38
  self._key = key
@@ -74,7 +74,7 @@ class _Bucket(t.Generic[KeyT]):
74
74
 
75
75
 
76
76
  class _ConcurrencyLimiterContextManager(t.Generic[KeyT]):
77
- __slots__ = ("_limiter", "_item")
77
+ __slots__ = ("_item", "_limiter")
78
78
 
79
79
  def __init__(self, limiter: ConcurrencyLimiter[KeyT], item: KeyT) -> None:
80
80
  self._limiter = limiter
@@ -122,7 +122,7 @@ class ConcurrencyLimiter(t.Generic[KeyT]):
122
122
  - [`custom_concurrency()`][arc.utils.concurrency_limiter.custom_concurrency]
123
123
  """
124
124
 
125
- __slots__: t.Sequence[str] = ("_capacity", "_buckets", "_get_key")
125
+ __slots__: t.Sequence[str] = ("_buckets", "_capacity", "_get_key")
126
126
 
127
127
  def __init__(self, capacity: int, *, get_key_with: t.Callable[[KeyT], str]) -> None:
128
128
  self._capacity = capacity
@@ -10,16 +10,16 @@ from .limiters import (
10
10
  )
11
11
 
12
12
  __all__ = (
13
- "guild_only",
14
- "owner_only",
15
- "dm_only",
16
- "has_permissions",
13
+ "LimiterHook",
17
14
  "bot_has_permissions",
15
+ "channel_limiter",
16
+ "custom_limiter",
17
+ "dm_only",
18
18
  "global_limiter",
19
19
  "guild_limiter",
20
- "channel_limiter",
21
- "user_limiter",
20
+ "guild_only",
21
+ "has_permissions",
22
22
  "member_limiter",
23
- "custom_limiter",
24
- "LimiterHook",
23
+ "owner_only",
24
+ "user_limiter",
25
25
  )
arc/utils/hooks/basic.py CHANGED
@@ -5,7 +5,7 @@ import typing as t
5
5
  import hikari
6
6
 
7
7
  from arc.abc.hookable import HookResult
8
- from arc.context import Context # noqa: TCH001 Needed for DI to work
8
+ from arc.context import Context # noqa: TC001 Needed for DI to work
9
9
  from arc.errors import (
10
10
  BotMissingPermissionsError,
11
11
  DMOnlyError,
@@ -10,12 +10,12 @@ from arc.utils.ratelimiter import RateLimiter, RateLimiterExhaustedError
10
10
 
11
11
  __all__ = (
12
12
  "LimiterHook",
13
+ "channel_limiter",
14
+ "custom_limiter",
13
15
  "global_limiter",
14
16
  "guild_limiter",
15
- "channel_limiter",
16
- "user_limiter",
17
17
  "member_limiter",
18
- "custom_limiter",
18
+ "user_limiter",
19
19
  )
20
20
 
21
21
 
arc/utils/loops.py CHANGED
@@ -6,7 +6,7 @@ import sys
6
6
  import traceback
7
7
  import typing as t
8
8
 
9
- __all__ = ("IntervalLoop", "CronLoop", "interval_loop", "cron_loop")
9
+ __all__ = ("CronLoop", "IntervalLoop", "cron_loop", "interval_loop")
10
10
 
11
11
  P = t.ParamSpec("P")
12
12
 
@@ -25,7 +25,7 @@ class _LoopBase(abc.ABC, t.Generic[P]):
25
25
  - [`CronLoop`][arc.utils.loops.CronLoop]
26
26
  """
27
27
 
28
- __slots__ = ("_coro", "_task", "_failed", "_stop_next", "_run_on_start")
28
+ __slots__ = ("_coro", "_failed", "_run_on_start", "_stop_next", "_task")
29
29
 
30
30
  def __init__(self, callback: t.Callable[P, t.Awaitable[None]], *, run_on_start: bool = True) -> None:
31
31
  self._coro = callback
arc/utils/ratelimiter.py CHANGED
@@ -117,7 +117,7 @@ class RateLimiter(t.Generic[KeyT]):
117
117
  A callable that returns a key for the ratelimiter bucket.
118
118
  """
119
119
 
120
- __slots__ = ("period", "limit", "_buckets", "_get_key", "_gc_task")
120
+ __slots__ = ("_buckets", "_gc_task", "_get_key", "limit", "period")
121
121
 
122
122
  def __init__(self, period: float, limit: int, *, get_key_with: t.Callable[[KeyT], str]) -> None:
123
123
  self.period: float = period