From 196df654f0a9c5846f42eca2a38717efc57849e5 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Sun, 29 Sep 2019 23:28:05 +0200 Subject: [PATCH 1/8] Fix #135, convert prerelease and build to string Creating VersionInfo(3, 2, 1, 1) succeeds, but fails later when comparing it with another VersionInfo instance (for example, v1 < v2): ``` def split_key(key): > return [convert(c) for c in key.split('.')] E AttributeError: 'int' object has no attribute 'split' ``` --- semver.py | 4 ++-- test_semver.py | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/semver.py b/semver.py index d234f26a..fff89a1d 100644 --- a/semver.py +++ b/semver.py @@ -102,8 +102,8 @@ def __init__(self, major, minor=0, patch=0, prerelease=None, build=None): self._major = major self._minor = minor self._patch = patch - self._prerelease = prerelease - self._build = build + self._prerelease = None if prerelease is None else str(prerelease) + self._build = None if build is None else str(build) @property def major(self): diff --git a/test_semver.py b/test_semver.py index 96b78967..f3f57676 100644 --- a/test_semver.py +++ b/test_semver.py @@ -497,3 +497,9 @@ def test_immutable_unknown_attribute(version): def test_version_info_should_be_iterable(version): assert tuple(version) == (version.major, version.minor, version.patch, version.prerelease, version.build) + + +def test_should_compare_prerelease_and_build_with_numbers(): + v1 = VersionInfo(major=1, minor=9, patch=1, prerelease=1, build=1) + v2 = VersionInfo(major=1, minor=9, patch=1, prerelease=2, build=1) + assert v1 < v2 From 2f5a68db22781f8fbece4c4fd43275fcb659715e Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Mon, 30 Sep 2019 08:38:56 +0200 Subject: [PATCH 2/8] Force major, minor, and patch as int To allow VersionInfo(10) > VersionInfo('2') == True --- semver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/semver.py b/semver.py index fff89a1d..ec764946 100644 --- a/semver.py +++ b/semver.py @@ -99,9 +99,9 @@ class VersionInfo(object): __slots__ = ('_major', '_minor', '_patch', '_prerelease', '_build') def __init__(self, major, minor=0, patch=0, prerelease=None, build=None): - self._major = major - self._minor = minor - self._patch = patch + self._major = int(major) + self._minor = int(minor) + self._patch = int(patch) self._prerelease = None if prerelease is None else str(prerelease) self._build = None if build is None else str(build) From ef9abb1253f76ec6f8dcdf61d77e2cfef1549309 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Mon, 30 Sep 2019 08:40:59 +0200 Subject: [PATCH 3/8] Enhance test_should_compare_prerelease_and_build_with_numbers Add example from #135 --- test_semver.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test_semver.py b/test_semver.py index f3f57676..dc9e3e57 100644 --- a/test_semver.py +++ b/test_semver.py @@ -499,7 +499,13 @@ def test_version_info_should_be_iterable(version): version.prerelease, version.build) -def test_should_compare_prerelease_and_build_with_numbers(): - v1 = VersionInfo(major=1, minor=9, patch=1, prerelease=1, build=1) - v2 = VersionInfo(major=1, minor=9, patch=1, prerelease=2, build=1) - assert v1 < v2 +@pytest.mark.parametrize("v1,v2", [ + # no. 1 + ({'major': 1, 'minor': 9, 'patch': 1, 'prerelease': 1, 'build': 1}, + {'major': 1, 'minor': 9, 'patch': 1, 'prerelease': 2, 'build': 1}), + # no. 2 + ({'major': 3, 'minor': 2, 'patch': 1, 'prerelease': 1}, + {'major': 3, 'minor': 2, 'patch': 1, 'prerelease': 3}), +]) +def test_should_compare_prerelease_and_build_with_numbers(v1, v2): + assert VersionInfo(**v1) < VersionInfo(**v2) From d708dd7384be4f86887e7a7d5f01fc35689b8ffd Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Mon, 30 Sep 2019 09:59:09 +0200 Subject: [PATCH 4/8] Simplify test case, thanks to Alexander Co-authored-by: Alexander Grund --- test_semver.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/test_semver.py b/test_semver.py index dc9e3e57..6f018e1c 100644 --- a/test_semver.py +++ b/test_semver.py @@ -499,13 +499,9 @@ def test_version_info_should_be_iterable(version): version.prerelease, version.build) -@pytest.mark.parametrize("v1,v2", [ - # no. 1 - ({'major': 1, 'minor': 9, 'patch': 1, 'prerelease': 1, 'build': 1}, - {'major': 1, 'minor': 9, 'patch': 1, 'prerelease': 2, 'build': 1}), - # no. 2 - ({'major': 3, 'minor': 2, 'patch': 1, 'prerelease': 1}, - {'major': 3, 'minor': 2, 'patch': 1, 'prerelease': 3}), -]) -def test_should_compare_prerelease_and_build_with_numbers(v1, v2): - assert VersionInfo(**v1) < VersionInfo(**v2) +def test_should_compare_prerelease_and_build_with_numbers(): + assert VersionInfo(major=1, minor=9, patch=1, prerelease=1, build=1) < \ + VersionInfo(major=1, minor=9, patch=1, prerelease=2, build=1) + assert VersionInfo(1, 9, 1, 1, 1) < VersionInfo(1, 9, 1, 2, 1) + assert VersionInfo('2') < VersionInfo(10) + assert VersionInfo('2') < VersionInfo('10') From a611a73f5c6879ffcd9891f5a8cd3e994ac273af Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Mon, 30 Sep 2019 11:27:27 +0200 Subject: [PATCH 5/8] Split test case and check types Co-authored-by: Alexander Grund --- test_semver.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test_semver.py b/test_semver.py index 6f018e1c..d09cd4d2 100644 --- a/test_semver.py +++ b/test_semver.py @@ -505,3 +505,19 @@ def test_should_compare_prerelease_and_build_with_numbers(): assert VersionInfo(1, 9, 1, 1, 1) < VersionInfo(1, 9, 1, 2, 1) assert VersionInfo('2') < VersionInfo(10) assert VersionInfo('2') < VersionInfo('10') + + +def test_should_be_able_to_use_strings_as_major_minor_patch(): + v = VersionInfo('1', '2', '3') + assert isinstance(v.major, int) + assert isinstance(v.minor, int) + assert isinstance(v.patch, int) + assert v.prerelease is None + assert v.build is None + + +def test_should_be_able_to_use_integers_as_prerelease_build(): + v = VersionInfo('1', '2', '3', 4, 5) + assert isinstance(v.prerelease, str) + assert isinstance(v.build, str) + assert VersionInfo('1', '2', '3') == VersionInfo(1, 2, 3) From 9361751c00299ae2d0fffb77d08bba07b19eb782 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Mon, 30 Sep 2019 19:50:28 +0200 Subject: [PATCH 6/8] Move assert line * Move assert line to test_should_be_able_to_use_strings_as_major_minor_patch * Add additional assert, comparing VersionInfo created with strings and with integers Co-authored-by: Alexander Grund --- test_semver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_semver.py b/test_semver.py index d09cd4d2..ddc3707a 100644 --- a/test_semver.py +++ b/test_semver.py @@ -514,10 +514,11 @@ def test_should_be_able_to_use_strings_as_major_minor_patch(): assert isinstance(v.patch, int) assert v.prerelease is None assert v.build is None + assert v == VersionInfo(1, 2, 3) + assert VersionInfo(1, 2, 3, 4, 5) == VersionInfo(1, 2, 3, '4', '5') def test_should_be_able_to_use_integers_as_prerelease_build(): v = VersionInfo('1', '2', '3', 4, 5) assert isinstance(v.prerelease, str) assert isinstance(v.build, str) - assert VersionInfo('1', '2', '3') == VersionInfo(1, 2, 3) From 45a10496eb05da4a17c5debfd09f4c14796f1b20 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Tue, 1 Oct 2019 09:04:28 +0200 Subject: [PATCH 7/8] Integrate tests from Alex, many thanks! Co-authored-by: Alexander Grund --- test_semver.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/test_semver.py b/test_semver.py index ddc3707a..ce968e59 100644 --- a/test_semver.py +++ b/test_semver.py @@ -514,11 +514,20 @@ def test_should_be_able_to_use_strings_as_major_minor_patch(): assert isinstance(v.patch, int) assert v.prerelease is None assert v.build is None - assert v == VersionInfo(1, 2, 3) - assert VersionInfo(1, 2, 3, 4, 5) == VersionInfo(1, 2, 3, '4', '5') + assert VersionInfo('1', '2', '3') == VersionInfo(1, 2, 3) + + +def test_using_non_numeric_string_as_major_minor_patch_throws(): + with pytest.raises(ValueError): + v = VersionInfo('a') + with pytest.raises(ValueError): + v = VersionInfo(1, 'a') + with pytest.raises(ValueError): + v = VersionInfo(1, 2, 'a') def test_should_be_able_to_use_integers_as_prerelease_build(): - v = VersionInfo('1', '2', '3', 4, 5) + v = VersionInfo(1, 2, 3, 4, 5) assert isinstance(v.prerelease, str) assert isinstance(v.build, str) + assert VersionInfo(1, 2, 3, 4, 5) == VersionInfo(1, 2, 3, '4', '5') From db851067401431abbde00d1b483ad2cb766b80d7 Mon Sep 17 00:00:00 2001 From: Thomas Schraitle Date: Tue, 1 Oct 2019 09:07:11 +0200 Subject: [PATCH 8/8] Remove v variable to silence flake8 --- test_semver.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_semver.py b/test_semver.py index ce968e59..a9b1061e 100644 --- a/test_semver.py +++ b/test_semver.py @@ -519,11 +519,11 @@ def test_should_be_able_to_use_strings_as_major_minor_patch(): def test_using_non_numeric_string_as_major_minor_patch_throws(): with pytest.raises(ValueError): - v = VersionInfo('a') + VersionInfo('a') with pytest.raises(ValueError): - v = VersionInfo(1, 'a') + VersionInfo(1, 'a') with pytest.raises(ValueError): - v = VersionInfo(1, 2, 'a') + VersionInfo(1, 2, 'a') def test_should_be_able_to_use_integers_as_prerelease_build():