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

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. 

4 

5import re 

6import textwrap 

7 

8from cuda.core._vendored.deprecated.classic import ClassicAdapter 

9from cuda.core._vendored.deprecated.classic import deprecated as _classic_deprecated 

10 

11 

12class SphinxAdapter(ClassicAdapter): 

13 """ 

14 Sphinx adapter -- *for advanced usage only* 

15 

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 """ 

20 

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 ) 

38 

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("") 

56 

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" 

65 

66 docstring += "".join(f"{line}\n" for line in div_lines) 

67 

68 wrapped.__doc__ = docstring 

69 if self.directive in {"versionadded", "versionchanged"}: 

70 return wrapped 

71 return super().__call__(wrapped) 

72 

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

77 

78 

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 ) 

89 

90 

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 ) 

101 

102 

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)