Skip to content

Commit 08c71eb

Browse files
committed
Improve deprecated decorator
Allow optional arguments replace and version
1 parent da7a12c commit 08c71eb

File tree

1 file changed

+55
-25
lines changed

1 file changed

+55
-25
lines changed

semver.py

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
import argparse
55
import collections
6-
from functools import wraps
6+
from functools import wraps, partial
7+
import inspect
78
import re
89
import sys
910
import warnings
@@ -28,35 +29,62 @@ def cmp(a, b):
2829
return (a > b) - (a < b)
2930

3031

31-
def deprecated(replace=None):
32+
def deprecated(func=None, replace=None, version=None, category=DeprecationWarning):
3233
"""
3334
Decorates a function to output a deprecation warning.
3435
35-
:param str replace: the name of the function which the deprecated
36-
function should be replaced with
37-
3836
This function will be removed once major version 4 of semver is
3937
released.
40-
"""
4138
42-
def decorator(func):
43-
r = replace or func.__name__ # __qualname__
39+
:param str replace: the function to replace (use the full qualified
40+
name like ``semver.VersionInfo.bump_major``.
41+
:param str version: the first version when this function was deprecated.
42+
:param category: allow you to specify the deprecation warning class
43+
of your choice. By default, it's :class:`DeprecationWarning`, but
44+
you can choose :class:`PendingDeprecationWarning``or a custom class.
45+
"""
4446

47+
def decorator():
4548
@wraps(func)
4649
def wrapper(*args, **kwargs):
47-
msg = (
48-
"Function 'semver.{f}' is deprecated. "
49-
"Use the respective 'semver.VersionInfo.{r}' instead."
50+
msg = ["Function 'semver.{f}' is deprecated."]
51+
52+
if version:
53+
msg.append("Deprecated since version {v}.")
54+
55+
if replace:
56+
msg.append("Use {r!r} instead.")
57+
else:
58+
msg.append("Use the respective 'semver.VersionInfo.{r}' instead.")
59+
60+
# warnings.simplefilter('always', category)
61+
frame = inspect.currentframe().f_back
62+
63+
msg = " ".join(msg)
64+
msg = msg.format(f=func.__name__, r=replace, v=version)
65+
warnings.warn_explicit(
66+
msg,
67+
category=category,
68+
# stacklevel=2,
69+
filename=inspect.getfile(frame.f_code),
70+
lineno=frame.f_lineno,
5071
)
51-
warnings.warn(msg.format(f=func.__name__, r=r), category=DeprecationWarning)
72+
# warnings.simplefilter('default', category)
73+
# As recommended in the Python documentation
74+
# https://docs.python.org/3/library/inspect.html#the-interpreter-stack
75+
# better remove the interpreter stack:
76+
del frame
5277
return func(*args, **kwargs)
5378

5479
return wrapper
5580

56-
return decorator
81+
if callable(func):
82+
return decorator()
83+
else:
84+
return partial(deprecated, replace=replace, version=version, category=category)
5785

5886

59-
@deprecated()
87+
@deprecated(version="2.9.2")
6088
def parse(version):
6189
"""
6290
Parse version to major, minor, patch, pre-release, build parts.
@@ -229,8 +257,10 @@ def to_dict(self):
229257
)
230258

231259
# For compatibility reasons:
232-
_astuple = deprecated("to_tuple")(to_tuple)
233-
_asdict = deprecated("to_dict")(to_dict)
260+
_astuple = deprecated(replace="semver.VersionInfo.to_tuple", version="2.9.2")(
261+
to_tuple
262+
)
263+
_asdict = deprecated(replace="semver.VersionInfo.to_dict", version="2.9.2")(to_dict)
234264

235265
def __iter__(self):
236266
"""Implement iter(self)."""
@@ -450,7 +480,7 @@ def _to_dict(obj):
450480
return obj
451481

452482

453-
@deprecated("parse")
483+
@deprecated(replace="semver.VersionInfo.parse", version="2.9.2")
454484
def parse_version_info(version):
455485
"""
456486
Parse version string to a VersionInfo instance.
@@ -640,7 +670,7 @@ def min_ver(ver1, ver2):
640670
return ver2
641671

642672

643-
@deprecated()
673+
@deprecated(version="2.9.2")
644674
def format_version(major, minor, patch, prerelease=None, build=None):
645675
"""
646676
Format a version string according to the Semantic Versioning specification.
@@ -676,7 +706,7 @@ def _increment_string(string):
676706
return string
677707

678708

679-
@deprecated()
709+
@deprecated(version="2.9.2")
680710
def bump_major(version):
681711
"""
682712
Raise the major part of the version string.
@@ -694,7 +724,7 @@ def bump_major(version):
694724
return str(VersionInfo.parse(version).bump_major())
695725

696726

697-
@deprecated()
727+
@deprecated(version="2.9.2")
698728
def bump_minor(version):
699729
"""
700730
Raise the minor part of the version string.
@@ -712,7 +742,7 @@ def bump_minor(version):
712742
return str(VersionInfo.parse(version).bump_minor())
713743

714744

715-
@deprecated()
745+
@deprecated(version="2.9.2")
716746
def bump_patch(version):
717747
"""
718748
Raise the patch part of the version string.
@@ -730,7 +760,7 @@ def bump_patch(version):
730760
return str(VersionInfo.parse(version).bump_patch())
731761

732762

733-
@deprecated()
763+
@deprecated(version="2.9.2")
734764
def bump_prerelease(version, token="rc"):
735765
"""
736766
Raise the prerelease part of the version string.
@@ -749,7 +779,7 @@ def bump_prerelease(version, token="rc"):
749779
return str(VersionInfo.parse(version).bump_prerelease(token))
750780

751781

752-
@deprecated()
782+
@deprecated(version="2.9.2")
753783
def bump_build(version, token="build"):
754784
"""
755785
Raise the build part of the version string.
@@ -768,7 +798,7 @@ def bump_build(version, token="build"):
768798
return str(VersionInfo.parse(version).bump_build(token))
769799

770800

771-
@deprecated()
801+
@deprecated(version="2.9.2")
772802
def finalize_version(version):
773803
"""
774804
Remove any prerelease and build metadata from the version string.
@@ -790,7 +820,7 @@ def finalize_version(version):
790820
return str(verinfo.finalize_version())
791821

792822

793-
@deprecated()
823+
@deprecated(version="2.9.2")
794824
def replace(version, **parts):
795825
"""
796826
Replace one or more parts of a version and return the new string.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy