hikari-arc 1.3.3__tar.gz → 1.3.4__tar.gz

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.
Files changed (80) hide show
  1. {hikari_arc-1.3.3/hikari_arc.egg-info → hikari_arc-1.3.4}/PKG-INFO +5 -5
  2. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/client.py +4 -4
  3. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/about.py +1 -1
  4. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/hooks/basic.py +1 -3
  5. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/dev_requirements.txt +3 -3
  6. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/doc_requirements.txt +1 -1
  7. {hikari_arc-1.3.3 → hikari_arc-1.3.4/hikari_arc.egg-info}/PKG-INFO +5 -5
  8. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/hikari_arc.egg-info/SOURCES.txt +1 -0
  9. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/hikari_arc.egg-info/requires.txt +4 -4
  10. hikari_arc-1.3.4/tests/test_command.py +319 -0
  11. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/LICENSE +0 -0
  12. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/MANIFEST.in +0 -0
  13. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/README.md +0 -0
  14. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/__init__.py +0 -0
  15. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/__main__.py +0 -0
  16. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/__init__.py +0 -0
  17. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/command.py +0 -0
  18. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/concurrency_limiting.py +0 -0
  19. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/error_handler.py +0 -0
  20. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/hookable.py +0 -0
  21. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/limiter.py +0 -0
  22. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/option.py +0 -0
  23. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/abc/plugin.py +0 -0
  24. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/client.py +0 -0
  25. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/__init__.py +0 -0
  26. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/message.py +0 -0
  27. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/__init__.py +0 -0
  28. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/attachment.py +0 -0
  29. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/bool.py +0 -0
  30. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/channel.py +0 -0
  31. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/custom/__init__.py +0 -0
  32. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/custom/color.py +0 -0
  33. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/custom/member.py +0 -0
  34. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/float.py +0 -0
  35. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/int.py +0 -0
  36. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/mentionable.py +0 -0
  37. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/role.py +0 -0
  38. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/str.py +0 -0
  39. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/option/user.py +0 -0
  40. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/slash.py +0 -0
  41. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/command/user.py +0 -0
  42. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/context/__init__.py +0 -0
  43. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/context/autocomplete.py +0 -0
  44. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/context/base.py +0 -0
  45. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/errors.py +0 -0
  46. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/events.py +0 -0
  47. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/ext/__init__.py +0 -0
  48. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/extension.py +0 -0
  49. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/__init__.py +0 -0
  50. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/deprecation.py +0 -0
  51. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/options.py +0 -0
  52. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/sigparse.py +0 -0
  53. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/sync.py +0 -0
  54. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/types.py +0 -0
  55. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/internal/version.py +0 -0
  56. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/locale.py +0 -0
  57. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/plugin.py +0 -0
  58. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/py.typed +0 -0
  59. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/__init__.py +0 -0
  60. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/concurrency_limiter.py +0 -0
  61. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/hooks/__init__.py +0 -0
  62. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/hooks/limiters.py +0 -0
  63. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/loops.py +0 -0
  64. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/arc/utils/ratelimiter.py +0 -0
  65. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/cron_requirements.txt +0 -0
  66. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/hikari_arc.egg-info/dependency_links.txt +0 -0
  67. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/hikari_arc.egg-info/not-zip-safe +0 -0
  68. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/hikari_arc.egg-info/top_level.txt +0 -0
  69. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/pyproject.toml +0 -0
  70. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/requirements.txt +0 -0
  71. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/rest_requirements.txt +0 -0
  72. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/setup.cfg +0 -0
  73. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/setup.py +0 -0
  74. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_client.py +0 -0
  75. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_context_command.py +0 -0
  76. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_di.py +0 -0
  77. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_inheritance.py +0 -0
  78. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_options.py +0 -0
  79. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_sigparse.py +0 -0
  80. {hikari_arc-1.3.3 → hikari_arc-1.3.4}/tests/test_slash.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hikari-arc
3
- Version: 1.3.3
3
+ Version: 1.3.4
4
4
  Summary: A command handler for hikari with a focus on type-safety and correctness.
