Skip to content

Commit d69e7c4

Browse files
authored
Merge pull request #239 from tomschr/bugfix/236-deprecate-others
Fix #236: add missing deprecated functions
2 parents 9691b41 + 1c8fc74 commit d69e7c4

File tree

2 files changed

+120
-71
lines changed

2 files changed

+120
-71
lines changed

semver.py

Lines changed: 118 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -371,29 +371,80 @@ def bump_build(self, token="build"):
371371
build = cls._increment_string(self._build or (token or "build") + ".0")
372372
return cls(self._major, self._minor, self._patch, self._prerelease, build)
373373

374+
def compare(self, other):
375+
"""
376+
Compare self with other.
377+
378+
:param other: the second version (can be string, a dict, tuple/list, or
379+
a VersionInfo instance)
380+
:return: The return value is negative if ver1 < ver2,
381+
zero if ver1 == ver2 and strictly positive if ver1 > ver2
382+
:rtype: int
383+
384+
>>> semver.VersionInfo.parse("1.0.0").compare("2.0.0")
385+
-1
386+
>>> semver.VersionInfo.parse("2.0.0").compare("1.0.0")
387+
1
388+
>>> semver.VersionInfo.parse("2.0.0").compare("2.0.0")
389+
0
390+
>>> semver.VersionInfo.parse("2.0.0").compare(dict(major=2, minor=0, patch=0))
391+
0
392+
"""
393+
cls = type(self)
394+
if isinstance(other, str):
395+
other = cls.parse(other)
396+
elif isinstance(other, dict):
397+
other = cls(**other)
398+
elif isinstance(other, (tuple, list)):
399+
other = cls(*other)
400+
elif not isinstance(other, cls):
401+
raise TypeError(
402+
"Expected str or {} instance, but got {}".format(
403+
cls.__name__, type(other)
404+
)
405+
)
406+
407+
v1 = self.to_tuple()[:3]
408+
v2 = other.to_tuple()[:3]
409+
x = cmp(v1, v2)
410+
if x:
411+
return x
412+
413+
rc1, rc2 = self.prerelease, other.prerelease
414+
rccmp = _nat_cmp(rc1, rc2)
415+
416+
if not rccmp:
417+
return 0
418+
if not rc1:
419+
return 1
420+
elif not rc2:
421+
return -1
422+
423+
return rccmp
424+
374425
@comparator
375426
def __eq__(self, other):
376-
return _compare_by_keys(self.to_dict(), _to_dict(other)) == 0
427+
return self.compare(other) == 0
377428

378429
@comparator
379430
def __ne__(self, other):
380-
return _compare_by_keys(self.to_dict(), _to_dict(other)) != 0
431+
return self.compare(other) != 0
381432

382433
@comparator
383434
def __lt__(self, other):
384-
return _compare_by_keys(self.to_dict(), _to_dict(other)) < 0
435+
return self.compare(other) < 0
385436

386437
@comparator
387438
def __le__(self, other):
388-
return _compare_by_keys(self.to_dict(), _to_dict(other)) <= 0
439+
return self.compare(other) <= 0
389440

390441
@comparator
391442
def __gt__(self, other):
392-
return _compare_by_keys(self.to_dict(), _to_dict(other)) > 0
443+
return self.compare(other) > 0
393444

394445
@comparator
395446
def __ge__(self, other):
396-
return _compare_by_keys(self.to_dict(), _to_dict(other)) >= 0
447+
return self.compare(other) >= 0
397448

398449
def __repr__(self):
399450
s = ", ".join("%s=%r" % (key, val) for key, val in self.to_dict().items())
@@ -424,6 +475,53 @@ def finalize_version(self):
424475
cls = type(self)
425476
return cls(self.major, self.minor, self.patch)
426477

478+
def match(self, match_expr):
479+
"""
480+
Compare self to match a match expression.
481+
482+
:param str match_expr: operator and version; valid operators are
483+
< smaller than
484+
> greater than
485+
>= greator or equal than
486+
<= smaller or equal than
487+
== equal
488+
!= not equal
489+
:return: True if the expression matches the version, otherwise False
490+
:rtype: bool
491+
492+
>>> semver.VersionInfo.parse("2.0.0").match(">=1.0.0")
493+
True
494+
>>> semver.VersionInfo.parse("1.0.0").match(">1.0.0")
495+
False
496+
"""
497+
prefix = match_expr[:2]
498+
if prefix in (">=", "<=", "==", "!="):
499+
match_version = match_expr[2:]
500+
elif prefix and prefix[0] in (">", "<"):
501+
prefix = prefix[0]
502+
match_version = match_expr[1:]
503+
else:
504+
raise ValueError(
505+
"match_expr parameter should be in format <op><ver>, "
506+
"where <op> is one of "
507+
"['<', '>', '==', '<=', '>=', '!=']. "
508+
"You provided: %r" % match_expr
509+
)
510+
511+
possibilities_dict = {
512+
">": (1,),
513+
"<": (-1,),
514+
"==": (0,),
515+
"!=": (-1, 1),
516+
">=": (0, 1),
517+
"<=": (-1, 0),
518+
}
519+
520+
possibilities = possibilities_dict[prefix]
521+
cmp_res = self.compare(match_version)
522+
523+
return cmp_res in possibilities
524+
427525
@staticmethod
428526
def parse(version):
429527
"""
@@ -495,14 +593,6 @@ def isvalid(cls, version):
495593
return False
496594

497595

498-
def _to_dict(obj):
499-
if isinstance(obj, VersionInfo):
500-
return obj.to_dict()
501-
elif isinstance(obj, tuple):
502-
return VersionInfo(*obj).to_dict()
503-
return obj
504-
505-
506596
@deprecated(replace="semver.VersionInfo.parse", version="2.10.0")
507597
def parse_version_info(version):
508598
"""
@@ -560,25 +650,7 @@ def cmp_prerelease_tag(a, b):
560650
return cmp(len(a), len(b))
561651

