diff --git a/src/scverse_misc/_deprecated.py b/src/scverse_misc/_deprecated.py index c13b65f..1076491 100644 --- a/src/scverse_misc/_deprecated.py +++ b/src/scverse_misc/_deprecated.py @@ -2,6 +2,7 @@ import sys from inspect import getdoc +from textwrap import indent from typing import TYPE_CHECKING, LiteralString if sys.version_info >= (3, 13): @@ -54,13 +55,15 @@ def _deprecated_at[F: Callable[..., object]]( def decorate(func: F) -> F: kind = "function" if func.__name__ == func.__qualname__ else "method" - warnmsg = f"The {kind} {func.__name__} is deprecated and will be removed in the future." + warnmsg = f"The {kind} {func.__name__} is deprecated and will be removed in the future" doc = getdoc(func) docmsg = f".. version-deprecated:: {msg.version_deprecated}" if len(msg): - docmsg += f"\n {msg}" - warnmsg += f" {msg}" + docmsg += f"\n{indent(msg, 3 * ' ')}" + warnmsg += f". {msg}" if msg.count("\n") == 0 else f":\n{indent(msg, 4 * ' ')}" + else: + warnmsg += "." if doc is None: doc = docmsg diff --git a/tests/test_deprecation_decorator.py b/tests/test_deprecation_decorator.py index 9ecea5c..097e631 100644 --- a/tests/test_deprecation_decorator.py +++ b/tests/test_deprecation_decorator.py @@ -6,7 +6,13 @@ from scverse_misc import Deprecation, deprecated -@pytest.fixture(params=[pytest.param(None, id="no_message"), pytest.param("Test message.", id="message")]) +@pytest.fixture( + params=[ + pytest.param(None, id="no_message"), + pytest.param("Test message.", id="short_message"), + pytest.param("Test\nmessage.", id="long_message"), + ] +) def msg(request: pytest.FixtureRequest) -> str | None: return cast(str | None, request.param) @@ -52,14 +58,17 @@ def test_deprecation_decorator( assert deprecated_func.__doc__ is not None lines = deprecated_func.__doc__.expandtabs().splitlines() - if docstring is None: - assert lines[0].startswith(".. version-deprecated::") - else: + offset = 0 if docstring is None else 2 + + if docstring is not None: lines_orig = docstring.expandtabs().splitlines() assert lines[0] == lines_orig[0] - assert len(lines[1].strip()) == 0 - assert lines[2].startswith(".. version-deprecated") - if msg is None: - assert len(lines) == 3 or not lines[3].startswith(" ") - else: - assert lines[3] == f" {msg}" + assert len(lines[1].strip()) == 0, "expected empty line following summary" + + assert lines[offset].startswith(".. version-deprecated") + if msg is None: + assert len(lines) == offset + 1 or not lines[offset + 1].startswith(" ") + else: + msg_lines = msg.splitlines() + msg_indented = [f" {line}" for line in msg_lines] + assert lines[offset + 1 : offset + 1 + len(msg_lines)] == msg_indented