diff --git a/discord/__init__.py b/discord/__init__.py index b639517..18f1295 100644 --- a/discord/__init__.py +++ b/discord/__init__.py @@ -19,7 +19,7 @@ __path__ = __import__('pkgutil').extend_path(__path__, __name__) __slots__ = ('you','are','a','faggot') -import logging +import loguru from typing import NamedTuple, Literal from .client import * diff --git a/discord/activity.py b/discord/activity.py index 1d82298..dc86795 100644 --- a/discord/activity.py +++ b/discord/activity.py @@ -747,7 +747,7 @@ def __init__( ) -> None: super().__init__(**extra) self.name: Optional[str] = name - self.state: Optional[str] = extra.pop('state', None) + self.state: Optional[str] = extra.pop('state', name) if self.name == 'Custom Status': self.name = self.state diff --git a/discord/app_commands/tree.py b/discord/app_commands/tree.py index da7ec54..b4ebab4 100644 --- a/discord/app_commands/tree.py +++ b/discord/app_commands/tree.py @@ -23,7 +23,7 @@ """ from __future__ import annotations -import logging +import loguru import inspect from typing import ( @@ -79,7 +79,7 @@ __all__ = ('CommandTree',) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) def _retrieve_guild_ids( diff --git a/discord/client.py b/discord/client.py index b1b2996..a31c9c2 100644 --- a/discord/client.py +++ b/discord/client.py @@ -26,7 +26,7 @@ from collections import deque import asyncio import datetime -import logging +import loguru from typing import ( TYPE_CHECKING, Any, @@ -127,7 +127,7 @@ Coro = Coroutine[Any, Any, T] CoroT = TypeVar('CoroT', bound=Callable[..., Coro[Any]]) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) class _LoopSentinel: @@ -199,9 +199,9 @@ class Client: .. versionadded:: 1.5 status: Optional[:class:`.Status`] - A status to start your presence with upon logging on to Discord. + A status to start your presence with upon loguru on to Discord. activity: Optional[:class:`.BaseActivity`] - An activity to start your presence with upon logging on to Discord. + An activity to start your presence with upon loguru on to Discord. allowed_mentions: Optional[:class:`AllowedMentions`] Control how the client handles mentions by default on every message sent. @@ -650,7 +650,7 @@ async def login(self, token: str) -> None: passing status code. """ - _log.info('logging in using static token') + _log.info('loguru in using static token') if self.loop is _loop: await self._async_setup_hook() @@ -834,8 +834,8 @@ def run( token: str, *, reconnect: bool = True, - log_handler: Optional[logging.Handler] = MISSING, - log_formatter: logging.Formatter = MISSING, + log_handler: Optional[loguru.Handler] = MISSING, + log_formatter: loguru.Formatter = MISSING, log_level: int = MISSING, root_logger: bool = False, ) -> None: @@ -846,7 +846,7 @@ def run( function should not be used. Use :meth:`start` coroutine or :meth:`connect` + :meth:`login`. - This function also sets up the logging library to make it easier + This function also sets up the loguru library to make it easier for beginners to know what is going on with the library. For more advanced users, this can be disabled by passing ``None`` to the ``log_handler`` parameter. @@ -867,23 +867,23 @@ def run( failure or a specific failure on Discord's part. Certain disconnects that lead to bad state will not be handled (such as invalid sharding payloads or bad tokens). - log_handler: Optional[:class:`logging.Handler`] + log_handler: Optional[:class:`loguru.Handler`] The log handler to use for the library's logger. If this is ``None`` - then the library will not set up anything logging related. Logging + then the library will not set up anything loguru related. loguru will still work if ``None`` is passed, though it is your responsibility to set it up. - The default log handler if not provided is :class:`logging.StreamHandler`. + The default log handler if not provided is :class:`loguru.StreamHandler`. .. versionadded:: 2.0 - log_formatter: :class:`logging.Formatter` + log_formatter: :class:`loguru.Formatter` The formatter to use with the given log handler. If not provided then it - defaults to a colour based logging formatter (if available). + defaults to a colour based loguru formatter (if available). .. versionadded:: 2.0 log_level: :class:`int` The default log level for the library's logger. This is only applied if the - ``log_handler`` parameter is not ``None``. Defaults to ``logging.INFO``. + ``log_handler`` parameter is not ``None``. Defaults to ``loguru.INFO``. .. versionadded:: 2.0 root_logger: :class:`bool` @@ -901,7 +901,7 @@ async def runner(): await self.start(token, reconnect=reconnect) if log_handler is not None: - utils.setup_logging( + utils.setup_loguru( handler=log_handler, formatter=log_formatter, level=log_level, @@ -925,7 +925,7 @@ def is_closed(self) -> bool: @property def activity(self) -> Optional[ActivityTypes]: """Optional[:class:`.BaseActivity`]: The activity being used upon - logging in. + loguru in. """ return create_activity(self._connection._activity, self._connection) @@ -942,7 +942,7 @@ def activity(self, value: Optional[ActivityTypes]) -> None: @property def status(self) -> Status: """:class:`.Status`: - The status being used upon logging on to Discord. + The status being used upon loguru on to Discord. .. versionadded: 2.0 """ diff --git a/discord/ext/commands/bot.py b/discord/ext/commands/bot.py index 49fe1ec..af150b5 100644 --- a/discord/ext/commands/bot.py +++ b/discord/ext/commands/bot.py @@ -31,7 +31,7 @@ import inspect import importlib.util import sys -import logging +import loguru import types from typing import ( Any, @@ -96,7 +96,7 @@ T = TypeVar('T') CFT = TypeVar('CFT', bound='CoroFunc') from discord.globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) def when_mentioned(bot: _Bot, msg: Message, /) -> List[str]: @@ -207,8 +207,8 @@ async def _async_setup_hook(self) -> None: await super()._async_setup_hook() # type: ignore prefix = self.command_prefix - # This has to be here because for the default logging set up to capture - # the logging calls, they have to come after the `Client.run` call. + # This has to be here because for the default loguru set up to capture + # the loguru calls, they have to come after the `Client.run` call. # The best place to do this is in an async init scenario if not self.intents.message_content: # type: ignore trigger_warning = ( @@ -895,7 +895,11 @@ async def _fill(self, ctx: Context[BotT]): ctx.permissions.value = 0 try: - command.perms = list(check(ctx).cr_frame.f_locals['perms'].keys()) + if asyncio.iscoroutinefunction(check): + invoke = await check(ctx) + else: + invoke = check(ctx) + command.perms = list(invoke.cr_frame.f_locals['perms'].keys()) except errors.MissingPermissions as err: command.perms = err.missing_permissions @@ -910,7 +914,11 @@ async def _fill(self, ctx: Context[BotT]): ctx.bot_permissions.value = 0 try: - command.bot_perms = list(check(ctx).cr_frame.f_locals['perms'].keys()) + if asyncio.iscoroutinefunction(check): + invoke = await check(ctx) + else: + invoke = check(ctx) + command.bot_perms = list(invoke.cr_frame.f_locals['perms'].keys()) except errors.BotMissingPermissions as err: command.bot_perms = err.missing_permissions diff --git a/discord/ext/tasks/__init__.py b/discord/ext/tasks/__init__.py index 30b596c..364bba8 100644 --- a/discord/ext/tasks/__init__.py +++ b/discord/ext/tasks/__init__.py @@ -26,7 +26,7 @@ import asyncio import datetime -import logging +import loguru from typing import ( Any, Callable, @@ -47,7 +47,7 @@ from discord.backoff import ExponentialBackoff from discord.utils import MISSING from discord.globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) # fmt: off __all__ = ( diff --git a/discord/gateway.py b/discord/gateway.py index 6dc6133..08abd53 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -26,7 +26,7 @@ import asyncio from collections import deque import concurrent.futures -import logging +import loguru import struct import sys import time @@ -46,7 +46,7 @@ from .expiringdictionary import ExpiringDictionary from xxhash import xxh3_64_hexdigest as hash_ from .globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) __all__ = ( 'DiscordWebSocket', diff --git a/discord/http.py b/discord/http.py index 2377aef..afa7acb 100644 --- a/discord/http.py +++ b/discord/http.py @@ -25,7 +25,7 @@ from __future__ import annotations import asyncio -import logging,socket +import loguru,socket import sys from typing import ( Any, @@ -58,7 +58,7 @@ from . import __version__, utils from .utils import MISSING from .globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) if TYPE_CHECKING: from typing_extensions import Self @@ -719,7 +719,7 @@ async def request( # 1. It's a sub-ratelimit which is hard to handle # 2. The rate limit information genuinely changed # There is no good way to discern these, Discord doesn't provide a way to do so. - # At best, there will be some form of logging to help catch it. + # At best, there will be some form of loguru to help catch it. # Alternating sub-ratelimits means that the requests oscillate between # different underlying rate limits -- this can lead to unexpected 429s # It is unavoidable. diff --git a/discord/opus.py b/discord/opus.py index c791007..4b49705 100644 --- a/discord/opus.py +++ b/discord/opus.py @@ -29,7 +29,7 @@ import array import ctypes import ctypes.util -import logging +import loguru import math import os.path import struct @@ -63,7 +63,7 @@ class SignalCtl(TypedDict): 'OpusNotLoaded', ) from .globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) c_int_ptr = ctypes.POINTER(ctypes.c_int) c_int16_ptr = ctypes.POINTER(ctypes.c_int16) diff --git a/discord/player.py b/discord/player.py index 06b9d7f..fd76624 100644 --- a/discord/player.py +++ b/discord/player.py @@ -27,7 +27,7 @@ import subprocess import audioop import asyncio -import logging +import loguru import shlex import time import orjson @@ -51,7 +51,7 @@ AT = TypeVar('AT', bound='AudioSource') -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) __all__ = ( 'AudioSource', diff --git a/discord/shard.py b/discord/shard.py index e751897..1e059f2 100644 --- a/discord/shard.py +++ b/discord/shard.py @@ -25,7 +25,7 @@ from __future__ import annotations import asyncio -import logging +import loguru import aiohttp import yarl @@ -56,7 +56,7 @@ 'ShardInfo', ) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) class EventType: diff --git a/discord/state.py b/discord/state.py index 4b94373..61e8b24 100644 --- a/discord/state.py +++ b/discord/state.py @@ -27,7 +27,7 @@ import asyncio from collections import deque, OrderedDict import copy -import logging +import loguru from typing import ( Dict, Optional, @@ -153,10 +153,10 @@ def done(self) -> None: future.set_result(self.buffer) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) -async def logging_coroutine(coroutine: Coroutine[Any, Any, T], *, info: str) -> Optional[T]: +async def loguru_coroutine(coroutine: Coroutine[Any, Any, T], *, info: str) -> Optional[T]: try: await coroutine except Exception: @@ -1306,7 +1306,7 @@ def parse_guild_ban_add(self, data: gw.GuildBanAddEvent) -> None: # before GUILD_MEMBER_REMOVE is called # hence we don't remove it from cache or do anything # strange with it, the main purpose of this event - # is mainly to dispatch to another event worth listening to for logging + # is mainly to dispatch to another event worth listening to for loguru guild = self._get_guild(int(data['guild_id'])) if guild is not None: try: @@ -1551,7 +1551,7 @@ def parse_voice_state_update(self, data: gw.VoiceStateUpdateEvent) -> None: voice = self._get_voice_client(guild.id) if voice is not None: coro = voice.on_voice_state_update(data) - asyncio.create_task(logging_coroutine(coro, info='Voice Protocol voice state update handler')) + asyncio.create_task(loguru_coroutine(coro, info='Voice Protocol voice state update handler')) member, before, after = guild._update_voice_state(data, channel_id) # type: ignore if member is not None: @@ -1572,7 +1572,7 @@ def parse_voice_server_update(self, data: gw.VoiceServerUpdateEvent) -> None: vc = self._get_voice_client(key_id) if vc is not None: coro = vc.on_voice_server_update(data) - asyncio.create_task(logging_coroutine(coro, info='Voice Protocol voice server update handler')) + asyncio.create_task(loguru_coroutine(coro, info='Voice Protocol voice server update handler')) def parse_typing_start(self, data: gw.TypingStartEvent) -> None: raw = RawTypingEvent(data) diff --git a/discord/ui/modal.py b/discord/ui/modal.py index d478427..2756b29 100644 --- a/discord/ui/modal.py +++ b/discord/ui/modal.py @@ -25,7 +25,7 @@ from __future__ import annotations import asyncio -import logging +import loguru import os from copy import deepcopy from typing import TYPE_CHECKING, Any, Dict, Optional, Sequence, ClassVar, List @@ -49,7 +49,7 @@ # fmt: on from discord.globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) class Modal(View): diff --git a/discord/ui/view.py b/discord/ui/view.py index ef07cae..20bd0d7 100644 --- a/discord/ui/view.py +++ b/discord/ui/view.py @@ -28,7 +28,7 @@ from itertools import groupby import asyncio -import logging +import loguru import sys import time import os @@ -59,7 +59,7 @@ from .modal import Modal from discord.globals import get_global -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) def _walk_all_components(components: List[Component]) -> Iterator[Component]: diff --git a/discord/utils.py b/discord/utils.py index c7ac347..a4a889e 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -71,7 +71,7 @@ import sys import types import warnings -import logging +import logging as loguru import yarl @@ -101,7 +101,7 @@ 'as_chunks', 'format_dt', 'MISSING', - 'setup_logging', + 'setup_loguru', ) DISCORD_EPOCH = 1420070400000 @@ -1386,7 +1386,7 @@ def stream_supports_colour(stream: Any) -> bool: return is_a_tty and ('ANSICON' in os.environ or 'WT_SESSION' in os.environ) -class _ColourFormatter(logging.Formatter): +class _ColourFormatter(loguru.Formatter): # ANSI codes are a bit weird to decipher if you're unfamiliar with them, so here's a refresher # It starts off with a format like \x1b[XXXm where XXX is a semicolon separated list of commands @@ -1398,15 +1398,15 @@ class _ColourFormatter(logging.Formatter): # 1 means bold, 2 means dim, 0 means reset, and 4 means underline. LEVEL_COLOURS = [ - (logging.DEBUG, '\x1b[40;1m'), - (logging.INFO, '\x1b[34;1m'), - (logging.WARNING, '\x1b[33;1m'), - (logging.ERROR, '\x1b[31m'), - (logging.CRITICAL, '\x1b[41m'), + (loguru.DEBUG, '\x1b[40;1m'), + (loguru.INFO, '\x1b[34;1m'), + (loguru.WARNING, '\x1b[33;1m'), + (loguru.ERROR, '\x1b[31m'), + (loguru.CRITICAL, '\x1b[41m'), ] FORMATS = { - level: logging.Formatter( + level: loguru.Formatter( f'\x1b[30;1m%(asctime)s\x1b[0m {colour}%(levelname)-8s\x1b[0m \x1b[35m%(name)s\x1b[0m %(message)s', '%Y-%m-%d %H:%M:%S', ) @@ -1416,7 +1416,7 @@ class _ColourFormatter(logging.Formatter): def format(self, record): formatter = self.FORMATS.get(record.levelno) if formatter is None: - formatter = self.FORMATS[logging.DEBUG] + formatter = self.FORMATS[loguru.DEBUG] # Override the traceback to always print in red if record.exc_info: @@ -1430,59 +1430,59 @@ def format(self, record): return output -def setup_logging( +def setup_loguru( *, - handler: logging.Handler = MISSING, - formatter: logging.Formatter = MISSING, + handler: loguru.Handler = MISSING, + formatter: loguru.Formatter = MISSING, level: int = MISSING, root: bool = True, ) -> None: - """A helper function to setup logging. + """A helper function to setup loguru. - This is superficially similar to :func:`logging.basicConfig` but + This is superficially similar to :func:`loguru.basicConfig` but uses different defaults and a colour formatter if the stream can display colour. - This is used by the :class:`~discord.Client` to set up logging + This is used by the :class:`~discord.Client` to set up loguru if ``log_handler`` is not ``None``. .. versionadded:: 2.0 Parameters ----------- - handler: :class:`logging.Handler` + handler: :class:`loguru.Handler` The log handler to use for the library's logger. - The default log handler if not provided is :class:`logging.StreamHandler`. - formatter: :class:`logging.Formatter` + The default log handler if not provided is :class:`loguru.StreamHandler`. + formatter: :class:`loguru.Formatter` The formatter to use with the given log handler. If not provided then it - defaults to a colour based logging formatter (if available). If colour - is not available then a simple logging formatter is provided. + defaults to a colour based loguru formatter (if available). If colour + is not available then a simple loguru formatter is provided. level: :class:`int` - The default log level for the library's logger. Defaults to ``logging.INFO``. + The default log level for the library's logger. Defaults to ``loguru.INFO``. root: :class:`bool` Whether to set up the root logger rather than the library logger. Unlike the default for :class:`~discord.Client`, this defaults to ``True``. """ if level is MISSING: - level = logging.INFO + level = loguru.INFO if handler is MISSING: - handler = logging.StreamHandler() + handler = loguru.StreamHandler() if formatter is MISSING: - if isinstance(handler, logging.StreamHandler) and stream_supports_colour(handler.stream): + if isinstance(handler, loguru.StreamHandler) and stream_supports_colour(handler.stream): formatter = _ColourFormatter() else: dt_fmt = '%Y-%m-%d %H:%M:%S' - formatter = logging.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{') + formatter = loguru.Formatter('[{asctime}] [{levelname:<8}] {name}: {message}', dt_fmt, style='{') if root: - logger = logging.getLogger() + logger = loguru.getLogger() else: library, _, _ = __name__.partition('.') - logger = logging.getLogger(library) + logger = loguru.getLogger(library) handler.setFormatter(formatter) logger.setLevel(level) diff --git a/discord/voice_client.py b/discord/voice_client.py index bba191d..961f920 100644 --- a/discord/voice_client.py +++ b/discord/voice_client.py @@ -41,7 +41,7 @@ import asyncio import socket -import logging +import loguru import struct import threading from typing import Any, Callable, List, Optional, TYPE_CHECKING, Tuple, Union @@ -88,7 +88,7 @@ ) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) class VoiceProtocol: diff --git a/discord/webhook/async_.py b/discord/webhook/async_.py index bff31bf..249a7cc 100644 --- a/discord/webhook/async_.py +++ b/discord/webhook/async_.py @@ -24,7 +24,7 @@ from __future__ import annotations -import logging +import loguru import asyncio import re @@ -56,7 +56,7 @@ 'PartialWebhookGuild', ) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) if TYPE_CHECKING: from typing_extensions import Self diff --git a/discord/webhook/sync.py b/discord/webhook/sync.py index 70f6c50..dd0c929 100644 --- a/discord/webhook/sync.py +++ b/discord/webhook/sync.py @@ -31,7 +31,7 @@ from __future__ import annotations import threading -import logging +import loguru import orjson import time import re @@ -54,7 +54,7 @@ 'SyncWebhookMessage', ) -_log = get_global("logger", logging.getLogger(__name__)) +_log = get_global("logger", loguru.logger) if TYPE_CHECKING: from typing_extensions import Self