jenkins-bot has submitted this change and it was merged.
Change subject: Add deprecation notice (if necessary) to docstring of @deprecated functions ......................................................................
Add deprecation notice (if necessary) to docstring of @deprecated functions
If a deprecation notice is not already present in the summary section of the docstring of a deprecated function, a notice is added to the top of the docstring.
Unit tests also added for docstring modification.
Bug: T121366 Change-Id: I56cbc07b900c1f8c45ef273dc47707cb77bec8e2 --- M pywikibot/tools/__init__.py M tests/deprecation_tests.py 2 files changed, 84 insertions(+), 0 deletions(-)
Approvals: Xqt: Looks good to me, approved jenkins-bot: Verified
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py index 6aee965..aa1ea4a 100644 --- a/pywikibot/tools/__init__.py +++ b/pywikibot/tools/__init__.py @@ -1235,11 +1235,41 @@ issue_deprecation_warning(name, instead, depth) return obj(*args, **kwargs)
+ def add_docstring(wrapper): + """Add a Deprecated notice to the docstring.""" + deprecation_notice = 'Deprecated' + if instead: + deprecation_notice += '; use ' + instead + ' instead' + deprecation_notice += '.\n\n' + if wrapper.__doc__: # Append old docstring after the notice + wrapper.__doc__ = deprecation_notice + wrapper.__doc__ + else: + wrapper.__doc__ = deprecation_notice + if not __debug__: return obj
manage_wrapping(wrapper, obj)
+ # Regular expression to find existing deprecation notices + deprecated_notice = re.compile(r'(^|\s)DEPRECATED[.:;,]', + re.IGNORECASE) + + # Add the deprecation notice to the docstring if not present + if not wrapper.__doc__: + add_docstring(wrapper) + else: + if not deprecated_notice.search(wrapper.__doc__): + add_docstring(wrapper) + else: + # Get docstring up to @params so deprecation notices for + # parameters don't disrupt it + trim_params = re.compile(r'^.*?((?=@param)|$)', re.DOTALL) + trimmed_doc = trim_params.match(wrapper.__doc__).group(0) + + if not deprecated_notice.search(trimmed_doc): # No notice + add_docstring(wrapper) + return wrapper
without_parameters = len(args) == 1 and len(kwargs) == 0 and callable(args[0]) diff --git a/tests/deprecation_tests.py b/tests/deprecation_tests.py index 97a58b5..cd25d38 100644 --- a/tests/deprecation_tests.py +++ b/tests/deprecation_tests.py @@ -82,15 +82,33 @@ return foo
+@deprecated() +def deprecated_func_docstring(foo=None): + """DEPRECATED. Deprecated function.""" + return foo + + @deprecated def deprecated_func2(foo=None): """Deprecated function.""" return foo
+@deprecated +def deprecated_func2_docstring(foo=None): + """DEPRECATED, don't use this. Deprecated function.""" + return foo + + @deprecated(instead='baz') def deprecated_func_instead(foo=None): """Deprecated function.""" + return foo + + +@deprecated(instead='baz') +def deprecated_func_instead_docstring(foo=None): + """DEPRECATED, don't use this. Deprecated function.""" return foo
@@ -103,6 +121,22 @@ @deprecate_arg('bah', 'foo') def deprecated_func_arg(foo=None): """Deprecated arg 'bah'.""" + return foo + + +@deprecated +def deprecated_func_docstring_arg(foo=None): + """@param foo: Foo. DEPRECATED.""" + return foo + + +@deprecated +def deprecated_func_docstring_arg2(foo=None): + """ + DEPRECATED. + + @param foo: Foo. DEPRECATED. + """ return foo
@@ -255,6 +289,26 @@ self.assertOneDeprecationParts(__name__ + '.deprecated_func_instead', 'baz')
+ def test_deprecated_function_docstring(self): + """Test @deprecated docstring modification.""" + testcases = [ + (deprecated_func, 'Deprecated.\n\nDeprecated function.'), + (deprecated_func_docstring, 'DEPRECATED. Deprecated function.'), + (deprecated_func2, 'Deprecated.\n\nDeprecated function.'), + (deprecated_func2_docstring, 'DEPRECATED, don't use this. ' + 'Deprecated function.'), + (deprecated_func_instead, 'Deprecated; use baz instead.\n\n' + 'Deprecated function.'), + (deprecated_func_instead_docstring, 'DEPRECATED, don't use ' + 'this. Deprecated function.'), + (deprecated_func_docstring_arg, 'Deprecated.\n\n' + '@param foo: Foo. DEPRECATED.'), + (deprecated_func_docstring_arg2, '\n DEPRECATED.\n\n' + ' @param foo: Foo. DEPRECATED.\n '), + ] + for rv, doc in testcases: + self.assertEqual(rv.__doc__, doc) + def test_deprecated_function_bad_args(self): rv = deprecated_func_bad_args(None) self.assertEqual(rv, None)