Skip to content

Commit c2a5ce3

Browse files
committed
Fix #225: Deprecate module level functions
* Add test cases * In `setup.cfg`, add deprecation warnings filter for pytest * Implement DeprecationWarning with warnings module and the new decorator `deprecated` * Output a DeprecationWarning for the following functions: - semver.parse - semver.parse_version_info - semver.format_version - semver.bump_{major,minor,patch,prerelease,build} - semver.finalize_version - semver.replace
1 parent c3cdfd5 commit c2a5ce3

File tree

3 files changed

+68
-10
lines changed

3 files changed

+68
-10
lines changed

semver.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from functools import wraps
77
import re
88
import sys
9+
import warnings
910

1011

1112
__version__ = "2.9.1"
@@ -27,6 +28,37 @@ def cmp(a, b):
2728
return (a > b) - (a < b)
2829

2930

31+
def deprecated(replace=None):
32+
"""
33+
Decorates a function to output a deprecation warning.
34+
35+
This function will be removed once major version 3 of semver is
36+
released.
37+
"""
38+
# we can't use the 'nonlocal' keyword in Python2, so we need
39+
# to circumvent that with a dictionary:
40+
r = {"r": replace}
41+
42+
def decorator(func):
43+
@wraps(func)
44+
def wrapper(*args, **kwargs):
45+
# nonlocal replace
46+
replace = r["r"] if r["r"] is not None else func.__name__
47+
msg = (
48+
"Function 'semver.{f}' is deprecated. "
49+
"Use the respective 'semver.VersionInfo.{r}' instead."
50+
)
51+
warnings.warn(
52+
msg.format(f=func.__name__, r=replace), category=DeprecationWarning
53+
)
54+
return func(*args, **kwargs)
55+
56+
return wrapper
57+
58+
return decorator
59+
60+
61+
@deprecated()
3062
def parse(version):
3163
"""
3264
Parse version to major, minor, patch, pre-release, build parts.
@@ -186,7 +218,7 @@ def bump_major(self):
186218
VersionInfo(major=4, minor=0, patch=0, prerelease=None, build=None)
187219
"""
188220
cls = type(self)
189-
return cls(self._major+1)
221+
return cls(self._major + 1)
190222

191223
def bump_minor(self):
192224
"""
@@ -201,7 +233,7 @@ def bump_minor(self):
201233
VersionInfo(major=3, minor=5, patch=0, prerelease=None, build=None)
202234
"""
203235
cls = type(self)
204-
return cls(self._major, self._minor+1)
236+
return cls(self._major, self._minor + 1)
205237

206238
def bump_patch(self):
207239
"""
@@ -216,7 +248,7 @@ def bump_patch(self):
216248
VersionInfo(major=3, minor=4, patch=6, prerelease=None, build=None)
217249
"""
218250
cls = type(self)
219-
return cls(self._major, self._minor, self._patch+1)
251+
return cls(self._major, self._minor, self._patch + 1)
220252

221253
def bump_prerelease(self, token="rc"):
222254
"""
@@ -233,9 +265,7 @@ def bump_prerelease(self, token="rc"):
233265
build=None)
234266
"""
235267
cls = type(self)
236-
prerelease = _increment_string(
237-
self._prerelease or (token or "rc") + ".0"
238-
)
268+
prerelease = _increment_string(self._prerelease or (token or "rc") + ".0")
239269
return cls(self._major, self._minor, self._patch, prerelease)
240270

241271
def bump_build(self, token="build"):
@@ -253,9 +283,7 @@ def bump_build(self, token="build"):
253283
build='build.10')
254284
"""
255285
cls = type(self)
256-
build = _increment_string(
257-
self._build or (token or "build") + ".0"
258-
)
286+
build = _increment_string(self._build or (token or "build") + ".0")
259287
return cls(self._major, self._minor, self._patch, self._prerelease, build)
260288

261289
@comparator
@@ -389,6 +417,7 @@ def _to_dict(obj):
389417
return obj
390418

391419

420+
@deprecated("parse")
392421
def parse_version_info(version):
393422
"""
394423
Parse version string to a VersionInfo instance.
@@ -569,6 +598,7 @@ def min_ver(ver1, ver2):
569598
return ver2
570599

