Skip to content

Commit

Permalink
Python: adds LSET command (valkey-io#1584)
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamazon authored and cyip10 committed Jun 24, 2024
1 parent 4f1d102 commit 1651287
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* Python: Added HSTRLEN command ([#1564](https://github.com/aws/glide-for-redis/pull/1564))
* Python: Added MSETNX command ([#1565](https://github.com/aws/glide-for-redis/pull/1565))
* Python: Added MOVE command ([#1566](https://github.com/aws/glide-for-redis/pull/1566))
* Python: Added LSET command ([#1584](https://github.com/aws/glide-for-redis/pull/1584))
* Node: Added OBJECT IDLETIME command ([#1567](https://github.com/aws/glide-for-redis/pull/1567))
* Node: Added OBJECT REFCOUNT command ([#1568](https://github.com/aws/glide-for-redis/pull/1568))
* Python: Added SETBIT command ([#1571](https://github.com/aws/glide-for-redis/pull/1571))
Expand Down
27 changes: 27 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,33 @@ async def lindex(
await self._execute_command(RequestType.LIndex, [key, str(index)]),
)

async def lset(self, key: str, index: int, element: str) -> TOK:
"""
Sets the list element at `index` to `element`.
The index is zero-based, so `0` means the first element, `1` the second element and so on.
Negative indices can be used to designate elements starting at the tail of the list.
Here, `-1` means the last element, `-2` means the penultimate and so forth.
See https://valkey.io/commands/lset/ for details.
Args:
key (str): The key of the list.
index (int): The index of the element in the list to be set.
element (str): The new element to set at the specified index.
Returns:
TOK: A simple `OK` response.
Examples:
>>> await client.lset("testKey", 1, "two")
OK
"""
return cast(
TOK,
await self._execute_command(RequestType.LSet, [key, str(index), element]),
)

async def rpush(self, key: str, elements: List[str]) -> int:
"""
Inserts all the specified values at the tail of the list stored at `key`.
Expand Down
20 changes: 20 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,26 @@ def lindex(
"""
return self.append_command(RequestType.LIndex, [key, str(index)])

def lset(self: TTransaction, key: str, index: int, element: str) -> TTransaction:
"""
Sets the list element at `index` to `element`.
The index is zero-based, so `0` means the first element, `1` the second element and so on.
Negative indices can be used to designate elements starting at the tail of the list.
Here, `-1` means the last element, `-2` means the penultimate and so forth.
See https://valkey.io/commands/lset/ for details.
Args:
key (str): The key of the list.
index (int): The index of the element in the list to be set.
element (str): The new element to set at the specified index.
Commands response:
TOK: A simple `OK` response.
"""
return self.append_command(RequestType.LSet, [key, str(index), element])

def rpush(self: TTransaction, key: str, elements: List[str]) -> TTransaction:
"""Inserts all the specified values at the tail of the list stored at `key`.
`elements` are inserted one after the other to the tail of the list, from the leftmost element
Expand Down
30 changes: 30 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,36 @@ async def endless_blmove_call():
with pytest.raises(asyncio.TimeoutError):
await asyncio.wait_for(endless_blmove_call(), timeout=3)

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_lset(self, redis_client: TRedisClient):
key = get_random_string(10)
element = get_random_string(5)
values = [get_random_string(5) for _ in range(4)]

# key does not exist
with pytest.raises(RequestError):
await redis_client.lset("non_existing_key", 0, element)

# pushing elements to list
await redis_client.lpush(key, values) == 4

# index out of range
with pytest.raises(RequestError):
await redis_client.lset(key, 10, element)

# assert lset result
assert await redis_client.lset(key, 0, element) == OK

values = [element] + values[:-1][::-1]
assert await redis_client.lrange(key, 0, -1) == values

# assert lset with a negative index for the last element in the list
assert await redis_client.lset(key, -1, element) == OK

values[-1] = element
assert await redis_client.lrange(key, 0, -1) == values

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_sadd_srem_smembers_scard(self, redis_client: TRedisClient):
Expand Down
2 changes: 2 additions & 0 deletions python/python/tests/test_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ async def transaction_test(
args.append([key9, value3])
transaction.brpop([key9], 1)
args.append([key9, value])
transaction.lset(key9, 0, value2)
args.append(OK)

transaction.sadd(key7, ["foo", "bar"])
args.append(2)
Expand Down

0 comments on commit 1651287

Please sign in to comment.