Skip to content
Open
Show file tree
Hide file tree
Changes from all 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.
11 changes: 10 additions & 1 deletion disnake/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,17 @@ def warn_deprecated(
stacklevel = 1 # reset stacklevel, assume we just want the first frame outside library code

old_filters = warnings.filters[:]
if len(old_filters) > 0:
for action, _, category, module, _ in old_filters:
if (
(category is DeprecationWarning)
and ("disnake" in str(module))
and (action == "ignore")
):
return # If a disnake ignore rule is found, we skip warning.
# We allow force bypassing of filters if the default/global DeprecationWarning ignore is set.
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\..*")
utils.warn_deprecated(msg)

assert len(result) == 1, "Expected one warning to be raised."
assert result[0].category is DeprecationWarning
assert result[0].message.args[0] == msg # pyright: ignore[reportAttributeAccessIssue]

# Reset With empty filters.
# Expected behaviour is that a warning is forced because it's empty.
warnings.resetwarnings()
with warnings.catch_warnings(record=True) as result:
utils.warn_deprecated(msg)

assert len(result) == 1, "Expected one warning to be raised."
assert result[0].category is DeprecationWarning
assert result[0].message.args[0] == msg # pyright: ignore[reportAttributeAccessIssue]

# Reset With empty filters and add disnake ignore rule.
# Expected behaviour is that there is no warning because it's ignored.
warnings.resetwarnings()
with warnings.catch_warnings(record=True) as result:
warnings.filterwarnings("ignore", category=DeprecationWarning, module=r"disnake\..*")
utils.warn_deprecated(msg)

assert len(result) == 0, (
"Expected no warnings to be raised when declaring disnake to be ignored."
)

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


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