571600

601+
@deprecated()
572602
def format_version(major, minor, patch, prerelease=None, build=None):
573603
"""
574604
Format a version according to the Semantic Versioning specification.
@@ -601,6 +631,7 @@ def _increment_string(string):
601631
return string
602632

603633

634+
@deprecated()
604635
def bump_major(version):
605636
"""
606637
Raise the major part of the version.
@@ -615,6 +646,7 @@ def bump_major(version):
615646
return str(VersionInfo.parse(version).bump_major())
616647

617648

649+
@deprecated()
618650
def bump_minor(version):
619651
"""
620652
Raise the minor part of the version.
@@ -629,6 +661,7 @@ def bump_minor(version):
629661
return str(VersionInfo.parse(version).bump_minor())
630662

631663

664+
@deprecated()
632665
def bump_patch(version):
633666
"""
634667
Raise the patch part of the version.
@@ -643,6 +676,7 @@ def bump_patch(version):
643676
return str(VersionInfo.parse(version).bump_patch())
644677

645678

679+
@deprecated()
646680
def bump_prerelease(version, token="rc"):
647681
"""
648682
Raise the prerelease part of the version.
@@ -658,6 +692,7 @@ def bump_prerelease(version, token="rc"):
658692
return str(VersionInfo.parse(version).bump_prerelease(token))
659693

660694

695+
@deprecated()
661696
def bump_build(version, token="build"):
662697
"""
663698
Raise the build part of the version.
@@ -673,6 +708,7 @@ def bump_build(version, token="build"):
673708
return str(VersionInfo.parse(version).bump_build(token))
674709

675710

711+
@deprecated()
676712
def finalize_version(version):
677713
"""
678714
Remove any prerelease and build metadata from the version.
@@ -688,6 +724,7 @@ def finalize_version(version):
688724
return VersionInfo.format_version(verinfo.major, verinfo.minor, verinfo.patch)
689725

690726

727+
@deprecated()
691728
def replace(version, **parts):
692729
"""
693730
Replace one or more parts of a version and return the new string.

setup.cfg

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
[tool:pytest]
22
norecursedirs = .git build .env/ env/ .pyenv/ .tmp/ .eggs/
3+
filterwarnings =
4+
ignore:Function 'semver.*:DeprecationWarning
35
addopts =
46
--ignore=.eggs/
57
--no-cov-on-fail
@@ -17,4 +19,4 @@ exclude =
1719
.git,
1820
__pycache__,
1921
build,
20-
dist
22+
dist

test_semver.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,3 +827,22 @@ def test_replace_raises_ValueError_for_non_numeric_values():
827827
def test_should_versioninfo_isvalid():
828828
assert VersionInfo.isvalid("1.0.0") is True
829829
assert VersionInfo.isvalid("foo") is False
830+
831+
832+
@pytest.mark.parametrize(
833+
"func, args, kwargs",
834+
[
835+
(bump_build, ("1.2.3",), {}),
836+
(bump_major, ("1.2.3",), {}),
837+
(bump_minor, ("1.2.3",), {}),
838+
(bump_patch, ("1.2.3",), {}),
839+
(bump_prerelease, ("1.2.3",), {}),
840+
(format_version, (3, 4, 5), {}),
841+
(parse, ("1.2.3",), {}),
842+
(parse_version_info, ("1.2.3",), {}),
843+
(replace, ("1.2.3",), dict(major=2, patch=10)),
844+
],
845+
)
846+
def test_should_raise_deprecation_warnings(func, args, kwargs):
847+
with pytest.deprecated_call():
848+
func(*args, **kwargs)

0 commit comments

Comments
 (0)