From 9f9a34f7a550bdb4df568d0e02e831c80b1b5572 Mon Sep 17 00:00:00 2001 From: Didrik Frimann Barroso Koren Date: Sat, 8 Aug 2020 22:58:54 +0200 Subject: [PATCH 1/3] Add deprecation decorator --- podgen/decorators.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 podgen/decorators.py diff --git a/podgen/decorators.py b/podgen/decorators.py new file mode 100644 index 0000000..45d45fd --- /dev/null +++ b/podgen/decorators.py @@ -0,0 +1,28 @@ +import warnings + +def deprecated(deprecated_since, removed_in, description): + """Decorator for marking functions as deprecated. It wraps and copies name + and documentation of the decorated function. This decorator only allows for + deprecation of functions. + + :param deprecated_since: Version in which the function was deprecated. + :param removed_in: Version in which the function is to be removed. + :param description: Description of the deprecation. + :returns: Decorated function. + """ + + def deprecation_decorator(func): + def func_wrapper(*args, **kwargs): + warnings.warn( + "{} is deprecated as of {} and will be removed in {}. {}" + .format(func.__name__, deprecated_since, removed_in, description), + category=DeprecationWarning, + stacklevel=2 + ) + return func(*args, **kwargs) + + # Hide the decorator by taking the decorated functions name and docs. + func_wrapper.__name__ = func.__name__ + func_wrapper.__doc__ = func.__doc__ + return func_wrapper + return deprecation_decorator From d0496c3ea37b23dd01c728a8793c3b62887dca2a Mon Sep 17 00:00:00 2001 From: Didrik Frimann Barroso Koren Date: Sat, 8 Aug 2020 22:59:33 +0200 Subject: [PATCH 2/3] Deprecate direct usage of __str__ on podcast --- podgen/podcast.py | 2 ++ podgen/tests/test_podcast.py | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/podgen/podcast.py b/podgen/podcast.py index 41e96a3..0c8caa9 100644 --- a/podgen/podcast.py +++ b/podgen/podcast.py @@ -20,6 +20,7 @@ import dateutil.tz from podgen import EPISODE_TYPE_FULL +from podgen.decorators import deprecated from podgen.episode import Episode from podgen.warnings import NotSupportedByItunesWarning from podgen.util import ensure_format, formatRFC2822, listToHumanreadableStr, \ @@ -670,6 +671,7 @@ def _get_xslt_pi(self): 'type="text/xsl" href="' + quote_sanitized + '"', ), encoding="UTF-8").decode("UTF-8") + @deprecated('1.2.0', '2.0.0', 'Please use rss_str() directly.') def __str__(self): """Print the podcast in RSS format, using the default options. diff --git a/podgen/tests/test_podcast.py b/podgen/tests/test_podcast.py index fa81180..9a6fd5d 100644 --- a/podgen/tests/test_podcast.py +++ b/podgen/tests/test_podcast.py @@ -305,6 +305,15 @@ def test_generator(self): assert software_name in generator assert self.programname not in generator + def test__str__deprecation(self): + # Context manager catches and records deprecation warnings. + with warnings.catch_warnings(record=True) as catched_warning: + warnings.simplefilter("always") + + assert str(self.fg) + assert len(catched_warning) == 1 + assert issubclass(catched_warning[-1].category, DeprecationWarning) + def test_str(self): assert str(self.fg) == self.fg.rss_str( minimize=False, From c76d3ea881e255cd072fe2fd6461b41a8b39ba91 Mon Sep 17 00:00:00 2001 From: Didrik Frimann Barroso Koren Date: Sat, 8 Aug 2020 23:44:52 +0200 Subject: [PATCH 3/3] Extract deprecation_warning to standalone function --- podgen/decorators.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/podgen/decorators.py b/podgen/decorators.py index 45d45fd..1c2ab43 100644 --- a/podgen/decorators.py +++ b/podgen/decorators.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import warnings def deprecated(deprecated_since, removed_in, description): @@ -13,12 +15,11 @@ def deprecated(deprecated_since, removed_in, description): def deprecation_decorator(func): def func_wrapper(*args, **kwargs): - warnings.warn( - "{} is deprecated as of {} and will be removed in {}. {}" - .format(func.__name__, deprecated_since, removed_in, description), - category=DeprecationWarning, - stacklevel=2 - ) + deprecation_warning( + func.__name__, + deprecated_since, + removed_in, + description) return func(*args, **kwargs) # Hide the decorator by taking the decorated functions name and docs. @@ -26,3 +27,18 @@ def func_wrapper(*args, **kwargs): func_wrapper.__doc__ = func.__doc__ return func_wrapper return deprecation_decorator + +def deprecation_warning( + deprecated_name, + deprecated_since, + removed_in, + description): + + warnings.warn\ + ( + "{} is deprecated as of {} and will be removed in {}. {}" \ + .format(deprecated_name, deprecated_since, removed_in, \ + description), + category=DeprecationWarning, + stacklevel=2 + )