disagreement 0.1.0rc2__tar.gz → 0.1.0rc3__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.
- disagreement-0.1.0rc3/MANIFEST.in +4 -0
- {disagreement-0.1.0rc2/disagreement.egg-info → disagreement-0.1.0rc3}/PKG-INFO +1 -1
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/__init__.py +8 -4
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/client.py +0 -4
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/handler.py +25 -12
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/hybrid.py +1 -1
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/cog.py +15 -6
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/core.py +20 -10
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/gateway.py +102 -63
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/http.py +19 -4
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/models.py +3 -6
- disagreement-0.1.0rc3/disagreement/py.typed +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3/disagreement.egg-info}/PKG-INFO +1 -1
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement.egg-info/SOURCES.txt +1 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/pyproject.toml +1 -1
- disagreement-0.1.0rc2/MANIFEST.in +0 -3
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/LICENSE +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/README.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/audio.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/cache.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/color.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/components.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/enums.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/error_handler.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/errors.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/event_dispatcher.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/__init__.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/__init__.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/commands.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/context.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/converters.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/app_commands/decorators.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/__init__.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/converters.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/decorators.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/errors.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/help.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/commands/view.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/loader.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ext/tasks.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/hybrid_context.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/i18n.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/interactions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/logging_config.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/oauth.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/permissions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/rate_limiter.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/shard_manager.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/typing.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/__init__.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/button.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/item.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/modal.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/select.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/ui/view.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/utils.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement/voice_client.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement.egg-info/dependency_links.txt +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement.egg-info/requires.txt +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/disagreement.egg-info/top_level.txt +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/caching.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/commands.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/context_menus.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/converters.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/events.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/extension_loader.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/gateway.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/i18n.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/message_history.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/oauth2.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/permissions.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/presence.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/reactions.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/sharding.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/slash_commands.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/task_loop.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/typing_indicator.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/using_components.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/voice_client.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/voice_features.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/docs/webhooks.md +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/basic_bot.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/component_bot.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/context_menus.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/extension_management.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/hybrid_bot.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/message_history.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/modal_command.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/modal_send.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/sample_extension.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/sharded_bot.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/task_loop.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/examples/voice_bot.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/setup.cfg +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_additional_converters.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_cache.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_channel_permissions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_client_context_manager.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_color.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_color_acceptance.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_command_checks.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_components_factory.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_context.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_context_menus.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_converter_registration.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_converters.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_error_handler.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_errors.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_event_dispatcher.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_event_error_hook.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_extension_loader.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_gateway_backoff.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_gateway_intent.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_help_command.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_http_rate_limit.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_http_reactions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_hybrid_context.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_i18n.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_interaction.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_logging_config.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_member.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_message_pager.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_modal_send.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_modals.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_oauth.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_permissions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_presence_and_typing.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_presence_update.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_rate_limiter.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_reactions.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_send_files.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_sharding.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_slash_contexts.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_tasks_extension.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_textchannel_history.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_textchannel_purge.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_typing_indicator.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_ui.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_utils.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_view_layout.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_voice_client.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_wait_for.py +0 -0
- {disagreement-0.1.0rc2 → disagreement-0.1.0rc3}/tests/test_webhooks.py +0 -0
@@ -14,7 +14,7 @@ __title__ = "disagreement"
|
|
14
14
|
__author__ = "Slipstream"
|
15
15
|
__license__ = "BSD 3-Clause License"
|
16
16
|
__copyright__ = "Copyright 2025 Slipstream"
|
17
|
-
__version__ = "0.1.
|
17
|
+
__version__ = "0.1.0rc3"
|
18
18
|
|
19
19
|
from .client import Client, AutoShardedClient
|
20
20
|
from .models import Message, User, Reaction
|
@@ -35,7 +35,11 @@ from .enums import GatewayIntent, GatewayOpcode # Export enums
|
|
35
35
|
from .error_handler import setup_global_error_handler
|
36
36
|
from .hybrid_context import HybridContext
|
37
37
|
from .ext import tasks
|
38
|
+
from .logging_config import setup_logging
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
import logging
|
41
|
+
|
42
|
+
|
43
|
+
# Configure a default logger if none has been configured yet
|
44
|
+
if not logging.getLogger().hasHandlers():
|
45
|
+
setup_logging(logging.INFO)
|
@@ -123,14 +123,10 @@ class Client:
|
|
123
123
|
|
124
124
|
self._closed: bool = False
|
125
125
|
self._ready_event: asyncio.Event = asyncio.Event()
|
126
|
-
self.application_id: Optional[Snowflake] = None # For Application Commands
|
127
126
|
self.user: Optional["User"] = (
|
128
127
|
None # The bot's own user object, populated on READY
|
129
128
|
)
|
130
129
|
|
131
|
-
# Initialize AppCommandHandler
|
132
|
-
self.app_command_handler: AppCommandHandler = AppCommandHandler(client=self)
|
133
|
-
|
134
130
|
# Internal Caches
|
135
131
|
self._guilds: Dict[Snowflake, "Guild"] = {}
|
136
132
|
self._channels: Dict[Snowflake, "Channel"] = (
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# disagreement/ext/app_commands/handler.py
|
2
2
|
|
3
3
|
import inspect
|
4
|
+
import logging
|
4
5
|
from typing import (
|
5
6
|
TYPE_CHECKING,
|
6
7
|
Dict,
|
@@ -64,6 +65,9 @@ if not TYPE_CHECKING:
|
|
64
65
|
Message = Any
|
65
66
|
|
66
67
|
|
68
|
+
logger = logging.getLogger(__name__)
|
69
|
+
|
70
|
+
|
67
71
|
class AppCommandHandler:
|
68
72
|
"""
|
69
73
|
Manages application command registration, parsing, and dispatching.
|
@@ -544,7 +548,7 @@ class AppCommandHandler:
|
|
544
548
|
await command.invoke(ctx, *parsed_args, **parsed_kwargs)
|
545
549
|
|
546
550
|
except Exception as e:
|
547
|
-
|
551
|
+
logger.error("Error invoking app command '%s': %s", command.name, e)
|
548
552
|
await self.dispatch_app_command_error(ctx, e)
|
549
553
|
# else:
|
550
554
|
# # Default error reply if no handler on client
|
@@ -594,34 +598,43 @@ class AppCommandHandler:
|
|
594
598
|
payload = cmd_or_group.to_dict()
|
595
599
|
commands_to_sync.append(payload)
|
596
600
|
except AttributeError:
|
597
|
-
|
598
|
-
|
601
|
+
logger.warning(
|
602
|
+
"Command or group '%s' does not have a to_dict() method. Skipping.",
|
603
|
+
cmd_or_group.name,
|
599
604
|
)
|
600
605
|
except Exception as e:
|
601
|
-
|
602
|
-
|
606
|
+
logger.error(
|
607
|
+
"Error converting command/group '%s' to dict: %s. Skipping.",
|
608
|
+
cmd_or_group.name,
|
609
|
+
e,
|
603
610
|
)
|
604
611
|
|
605
612
|
if not commands_to_sync:
|
606
|
-
|
607
|
-
|
613
|
+
logger.info(
|
614
|
+
"No commands to sync for %s scope.",
|
615
|
+
f"guild {guild_id}" if guild_id else "global",
|
608
616
|
)
|
609
617
|
return
|
610
618
|
|
611
619
|
try:
|
612
620
|
if guild_id:
|
613
|
-
|
614
|
-
|
621
|
+
logger.info(
|
622
|
+
"Syncing %s commands for guild %s...",
|
623
|
+
len(commands_to_sync),
|
624
|
+
guild_id,
|
615
625
|
)
|
616
626
|
await self.client._http.bulk_overwrite_guild_application_commands(
|
617
627
|
application_id, guild_id, commands_to_sync
|
618
628
|
)
|
619
629
|
else:
|
620
|
-
|
630
|
+
logger.info(
|
631
|
+
"Syncing %s global commands...",
|
632
|
+
len(commands_to_sync),
|
633
|
+
)
|
621
634
|
await self.client._http.bulk_overwrite_global_application_commands(
|
622
635
|
application_id, commands_to_sync
|
623
636
|
)
|
624
|
-
|
637
|
+
logger.info("Command sync successful.")
|
625
638
|
except Exception as e:
|
626
|
-
|
639
|
+
logger.error("Error syncing application commands: %s", e)
|
627
640
|
# Consider re-raising or specific error handling
|
@@ -58,4 +58,4 @@ class HybridCommand(SlashCommand, PrefixCommand): # Inherit from both
|
|
58
58
|
# The correct one will be called depending on how the command is dispatched.
|
59
59
|
# The AppCommandHandler will use AppCommand.invoke (via SlashCommand).
|
60
60
|
# The prefix CommandHandler will use PrefixCommand.invoke.
|
61
|
-
# This seems acceptable.
|
61
|
+
# This seems acceptable.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# disagreement/ext/commands/cog.py
|
2
2
|
|
3
3
|
import inspect
|
4
|
+
import logging
|
4
5
|
from typing import TYPE_CHECKING, List, Tuple, Callable, Awaitable, Any, Dict, Union
|
5
6
|
|
6
7
|
if TYPE_CHECKING:
|
@@ -16,6 +17,8 @@ else: # pragma: no cover - runtime imports for isinstance checks
|
|
16
17
|
# EventDispatcher might be needed if cogs register listeners directly
|
17
18
|
# from disagreement.event_dispatcher import EventDispatcher
|
18
19
|
|
20
|
+
logger = logging.getLogger(__name__)
|
21
|
+
|
19
22
|
|
20
23
|
class Cog:
|
21
24
|
"""
|
@@ -59,8 +62,10 @@ class Cog:
|
|
59
62
|
cmd.cog = self # Assign the cog instance to the command
|
60
63
|
if cmd.name in self._commands:
|
61
64
|
# This should ideally be caught earlier or handled by CommandHandler
|
62
|
-
|
63
|
-
|
65
|
+
logger.warning(
|
66
|
+
"Duplicate command name '%s' in cog '%s'. Overwriting.",
|
67
|
+
cmd.name,
|
68
|
+
self.cog_name,
|
64
69
|
)
|
65
70
|
self._commands[cmd.name.lower()] = cmd
|
66
71
|
# Also register aliases
|
@@ -79,8 +84,10 @@ class Cog:
|
|
79
84
|
# For AppCommandGroup, its commands will have cog set individually if they are AppCommands
|
80
85
|
self._app_commands_and_groups.append(app_cmd_obj)
|
81
86
|
else:
|
82
|
-
|
83
|
-
|
87
|
+
logger.warning(
|
88
|
+
"Member '%s' in cog '%s' has '__app_command_object__' but it's not an AppCommand or AppCommandGroup.",
|
89
|
+
member_name,
|
90
|
+
self.cog_name,
|
84
91
|
)
|
85
92
|
|
86
93
|
elif isinstance(member, (AppCommand, AppCommandGroup)):
|
@@ -92,8 +99,10 @@ class Cog:
|
|
92
99
|
# This is a method decorated with @commands.Cog.listener or @commands.listener
|
93
100
|
if not inspect.iscoroutinefunction(member):
|
94
101
|
# Decorator should have caught this, but double check
|
95
|
-
|
96
|
-
|
102
|
+
logger.warning(
|
103
|
+
"Listener '%s' in cog '%s' is not a coroutine. Skipping.",
|
104
|
+
member_name,
|
105
|
+
self.cog_name,
|
97
106
|
)
|
98
107
|
continue
|
99
108
|
|
@@ -3,6 +3,7 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
import asyncio
|
6
|
+
import logging
|
6
7
|
import inspect
|
7
8
|
from typing import (
|
8
9
|
TYPE_CHECKING,
|
@@ -31,6 +32,8 @@ from .errors import (
|
|
31
32
|
from .converters import run_converters, DEFAULT_CONVERTERS, Converter
|
32
33
|
from disagreement.typing import Typing
|
33
34
|
|
35
|
+
logger = logging.getLogger(__name__)
|
36
|
+
|
34
37
|
if TYPE_CHECKING:
|
35
38
|
from .cog import Cog
|
36
39
|
from disagreement.client import Client
|
@@ -224,8 +227,10 @@ class CommandHandler:
|
|
224
227
|
self.commands[command.name.lower()] = command
|
225
228
|
for alias in command.aliases:
|
226
229
|
if alias in self.commands:
|
227
|
-
|
228
|
-
|
230
|
+
logger.warning(
|
231
|
+
"Alias '%s' for command '%s' conflicts with an existing command or alias.",
|
232
|
+
alias,
|
233
|
+
command.name,
|
229
234
|
)
|
230
235
|
self.commands[alias.lower()] = command
|
231
236
|
|
@@ -241,6 +246,7 @@ class CommandHandler:
|
|
241
246
|
|
242
247
|
def add_cog(self, cog_to_add: "Cog") -> None:
|
243
248
|
from .cog import Cog
|
249
|
+
|
244
250
|
if not isinstance(cog_to_add, Cog):
|
245
251
|
raise TypeError("Argument must be a subclass of Cog.")
|
246
252
|
|
@@ -258,8 +264,9 @@ class CommandHandler:
|
|
258
264
|
for event_name, callback in cog_to_add.get_listeners():
|
259
265
|
self.client._event_dispatcher.register(event_name.upper(), callback)
|
260
266
|
else:
|
261
|
-
|
262
|
-
|
267
|
+
logger.warning(
|
268
|
+
"Client does not have '_event_dispatcher'. Listeners for cog '%s' not registered.",
|
269
|
+
cog_to_add.cog_name,
|
263
270
|
)
|
264
271
|
|
265
272
|
if hasattr(cog_to_add, "cog_load") and inspect.iscoroutinefunction(
|
@@ -267,7 +274,7 @@ class CommandHandler:
|
|
267
274
|
):
|
268
275
|
asyncio.create_task(cog_to_add.cog_load())
|
269
276
|
|
270
|
-
|
277
|
+
logger.info("Cog '%s' added.", cog_to_add.cog_name)
|
271
278
|
|
272
279
|
def remove_cog(self, cog_name: str) -> Optional["Cog"]:
|
273
280
|
cog_to_remove = self.cogs.pop(cog_name, None)
|
@@ -277,8 +284,11 @@ class CommandHandler:
|
|
277
284
|
|
278
285
|
if hasattr(self.client, "_event_dispatcher"):
|
279
286
|
for event_name, callback in cog_to_remove.get_listeners():
|
280
|
-
|
281
|
-
|
287
|
+
logger.debug(
|
288
|
+
"Listener '%s' for event '%s' from cog '%s' needs manual unregistration logic in EventDispatcher.",
|
289
|
+
callback.__name__,
|
290
|
+
event_name,
|
291
|
+
cog_name,
|
282
292
|
)
|
283
293
|
|
284
294
|
if hasattr(cog_to_remove, "cog_unload") and inspect.iscoroutinefunction(
|
@@ -287,7 +297,7 @@ class CommandHandler:
|
|
287
297
|
asyncio.create_task(cog_to_remove.cog_unload())
|
288
298
|
|
289
299
|
cog_to_remove._eject()
|
290
|
-
|
300
|
+
logger.info("Cog '%s' removed.", cog_name)
|
291
301
|
return cog_to_remove
|
292
302
|
|
293
303
|
async def get_prefix(self, message: "Message") -> Union[str, List[str], None]:
|
@@ -493,11 +503,11 @@ class CommandHandler:
|
|
493
503
|
ctx.kwargs = parsed_kwargs
|
494
504
|
await command.invoke(ctx, *parsed_args, **parsed_kwargs)
|
495
505
|
except CommandError as e:
|
496
|
-
|
506
|
+
logger.error("Command error for '%s': %s", command.name, e)
|
497
507
|
if hasattr(self.client, "on_command_error"):
|
498
508
|
await self.client.on_command_error(ctx, e)
|
499
509
|
except Exception as e:
|
500
|
-
|
510
|
+
logger.error("Unexpected error invoking command '%s': %s", command.name, e)
|
501
511
|
exc = CommandInvokeError(e)
|
502
512
|
if hasattr(self.client, "on_command_error"):
|
503
513
|
await self.client.on_command_error(ctx, exc)
|