Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/1476.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix ``utils.warn_deprecated`` to respect :mod:`warnings` filters defined by user.
17 changes: 16 additions & 1 deletion disnake/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,23 @@ def warn_deprecated(
stacklevel = 1 # reset stacklevel, assume we just want the first frame outside library code

old_filters = warnings.filters[:]
send_warning = True
if len(old_filters) > 0:
for action, _, category, module, _ in old_filters:
if (
(category is DeprecationWarning)
and ("disnake" in str(module))
and (action == "ignore")
):
send_warning = False
break # break out after first disnake rule, it's good enough.

# allow force bypassing of filters if the default DeprecationWarning ignore is set.
if not send_warning:
return

try:
warnings.simplefilter("always", DeprecationWarning)
warnings.simplefilter(action="always", category=DeprecationWarning)
warnings.warn(*args, stacklevel=stacklevel + 1, category=DeprecationWarning, **kwargs)
finally:
assert isinstance(warnings.filters, list)
Expand Down
42 changes: 42 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,48 @@ def func(n: int) -> None:
assert result[0].filename == mock.__file__


@pytest.mark.parametrize(
"msg",
["This is a deprecated function"],
)
def test_deprecated_warn(msg: str) -> None:
# Just test if works
# first clear existing filters - these will be restored at the end as this is probably messing with the global warning filters
filters = warnings.filters[:]

warnings.resetwarnings()
with warnings.catch_warnings(record=True) as result:
warnings.filterwarnings(
"always", category=DeprecationWarning, module=r"disnake\..*"
) # this also works with just a plain str
utils.warn_deprecated(msg)

assert len(result) == 1
assert result[0].message.args[0] == msg # pyright: ignore[reportAttributeAccessIssue]
assert result[0].category is DeprecationWarning

# Reset With empty filters - expected behaviour is that a warning is forced because it's empty
warnings.resetwarnings()
assert len(warnings.filters) == 0 # should be empty
with warnings.catch_warnings(record=True) as result:
utils.warn_deprecated(msg)

assert len(result) == 1
assert result[0].message.args[0] == msg # pyright: ignore[reportAttributeAccessIssue]
assert result[0].category is DeprecationWarning

# Reset With empty filters - expected behaviour is that there is no warning because it's ignored
warnings.resetwarnings()
assert len(warnings.filters) == 0 # should be empty
with warnings.catch_warnings(record=True) as result:
warnings.filterwarnings("ignore", category=DeprecationWarning, module=r"disnake\..*")
utils.warn_deprecated(msg)

assert len(result) == 0

warnings.filters[:] = filters # pyright: ignore[reportIndexIssue]


@pytest.mark.parametrize(
("params", "expected"),
[
Expand Down