Skip to content

Commit db55f27

Browse files
authored
Ensure equal versions have equal hashes (#283)
* Version equality means for semver, that `major`, `minor`, `patch`, and `prerelease` parts are equal in both versions you compare. The `build` part is ignored. * Improve docs to describe version comparison
1 parent 49229d9 commit db55f27

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

docs/usage.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,32 @@ functions that leverage this capability; builtins including, but not limited to:
467467
(for examples, see :ref:`sec_max_min`) and :func:`sorted`.
468468

469469

470+
Determining Version Equality
471+
----------------------------
472+
473+
Version equality means for semver, that major, minor, patch, and prerelease
474+
parts are equal in both versions you compare. The build part is ignored.
475+
For example::
476+
477+
>>> v = semver.VersionInfo.parse("1.2.3-rc4+1e4664d")
478+
>>> v == "1.2.3-rc4+dedbeef"
479+
True
480+
481+
This also applies when a :class:`semver.VersionInfo` is a member of a set, or a
482+
dictionary key::
483+
484+
>>> d = {}
485+
>>> v1 = semver.VersionInfo.parse("1.2.3-rc4+1e4664d")
486+
>>> v2 = semver.VersionInfo.parse("1.2.3-rc4+dedbeef")
487+
>>> d[v1] = 1
488+
>>> d[v2]
489+
1
490+
>>> s = set()
491+
>>> s.add(v1)
492+
>>> v2 in s
493+
True
494+
495+
470496

471497
Comparing Versions through an Expression
472498
----------------------------------------

semver.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ def __str__(self):
641641
return version
642642

643643
def __hash__(self):
644-
return hash(self.to_tuple())
644+
return hash(self.to_tuple()[:4])
645645

646646
def finalize_version(self):
647647
"""

test_semver.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,20 @@ def test_parse_version_info_str_hash():
693693
d[v] = "" # to ensure that VersionInfo are hashable
694694

695695

696+
def test_equal_versions_have_equal_hashes():
697+
v1 = parse_version_info("1.2.3-alpha.1.2+build.11.e0f985a")
698+
v2 = parse_version_info("1.2.3-alpha.1.2+build.22.a589f0e")
699+
assert v1 == v2
700+
assert hash(v1) == hash(v2)
701+
d = {}
702+
d[v1] = 1
703+
d[v2] = 2
704+
assert d[v1] == 2
705+
s = set()
706+
s.add(v1)
707+
assert v2 in s
708+
709+
696710
def test_parse_method_for_version_info():
697711
s_version = "1.2.3-alpha.1.2+build.11.e0f985a"
698712
v = VersionInfo.parse(s_version)

0 commit comments

Comments
 (0)