summaryrefslogtreecommitdiff
blob: 1a86ad0449d1e10954618bddec180c990b5533f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
From f332326e54a5582092b50c8fa113d11bbdf1a9e6 Mon Sep 17 00:00:00 2001
From: Thomas Laferriere <t.laferriere@hotmail.ca>
Date: Wed, 10 Jun 2020 01:44:11 -0400
Subject: [PATCH] Fix #260 __getitem__ returning `None` on falsy parts

* Fix #260 and add tests for these special cases
* Fix IndexError not being thrown every time it should
* Update CHANGELOG.rst

Co-authored-by: Tom Schraitle <tomschr@users.noreply.github.com>
---
 CHANGELOG.rst  | 28 ++++++++++++++++++++++++++++
 semver.py      |  9 ++++-----
 test_semver.py | 35 ++++++++++++++++++++++++++++-------
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index c28880e..2671ef2 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -7,6 +7,34 @@ All notable changes to this code base will be documented in this file,
 in every released version.
 
 
+Version 2.10.2 (WIP)
+====================
+
+:Released: 2020-xx-yy
+:Maintainer:
+
+Features
+--------
+
+n/a
+
+Bug Fixes
+---------
+
+:gh:`260` (:pr:`261`): Fixed ``__getitem__`` returning None on wrong parts
+
+
+Additions
+---------
+
+n/a
+
+Removals
+--------
+
+n/a
+
+
 Version 2.10.1
 ==============
 
diff --git a/semver.py b/semver.py
index 00338e8..0c98af9 100644
--- a/semver.py
+++ b/semver.py
@@ -548,17 +548,16 @@ def __getitem__(self, index):
 
         if (
             isinstance(index, slice)
-            and (index.start is None or index.start < 0)
-            and (index.stop is None or index.stop < 0)
+            and (index.start is not None and index.start < 0)
+            or (index.stop is not None and index.stop < 0)
         ):
             raise IndexError("Version index cannot be negative")
 
-        # Could raise IndexError:
-        part = tuple(filter(None, self.to_tuple()[index]))
+        part = tuple(filter(lambda p: p is not None, self.to_tuple()[index]))
 
         if len(part) == 1:
             part = part[0]
-        if not part:
+        elif not part:
             raise IndexError("Version part undefined")
         return part
 
diff --git a/test_semver.py b/test_semver.py
index 8ecc81f..1fd87ee 100644
--- a/test_semver.py
+++ b/test_semver.py
@@ -774,6 +774,8 @@ def test_should_be_able_to_use_integers_as_prerelease_build():
         ("1.2.3", 0, 1),
         ("1.2.3", 1, 2),
         ("1.2.3", 2, 3),
+        # Special cases
+        ("1.0.2", 1, 0),
     ],
 )
 def test_version_info_should_be_accessed_with_index(version, index, expected):
@@ -801,6 +803,7 @@ def test_version_info_should_be_accessed_with_index(version, index, expected):
         ("1.2.3-rc.0+build.0", slice(0, 5, 2), (1, 3, "build.0")),
         ("1.2.3-rc.0+build.0", slice(None, 5, 2), (1, 3, "build.0")),
         ("1.2.3-rc.0+build.0", slice(5, 0, -2), ("build.0", 3)),
+        ("1.2.0-rc.0+build.0", slice(3), (1, 2, 0)),
     ],
 )
 def test_version_info_should_be_accessed_with_slice_object(
@@ -813,19 +816,37 @@ def test_version_info_should_be_accessed_with_slice_object(
 @pytest.mark.parametrize(
     "version, index",
     [
-        ("1.2.3-rc.0+build.0", -1),
-        ("1.2.3-rc.0", -1),
-        ("1.2.3-rc.0", 4),
-        ("1.2.3", -1),
         ("1.2.3", 3),
+        ("1.2.3", slice(3, 4)),
         ("1.2.3", 4),
-        ("1.2.3", 10),
-        ("1.2.3", slice(-3)),
+        ("1.2.3", slice(4, 5)),
+        ("1.2.3", 5),
+        ("1.2.3", slice(5, 6)),
+        ("1.2.3-rc.0", 5),
+        ("1.2.3-rc.0", slice(5, 6)),
+        ("1.2.3-rc.0", 6),
+        ("1.2.3-rc.0", slice(6, 7)),
     ],
 )
 def test_version_info_should_throw_index_error(version, index):
     version_info = VersionInfo.parse(version)
-    with pytest.raises(IndexError):
+    with pytest.raises(IndexError, match=r"Version part undefined"):
+        version_info[index]
+
+
+@pytest.mark.parametrize(
+    "version, index",
+    [
+        ("1.2.3", -1),
+        ("1.2.3", -2),
+        ("1.2.3", slice(-2, 2)),
+        ("1.2.3", slice(2, -2)),
+        ("1.2.3", slice(-2, -2)),
+    ],
+)
+def test_version_info_should_throw_index_error_when_negative_index(version, index):
+    version_info = VersionInfo.parse(version)
+    with pytest.raises(IndexError, match=r"Version index cannot be negative"):
         version_info[index]