5
5
  Home-page: https://github.com/hypergonial/hikari-arc
6
6
  Author: hypergonial
@@ -28,17 +28,17 @@ Requires-Dist: alluka<0.4,>=0.3.0
28
28
  Requires-Dist: attrs>=23.1
29
29
  Requires-Dist: colorama; sys_platform == "win32"
30
30
  Provides-Extra: docs
31
- Requires-Dist: mkdocs-material[imaging]~=9.5.24; extra == "docs"
31
+ Requires-Dist: mkdocs-material[imaging]~=9.5.25; extra == "docs"
32
32
  Requires-Dist: mkdocs~=1.6.0; extra == "docs"
33
33
  Requires-Dist: mkdocstrings-python~=1.10.3; extra == "docs"
34
34
  Requires-Dist: black~=24.4.2; extra == "docs"
35
35
  Requires-Dist: griffe-inherited-docstrings~=1.0.0; extra == "docs"
36
36
  Requires-Dist: mkdocs-glightbox~=0.4.0; extra == "docs"
37
37
  Provides-Extra: dev
38
- Requires-Dist: ruff==0.4.5; extra == "dev"
39
- Requires-Dist: pyright==1.1.364; extra == "dev"
38
+ Requires-Dist: ruff==0.4.6; extra == "dev"
39
+ Requires-Dist: pyright==1.1.365; extra == "dev"
40
40
  Requires-Dist: nox==2024.4.15; extra == "dev"
41
- Requires-Dist: typing_extensions==4.11.0; extra == "dev"
41
+ Requires-Dist: typing_extensions==4.12.0; extra == "dev"
42
42
  Requires-Dist: pytest==8.2.1; extra == "dev"
43
43
  Requires-Dist: pytest-asyncio==0.23.7; extra == "dev"
44
44
  Requires-Dist: slotscheck==0.19.0; extra == "dev"
@@ -333,10 +333,10 @@ class Client(t.Generic[AppT], abc.ABC):
333
333
  inj_ctx = alluka.OverridingContext.from_client(self.injector)
334
334
 
335
335
  for hook in self._injection_hooks:
336
- if inspect.isawaitable(hook):
337
- await hook(ctx, inj_ctx) # type: ignore
338
- else:
339
- hook(ctx, inj_ctx)
336
+ res = hook(ctx, inj_ctx)
337
+
338
+ if inspect.isawaitable(res):
339
+ await res
340
340
  return inj_ctx
341
341
 
342
342
  def _provide_command_locale(self, request: CommandLocaleRequest) -> LocaleResponse:
@@ -5,7 +5,7 @@ __author_email__: t.Final[str] = "git@hypergonial.com"
5
5
  __maintainer__: t.Final[str] = "hypergonial"
6
6
  __license__: t.Final[str] = "MIT"
7
7
  __url__: t.Final[str] = "https://github.com/hypergonial/hikari-arc"
8
- __version__: t.Final[str] = "1.3.3"
8
+ __version__: t.Final[str] = "1.3.4"
9
9
 
10
10
  # MIT License
11
11
  #
