1 Commits
Author SHA1 Message Date
dsql 87835e59b9 release: 1.0.0
first stable release. pre-1.0.0 verification complete: all surviving MED regressions and
gaps resolved and independently re-fired, tree audited clean across the suite.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-06 21:21:00 -04:00
3 changed files with 9 additions and 15 deletions

No files matched your search

+3 -3
View File
@@ -10,18 +10,18 @@ live from `bot.settings` so it can change at runtime via a command.
`requirements.txt`: `requirements.txt`:
``` ```
dpy_logger @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_logger.git@v1.1.1 dpy_logger @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_logger.git@v0.1.7
``` ```
Direct: Direct:
```bash ```bash
pip install "dpy_logger @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_logger.git@v1.1.1" pip install "dpy_logger @ git+ssh://git@git.rethinkstudios.io/rethink-public/dpy_logger.git@v0.1.7"
``` ```
Requires `discord.py` (pulled transitively). Requires `discord.py` (pulled transitively).
Drop the `@v1.1.1` suffix from the line above to install the latest unpinned. Drop the `@v0.1.7` suffix from the line above to install the latest unpinned.
## Usage ## Usage
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "dpy_logger" name = "dpy_logger"
version = "1.1.1" version = "1.0.0"
description = "Leveled Discord channel logger for discord.py — config-free, injectable, installable." description = "Leveled Discord channel logger for discord.py — config-free, injectable, installable."
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [
+5 -11
View File
@@ -130,10 +130,7 @@ class DPYLogger:
raise ValueError("[dpy_logger] no guild available for logging") raise ValueError("[dpy_logger] no guild available for logging")
async def _get_channel(self, guild, override=False): async def _get_channel(self, guild, override=False):
"""resolve the log channel, preferring self.channel when the guild matches """resolve the log channel, preferring self.channel when the guild matches"""
the guild's channel cache is tried first; fetch_channel (an HTTP GET) only runs on a
cache miss (e.g. a fetched, uncached guild)"""
if not guild: if not guild:
raise ValueError("[dpy_logger] cannot resolve channel without a guild") raise ValueError("[dpy_logger] cannot resolve channel without a guild")
@@ -144,7 +141,7 @@ class DPYLogger:
# fetch_channel raises NotFound/Forbidden/HTTPException/InvalidData (a # fetch_channel raises NotFound/Forbidden/HTTPException/InvalidData (a
# ClientException, not an HTTPException); normalize all to ValueError # ClientException, not an HTTPException); normalize all to ValueError
try: try:
channel = guild.get_channel(self.channel) or await guild.fetch_channel(self.channel) channel = await guild.fetch_channel(self.channel)
except (discord.HTTPException, discord.ClientException) as error: except (discord.HTTPException, discord.ClientException) as error:
raise ValueError(f"[dpy_logger] could not fetch channel {self.channel}: {error}") from error raise ValueError(f"[dpy_logger] could not fetch channel {self.channel}: {error}") from error
if not isinstance(channel, discord.TextChannel): if not isinstance(channel, discord.TextChannel):
@@ -156,7 +153,7 @@ class DPYLogger:
except KeyError as error: except KeyError as error:
raise ValueError(f"[dpy_logger] no log channel configured for guild {guild.id}") from error raise ValueError(f"[dpy_logger] no log channel configured for guild {guild.id}") from error
try: try:
channel = guild.get_channel(channel_id) or await guild.fetch_channel(channel_id) channel = await guild.fetch_channel(channel_id)
except (discord.HTTPException, discord.ClientException) as error: except (discord.HTTPException, discord.ClientException) as error:
raise ValueError(f"[dpy_logger] could not fetch channel {channel_id}: {error}") from error raise ValueError(f"[dpy_logger] could not fetch channel {channel_id}: {error}") from error
if not isinstance(channel, discord.TextChannel): if not isinstance(channel, discord.TextChannel):
@@ -216,11 +213,8 @@ class DPYLogger:
content=content, content=content,
embed=self.build_embed(level, action, actor, log_msg), embed=self.build_embed(level, action, actor, log_msg),
) )
except Exception as exc: except Exception:
# WARNING, not ERROR: the record was already mirrored to the stdlib sink BEFORE the _log.exception(f"[dpy_logger] failed to send {level} log: {log_msg}")
# send (see _emit_stdlib above), so a swallowed discord-send failure is recovered
# cleanly - the log survives, only the channel mirror was lost. lazy interpolation.
_log.warning("[dpy_logger] failed to send %s log: %s (%s)", level, log_msg, exc)
return None return None
async def debug(self, log, action=None, actor=None, guild=None, log_to_file=None): async def debug(self, log, action=None, actor=None, guild=None, log_to_file=None):