33
44import argparse
55import collections
6- from functools import wraps
6+ from functools import wraps , partial
7+ import inspect
78import re
89import sys
910import 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" )
6088def 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 " )
454484def 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" )
644674def 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" )
680710def 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" )
698728def 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" )
716746def 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" )
734764def 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" )
753783def 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" )
772802def 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" )
794824def replace (version , ** parts ):
795825 """
796826 Replace one or more parts of a version and return the new string.
0 commit comments