@@ -5,6 +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
9
  from arc.errors import (
9
10
  BotMissingPermissionsError,
10
11
  DMOnlyError,
@@ -13,9 +14,6 @@ from arc.errors import (
13
14
  NotOwnerError,
14
15
  )
15
16
 
16
- if t.TYPE_CHECKING:
17
- from arc.context import Context
18
-
19
17
 
20
18
  def guild_only(ctx: Context[t.Any]) -> HookResult:
21
19
  """A pre-execution hook that aborts the execution of a command if it is invoked outside of a guild.
@@ -1,7 +1,7 @@
1
- ruff==0.4.5
2
- pyright==1.1.364
1
+ ruff==0.4.6
2
+ pyright==1.1.365
3
3
  nox==2024.4.15
4
- typing_extensions==4.11.0
4
+ typing_extensions==4.12.0
5
5
  pytest==8.2.1
6
6
  pytest-asyncio==0.23.7
7
7
  slotscheck==0.19.0
@@ -1,4 +1,4 @@
1
- mkdocs-material[imaging]~=9.5.24
1
+ mkdocs-material[imaging]~=9.5.25
2
2
  mkdocs~=1.6.0
3
3
  mkdocstrings-python~=1.10.3
4
4
  black~=24.4.2
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hikari-arc
3
- Version: 1.3.3
3
+ Version: 1.3.4
4
4
  Summary: A command handler for hikari with a focus on type-safety and correctness.
5
5
  Home-page: https://github.com/hypergonial/hikari-arc
6
6
  Author: hypergonial
@@ -28,17 +28,17 @@ Requires-Dist: alluka<0.4,>=0.3.0
28
28
  Requires-Dist: attrs>=23.1
29
29
  Requires-Dist: colorama; sys_platform == "win32"
30
30
  Provides-Extra: docs
31
- Requires-Dist: mkdocs-material[imaging]~=9.5.24; extra == "docs"
31
+ Requires-Dist: mkdocs-material[imaging]~=9.5.25; extra == "docs"
32
32
  Requires-Dist: mkdocs~=1.6.0; extra == "docs"
33
33
  Requires-Dist: mkdocstrings-python~=1.10.3; extra == "docs"
34
34
  Requires-Dist: black~=24.4.2; extra == "docs"
35
35
  Requires-Dist: griffe-inherited-docstrings~=1.0.0; extra == "docs"
36
36
  Requires-Dist: mkdocs-glightbox~=0.4.0; extra == "docs"
37
37
  Provides-Extra: dev
38
- Requires-Dist: ruff==0.4.5; extra == "dev"
39
- Requires-Dist: pyright==1.1.364; extra == "dev"
38
+ Requires-Dist: ruff==0.4.6; extra == "dev"
39
+ Requires-Dist: pyright==1.1.365; extra == "dev"
40
40
  Requires-Dist: nox==2024.4.15; extra == "dev"
41
- Requires-Dist: typing_extensions==4.11.0; extra == "dev"
41
+ Requires-Dist: typing_extensions==4.12.0; extra == "dev"
42
42
  Requires-Dist: pytest==8.2.1; extra == "dev"
43
43
  Requires-Dist: pytest-asyncio==0.23.7; extra == "dev"
44
44
  Requires-Dist: slotscheck==0.19.0; extra == "dev"
@@ -69,6 +69,7 @@ hikari_arc.egg-info/not-zip-safe
69
69
  hikari_arc.egg-info/requires.txt
70
70
  hikari_arc.egg-info/top_level.txt
71
71
  tests/test_client.py
72
+ tests/test_command.py
72
73
  tests/test_context_command.py
73
74
  tests/test_di.py
74
75
  tests/test_inheritance.py
@@ -10,16 +10,16 @@ croniter==2.0.5
10
10
  types-croniter==2.0.0.20240423
11
11
 
12
12
  [dev]
13
- ruff==0.4.5
14
- pyright==1.1.364
13
+ ruff==0.4.6
14
+ pyright==1.1.365
15
15
  nox==2024.4.15
16
- typing_extensions==4.11.0
16
+ typing_extensions==4.12.0
17
17
  pytest==8.2.1
18
18
  pytest-asyncio==0.23.7
19
19
  slotscheck==0.19.0
20
20
 
21
21
  [docs]
22
- mkdocs-material[imaging]~=9.5.24
22
+ mkdocs-material[imaging]~=9.5.25
23
23
  mkdocs~=1.6.0
24
24
  mkdocstrings-python~=1.10.3
25
25
  black~=24.4.2
@@ -0,0 +1,319 @@
1
+ import datetime
2
+
3
+ import hikari
4
+ import pytest
5
+ from hikari.users import UserImpl
6
+ from mock_client import MockClient, MockContext, MockPlugin
7
+
8
+ import arc
9
+
10
+ client = MockClient(hikari.GatewayBot(token="amongus"))
11
+
12
+
13
+ @pytest.fixture
14
+ def app() -> hikari.GatewayBot:
15
+ return build_app()
16
+
17
+
18
+ def build_app() -> hikari.GatewayBot:
19
+ return hikari.GatewayBot(token="amongus")
20
+
21
+
22
+ def build_user(app: hikari.GatewayBot, id: hikari.Snowflakeish = 123456789) -> hikari.User:
23
+ return UserImpl(
24
+ app=app,
25
+ id=hikari.Snowflake(id),
26
+ avatar_hash=None,
27
+ banner_hash=None,
28
+ global_name="Padoru",
29
+ accent_color=None,
30
+ flags=hikari.UserFlag.NONE,
31
+ discriminator="1234",
32
+ is_bot=False,
33
+ is_system=False,
34
+ username="Padoru",
35
+ )
36
+
37
+
38
+ def build_member(
39
+ app: hikari.GatewayBot,
40
+ id: hikari.Snowflakeish = 123456789,
41
+ *,
42
+ role_ids: list[hikari.Snowflake] | None = None,
43
+ permissions: hikari.Permissions | None = None,
44
+ ) -> hikari.InteractionMember:
45
+ return hikari.InteractionMember(
46
+ guild_id=hikari.Snowflake(123456789),
47
+ is_deaf=hikari.UNDEFINED,
48
+ is_mute=hikari.UNDEFINED,
49
+ is_pending=False,
50
+ nickname=None,
51
+ raw_communication_disabled_until=None,
52
+ role_ids=role_ids or [],
53
+ guild_avatar_hash=None,
54
+ joined_at=datetime.datetime(2021, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc),
55
+ permissions=permissions or hikari.Permissions.NONE,
56
+ premium_since=None,
57
+ user=build_user(app, id),
58
+ )
59
+
60
+
61
+ def build_inter(
62
+ app: hikari.GatewayBot,
63
+ *,
64
+ cmd_name: str,
65
+ options: list[hikari.CommandInteractionOption] | None = None,
66
+ resolved: hikari.ResolvedOptionData | None = None,
67
+ author_id: hikari.Snowflakeish = 123456789,
68
+ author_role_ids: list[hikari.Snowflake] | None = None,
69
+ author_perms: hikari.Permissions | None = None,
70
+ ) -> hikari.CommandInteraction:
71
+ parts = cmd_name.split(" ")
72
+
73
+ match len(parts):
74
+ case 1:
75
+ pass
76
+ case 2:
77
+ options = [
78
+ hikari.CommandInteractionOption(
79
+ name=parts[1], type=hikari.OptionType.SUB_COMMAND, value=None, options=options
80
+ )
81
+ ]
82
+ case 3:
83
+ options = [
84
+ hikari.CommandInteractionOption(
85
+ name=parts[1],
86
+ type=hikari.OptionType.SUB_COMMAND_GROUP,
87
+ value=None,
88
+ options=[
89
+ hikari.CommandInteractionOption(
90
+ name=parts[2], type=hikari.OptionType.SUB_COMMAND, value=None, options=options
91
+ )
92
+ ],
93
+ )
94
+ ]
95
+ case _:
96
+ raise ValueError("Invalid command name")
97
+
98
+ return hikari.CommandInteraction(
99
+ app=app,
100
+ id=hikari.Snowflake(123456789),
101
+ application_id=hikari.Snowflake(123456789),
102
+ command_id=hikari.Snowflake(123456789),
103
+ command_name=parts[0],
104
+ command_type=hikari.CommandType.SLASH,
105
+ entitlements=[],
106
+ app_permissions=hikari.Permissions.all_permissions(),
107
+ options=options,
108
+ resolved=resolved,
109
+ type=hikari.InteractionType.APPLICATION_COMMAND,
110
+ token="padoru padoru",
111
+ version=1,
112
+ channel_id=hikari.Snowflake(123456789),
113
+ guild_id=hikari.Snowflake(123456789),
114
+ guild_locale="en-US",
115
+ user=build_user(app, author_id),
116
+ member=build_member(app, author_id, role_ids=author_role_ids, permissions=author_perms),
117
+ locale="en-US",
118
+ )
119
+
120
+
121
+ class PluginCanHandleError(Exception):
122
+ pass
123
+
124
+
125
+ class GroupCanHandleError(Exception):
126
+ pass
127
+
128
+
129
+ class SubgroupCanHandleError(Exception):
130
+ pass
131
+
132
+
133
+ class CommandCanHandleError(Exception):
134
+ pass
135
+
136
+
137
+ @client.include
138
+ @arc.slash_command("ping")
139
+ async def ping(ctx: MockContext) -> None:
140
+ await ctx.respond("Pong!")
141
+
142
+
143
+ @client.include
144
+ @arc.with_hook(arc.owner_only)
145
+ @arc.slash_command("admin_ping")
146
+ async def ping_with_hook(ctx: MockContext) -> None:
147
+ await ctx.respond("Pong!")
148
+
149
+
150
+ @client.include
151
+ @arc.with_hook(arc.owner_only)
152
+ @arc.slash_command("admin_ping_err")
153
+ async def ping_with_hook_err(ctx: MockContext) -> None:
154
+ await ctx.respond("Pong!")
155
+
156
+
157
+ @ping_with_hook_err.set_error_handler
158
+ async def ping_with_hook_err_handler(ctx: MockContext, error: Exception) -> None:
159
+ if isinstance(error, arc.NotOwnerError):
160
+ await ctx.respond("❌ You are not the owner of the bot.")
161
+
162
+
163
+ @client.include
164
+ @arc.slash_command("sum")
165
+ async def sum(ctx: MockContext, a: arc.Option[int, arc.IntParams()], b: arc.Option[int, arc.IntParams()]) -> None:
166
+ await ctx.respond(f"Sum: {a + b}")
167
+
168
+
169
+ plugin = MockPlugin("test")
170
+ group = plugin.include_slash_group("group")
171
+ subgroup = group.include_subgroup("subgroup")
172
+
173
+ client.add_plugin(plugin)
174
+
175
+
176
+ @subgroup.include
177
+ @arc.slash_subcommand("nested")
178
+ async def nested(ctx: MockContext) -> None:
179
+ match ctx.author.id:
180
+ case 1:
181
+ raise CommandCanHandleError
182
+ case 2:
183
+ raise SubgroupCanHandleError
184
+ case 3:
185
+ raise GroupCanHandleError
186
+ case 4:
187
+ raise PluginCanHandleError
188
+ case 5:
189
+ raise Exception
190
+ case _:
191
+ await ctx.respond("Nested command!")
192
+
193
+
194
+ @nested.set_error_handler
195
+ async def nested_error_handler(ctx: MockContext, error: Exception) -> None:
196
+ if isinstance(error, CommandCanHandleError):
197
+ await ctx.respond("Command handled error")
198
+ return
199
+ raise error
200
+
201
+
202
+ @subgroup.set_error_handler
203
+ async def subgroup_error_handler(ctx: MockContext, error: Exception) -> None:
204
+ if isinstance(error, SubgroupCanHandleError):
205
+ await ctx.respond("Subgroup handled error")
206
+ return
207
+ raise error
208
+
209
+
210
+ @group.set_error_handler
211
+ async def group_error_handler(ctx: MockContext, error: Exception) -> None:
212
+ if isinstance(error, GroupCanHandleError):
213
+ await ctx.respond("Group handled error")
214
+ return
215
+ raise error
216
+
217
+
218
+ @plugin.set_error_handler
219
+ async def plugin_error_handler(ctx: MockContext, error: Exception) -> None:
220
+ if isinstance(error, PluginCanHandleError):
221
+ await ctx.respond("Plugin handled error")
222
+ return
223
+ raise error
224
+
225
+
226
+ @pytest.mark.asyncio
227
+ async def test_ping(app: hikari.GatewayBot) -> None:
228
+ response = await client.push_inter(build_inter(app, cmd_name="ping"))
229
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
230
+ assert response.content == "Pong!"
231
+
232
+
233
+ @pytest.mark.asyncio
234
+ async def test_sum(app: hikari.GatewayBot) -> None:
235
+ inter = build_inter(
236
+ app,
237
+ cmd_name="sum",
238
+ options=[
239
+ hikari.CommandInteractionOption(name="a", type=hikari.OptionType.INTEGER, value=3, options=None),
240
+ hikari.CommandInteractionOption(name="b", type=hikari.OptionType.INTEGER, value=2, options=None),
241
+ ],
242
+ )
243
+ response = await client.push_inter(inter)
244
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
245
+ assert response.content == "Sum: 5"
246
+
247
+
248
+ @pytest.mark.asyncio
249
+ async def test_admin_ping(app: hikari.GatewayBot) -> None:
250
+ inter = build_inter(app, cmd_name="admin_ping")
251
+ response = await client.push_inter(inter)
252
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
253
+ assert response.content == "Pong!"
254
+
255
+
256
+ @pytest.mark.asyncio
257
+ async def test_admin_ping_unprivileged(app: hikari.GatewayBot) -> None:
258
+ inter = build_inter(app, author_id=987654321, cmd_name="admin_ping")
259
+ response = await client.push_inter(inter)
260
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
261
+ # Unhandled error
262
+ assert response.content == "❌ Something went wrong. Please contact the bot developer."
263
+
264
+
265
+ @pytest.mark.asyncio
266
+ async def test_admin_ping_errhandler(app: hikari.GatewayBot) -> None:
267
+ inter = build_inter(app, author_id=987654321, cmd_name="admin_ping_err")
268
+ response = await client.push_inter(inter)
269
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
270
+ # Handled error
271
+ assert response.content == "❌ You are not the owner of the bot."
272
+
273
+
274
+ @pytest.mark.asyncio
275
+ async def test_nested_errhandler_ok(app: hikari.GatewayBot) -> None:
276
+ inter = build_inter(app, author_id=0, cmd_name="group subgroup nested")
277
+ response = await client.push_inter(inter)
278
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
279
+ assert response.content == "Nested command!"
280
+
281
+
282
+ @pytest.mark.asyncio
283
+ async def test_nested_errhandler_cmdhandler(app: hikari.GatewayBot) -> None:
284
+ inter = build_inter(app, author_id=1, cmd_name="group subgroup nested")
285
+ response = await client.push_inter(inter)
286
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
287
+ assert response.content == "Command handled error"
288
+
289
+
290
+ @pytest.mark.asyncio
291
+ async def test_nested_errhandler_subghandler(app: hikari.GatewayBot) -> None:
292
+ inter = build_inter(app, author_id=2, cmd_name="group subgroup nested")
293
+ response = await client.push_inter(inter)
294
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
295
+ assert response.content == "Subgroup handled error"
296
+
297
+
298
+ @pytest.mark.asyncio
299
+ async def test_nested_errhandler_grphandler(app: hikari.GatewayBot) -> None:
300
+ inter = build_inter(app, author_id=3, cmd_name="group subgroup nested")
301
+ response = await client.push_inter(inter)
302
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
303
+ assert response.content == "Group handled error"
304
+
305
+
306
+ @pytest.mark.asyncio
307
+ async def test_nested_errhandler_plghandler(app: hikari.GatewayBot) -> None:
308
+ inter = build_inter(app, author_id=4, cmd_name="group subgroup nested")
309
+ response = await client.push_inter(inter)
310
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
311
+ assert response.content == "Plugin handled error"
312
+
313
+
314
+ @pytest.mark.asyncio
315
+ async def test_nested_errhandler_unhandled(app: hikari.GatewayBot) -> None:
316
+ inter = build_inter(app, author_id=5, cmd_name="group subgroup nested")
317
+ response = await client.push_inter(inter)
318
+ assert isinstance(response, hikari.impl.InteractionMessageBuilder)
319
+ assert response.content == "❌ Something went wrong. Please contact the bot developer."
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes