Coverage for cuda/core/_vendored/deprecated/sphinx.py: 93.62%
47 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-03 01:38 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-03 01:38 +0000
1# Vendored from the Deprecated package (https://pypi.org/project/Deprecated/),
2# version 1.3.1, (c) Laurent LAPORTE, MIT License.
3# Modified to remove the dependency on the `wrapt` package.
5import re
6import textwrap
8from cuda.core._vendored.deprecated.classic import ClassicAdapter
9from cuda.core._vendored.deprecated.classic import deprecated as _classic_deprecated
12class SphinxAdapter(ClassicAdapter):
13 """
14 Sphinx adapter -- *for advanced usage only*
16 This adapter overrides :class:`~deprecated.classic.ClassicAdapter` to add
17 Sphinx directives ("versionadded", "versionchanged", "deprecated") to the
18 end of the decorated function or class docstring.
19 """
21 def __init__(
22 self,
23 directive,
24 reason="",
25 version="",
26 action=None,
27 category=DeprecationWarning,
28 extra_stacklevel=0,
29 line_length=70,
30 ):
31 if not version:
32 raise ValueError("'version' argument is required in Sphinx directives")
33 self.directive = directive
34 self.line_length = line_length
35 super().__init__(
36 reason=reason, version=version, action=action, category=category, extra_stacklevel=extra_stacklevel
37 )
39 def __call__(self, wrapped):
40 fmt = ".. {directive}:: {version}" if self.version else ".. {directive}::"
41 div_lines = [fmt.format(directive=self.directive, version=self.version)]
42 width = self.line_length - 3 if self.line_length > 3 else 2**16
43 reason = textwrap.dedent(self.reason).strip()
44 for paragraph in reason.splitlines():
45 if paragraph:
46 div_lines.extend(
47 textwrap.fill(
48 paragraph,
49 width=width,
50 initial_indent=" ",
51 subsequent_indent=" ",
52 ).splitlines()
53 )
54 else:
55 div_lines.append("")
57 docstring = wrapped.__doc__ or ""
58 lines = docstring.splitlines(True) or [""]
59 docstring = textwrap.dedent("".join(lines[1:])) if len(lines) > 1 else ""
60 docstring = lines[0] + docstring
61 if docstring:
62 docstring = re.sub(r"\n+$", "", docstring, flags=re.DOTALL) + "\n\n"
63 else:
64 docstring = "\n"
66 docstring += "".join(f"{line}\n" for line in div_lines)
68 wrapped.__doc__ = docstring
69 if self.directive in {"versionadded", "versionchanged"}:
70 return wrapped
71 return super().__call__(wrapped)
73 def get_deprecated_msg(self, wrapped, instance):
74 msg = super().get_deprecated_msg(wrapped, instance) 1b
75 msg = re.sub(r"(?: : [a-zA-Z]+ )? : [a-zA-Z]+ : (`[^`]*`)", r"\1", msg, flags=re.X) 1b
76 return msg 1b
79def versionadded(reason="", version="", line_length=70):
80 """
81 Decorator that inserts a "versionadded" Sphinx directive into the docstring.
82 """
83 return SphinxAdapter(
84 "versionadded",
85 reason=reason,
86 version=version,
87 line_length=line_length,
88 )
91def versionchanged(reason="", version="", line_length=70):
92 """
93 Decorator that inserts a "versionchanged" Sphinx directive into the docstring.
94 """
95 return SphinxAdapter(
96 "versionchanged",
97 reason=reason,
98 version=version,
99 line_length=line_length,
100 )
103def deprecated(reason="", version="", line_length=70, **kwargs):
104 """
105 Decorator that inserts a "deprecated" Sphinx directive into the docstring
106 and emits a :exc:`DeprecationWarning` when the decorated object is called.
107 """
108 directive = kwargs.pop("directive", "deprecated")
109 adapter_cls = kwargs.pop("adapter_cls", SphinxAdapter)
110 kwargs["reason"] = reason
111 kwargs["version"] = version
112 kwargs["line_length"] = line_length
113 return _classic_deprecated(directive=directive, adapter_cls=adapter_cls, **kwargs)