562652

563-
def _compare_by_keys(d1, d2):
564-
for key in ["major", "minor", "patch"]:
565-
v = cmp(d1.get(key), d2.get(key))
566-
if v:
567-
return v
568-
569-
rc1, rc2 = d1.get("prerelease"), d2.get("prerelease")
570-
rccmp = _nat_cmp(rc1, rc2)
571-
572-
if not rccmp:
573-
return 0
574-
if not rc1:
575-
return 1
576-
elif not rc2:
577-
return -1
578-
579-
return rccmp
580-
581-
653+
@deprecated(version="2.10.0")
582654
def compare(ver1, ver2):
583655
"""
584656
Compare two versions strings.
@@ -596,13 +668,11 @@ def compare(ver1, ver2):
596668
>>> semver.compare("2.0.0", "2.0.0")
597669
0
598670
"""
599-
600-
v1 = VersionInfo.parse(ver1).to_dict()
601-
v2 = VersionInfo.parse(ver2).to_dict()
602-
603-
return _compare_by_keys(v1, v2)
671+
v1 = VersionInfo.parse(ver1)
672+
return v1.compare(ver2)
604673

605674

675+
@deprecated(version="2.10.0")
606676
def match(version, match_expr):
607677
"""
608678
Compare two versions strings through a comparison.
@@ -623,33 +693,8 @@ def match(version, match_expr):
623693
>>> semver.match("1.0.0", ">1.0.0")
624694
False
625695
"""
626-
prefix = match_expr[:2]
627-
if prefix in (">=", "<=", "==", "!="):
628-
match_version = match_expr[2:]
629-
elif prefix and prefix[0] in (">", "<"):
630-
prefix = prefix[0]
631-
match_version = match_expr[1:]
632-
else:
633-
raise ValueError(
634-
"match_expr parameter should be in format <op><ver>, "
635-
"where <op> is one of "
636-
"['<', '>', '==', '<=', '>=', '!=']. "
637-
"You provided: %r" % match_expr
638-
)
639-
640-
possibilities_dict = {
641-
">": (1,),
642-
"<": (-1,),
643-
"==": (0,),
644-
"!=": (-1, 1),
645-
">=": (0, 1),
646-
"<=": (-1, 0),
647-
}
648-
649-
possibilities = possibilities_dict[prefix]
650-
cmp_res = compare(version, match_version)
651-
652-
return cmp_res in possibilities
696+
ver = VersionInfo.parse(version)
697+
return ver.match(match_expr)
653698

654699

655700
def max_ver(ver1, ver2):
@@ -664,9 +709,10 @@ def max_ver(ver1, ver2):
664709
>>> semver.max_ver("1.0.0", "2.0.0")
665710
'2.0.0'
666711
"""
667-
cmp_res = compare(ver1, ver2)
668-
if cmp_res == 0 or cmp_res == 1:
669-
return ver1
712+
ver1 = VersionInfo.parse(ver1)
713+
cmp_res = ver1.compare(ver2)
714+
if cmp_res >= 0:
715+
return str(ver1)
670716
else:
671717
return ver2
672718

@@ -683,9 +729,10 @@ def min_ver(ver1, ver2):
683729
>>> semver.min_ver("1.0.0", "2.0.0")
684730
'1.0.0'
685731
"""
686-
cmp_res = compare(ver1, ver2)
687-
if cmp_res == 0 or cmp_res == -1:
688-
return ver1
732+
ver1 = VersionInfo.parse(ver1)
733+
cmp_res = ver1.compare(ver2)
734+
if cmp_res <= 0:
735+
return str(ver1)
689736
else:
690737
return ver2
691738

test_semver.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,8 +855,10 @@ def test_should_versioninfo_isvalid():
855855
(bump_minor, ("1.2.3",), {}),
856856
(bump_patch, ("1.2.3",), {}),
857857
(bump_prerelease, ("1.2.3",), {}),
858+
(compare, ("1.2.1", "1.2.2"), {}),
858859
(format_version, (3, 4, 5), {}),
859860
(finalize_version, ("1.2.3-rc.5",), {}),
861+
(match, ("1.0.0", ">=1.0.0"), {}),
860862
(parse, ("1.2.3",), {}),
861863
(parse_version_info, ("1.2.3",), {}),
862864
(replace, ("1.2.3",), dict(major=2, patch=10)),

0 commit comments

Comments
 (0)