From 2a7b94fb3c42955bec130c9974e7fd78d40e009e Mon Sep 17 00:00:00 2001 From: Raj Shah Date: Thu, 4 Feb 2021 18:42:15 -0800 Subject: [PATCH 1/3] Fix extended slicing on RedisList Previously, extended slices with a negative step were broken. As of this commit, they're fixed. --- pottery/list.py | 8 ++++++-- tests/test_list.py | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/pottery/list.py b/pottery/list.py index 88f0b375..33dc62db 100644 --- a/pottery/list.py +++ b/pottery/list.py @@ -86,11 +86,15 @@ def __getitem__(self, index: Union[slice, int]) -> Any: # our ridiculous hack is to get all of the elements between # start and stop from Redis, then discard the ones between step # in Python. More info: - # http://redis.io/commands/lrange + # http://redis.io/commands/lrange with self._watch() as pipeline: indices = self.__slice_to_indices(index) + if indices.step >= 0: + start, stop = indices.start, indices.stop-1 + else: + start, stop = indices.stop+1, indices.start pipeline.multi() - pipeline.lrange(self.key, indices[0], indices[-1]) + pipeline.lrange(self.key, start, stop) encoded = pipeline.execute()[0] encoded = encoded[::index.step] value: Union[List[JSONTypes], JSONTypes] = [self._decode(value) for value in encoded] diff --git a/tests/test_list.py b/tests/test_list.py index f82bfc18..8e9c5458 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -216,3 +216,8 @@ def test_json_dumps(self): '["foo", "bar", "baz", "qux", "quux", "corge", "grault", "garply", ' '"waldo", "fred", "plugh", "xyzzy", "thud"]' ) + + def test_extended_slicing(self): + python_list = [1, 2, 3, 4, 5] + redis_list = RedisList(python_list, redis=self.redis) + assert redis_list[len(redis_list)-1:3-1:-1] == python_list[len(python_list)-1:3-1:-1] From 03a0e0afa503d6dc8c2b0c464ee17a5a4dbdf7df Mon Sep 17 00:00:00 2001 From: Raj Shah Date: Thu, 4 Feb 2021 18:58:54 -0800 Subject: [PATCH 2/3] Add more unit tests I got these examples from: https://railsware.com/blog/python-for-machine-learning-indexing-and-slicing-for-lists-tuples-strings-and-other-sequential-types/#Slice_Notation --- tests/test_list.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/test_list.py b/tests/test_list.py index 8e9c5458..de0695f5 100644 --- a/tests/test_list.py +++ b/tests/test_list.py @@ -54,7 +54,7 @@ def test_mutability_and_append(self): cubes.append(7**3) assert cubes == [1, 8, 27, 64, 125, 216, 343] - def test_slices(self): + def test_slicing(self): letters = RedisList( ('a', 'b', 'c', 'd', 'e', 'f', 'g'), redis=self.redis, @@ -221,3 +221,23 @@ def test_extended_slicing(self): python_list = [1, 2, 3, 4, 5] redis_list = RedisList(python_list, redis=self.redis) assert redis_list[len(redis_list)-1:3-1:-1] == python_list[len(python_list)-1:3-1:-1] + + def test_slice_notation(self): + # I got these examples from: + # https://railsware.com/blog/python-for-machine-learning-indexing-and-slicing-for-lists-tuples-strings-and-other-sequential-types/#Slice_Notation + nums = RedisList((10, 20, 30, 40, 50, 60, 70, 80, 90), redis=self.redis) + assert nums[2:7] == [30, 40, 50, 60, 70] + assert nums[0:4] == [10, 20, 30, 40] + assert nums[:5] == [10, 20, 30, 40, 50] + assert nums[-3:] == [70, 80, 90] + assert nums[1:-1] == [20, 30, 40, 50, 60, 70, 80] + assert nums[-3:8] == [70, 80] + assert nums[-5:-1] == [50, 60, 70, 80] + assert nums[:-2] == [10, 20, 30, 40, 50, 60, 70] + assert nums[::2] == [10, 30, 50, 70, 90] + assert nums[1::2] == [20, 40, 60, 80] + assert nums[1:-3:2] == [20, 40, 60] + assert nums[::-1] == [90, 80, 70, 60, 50, 40, 30, 20, 10] + assert nums[-2::-1] == [80, 70, 60, 50, 40, 30, 20, 10] + assert nums[-2:1:-1] == [80, 70, 60, 50, 40, 30] + assert nums[-2:1:-3] == [80, 50] From 9a8bf18df1635840dd04cabd61ac7a1694d170a1 Mon Sep 17 00:00:00 2001 From: Raj Shah Date: Fri, 5 Feb 2021 14:12:26 -0800 Subject: [PATCH 3/3] Bump version number --- pottery/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pottery/__init__.py b/pottery/__init__.py index 2b283c23..b4247c15 100644 --- a/pottery/__init__.py +++ b/pottery/__init__.py @@ -18,7 +18,7 @@ __title__ = 'pottery' -__version__ = '1.1.3' +__version__ = '1.1.4' __description__, __long_description__ = ( s.strip() for s in __doc__.split(sep='\n\n', maxsplit=1) )