Skip to content

Commit

Permalink
Python: add GETBIT command
Browse files Browse the repository at this point in the history
  • Loading branch information
aaron-congo committed Jun 15, 2024
1 parent 0b30286 commit f27fae5
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* 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))
* Python: Added GETBIT command ([#1575](https://github.com/aws/glide-for-redis/pull/1575))

### Breaking Changes
* Node: Update XREAD to return a Map of Map ([#1494](https://github.com/aws/glide-for-redis/pull/1494))
Expand Down
24 changes: 24 additions & 0 deletions python/python/glide/async_commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4061,6 +4061,30 @@ async def setbit(self, key: str, offset: int, value: int) -> int:
),
)

async def getbit(self, key: str, offset: int) -> int:
"""
Returns the bit value at `offset` in the string value stored at `key`.
`offset` should be greater than or equal to zero.
See https://valkey.io/commands/getbit for more details.
Args:
key (str): The key of the string.
offset (int): The index of the bit to return.
Returns:
int: The bit at the given `offset` of the string. Returns `0` if the key is empty or if the positive
`offset` exceeds the length of the string.
Examples:
>>> await client.getbit("my_key", 1)
1 # Indicates that the second bit of the string stored at "my_key" is set to 1.
"""
return cast(
int,
await self._execute_command(RequestType.GetBit, [key, str(offset)]),
)

async def object_encoding(self, key: str) -> Optional[str]:
"""
Returns the internal encoding for the Redis object stored at `key`.
Expand Down
17 changes: 17 additions & 0 deletions python/python/glide/async_commands/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -2794,6 +2794,23 @@ def setbit(self: TTransaction, key: str, offset: int, value: int) -> TTransactio
"""
return self.append_command(RequestType.SetBit, [key, str(offset), str(value)])

def getbit(self: TTransaction, key: str, offset: int) -> TTransaction:
"""
Returns the bit value at `offset` in the string value stored at `key`.
`offset` should be greater than or equal to zero.
See https://valkey.io/commands/getbit for more details.
Args:
key (str): The key of the string.
offset (int): The index of the bit to return.
Command response:
int: The bit at the given `offset` of the string. Returns `0` if the key is empty or if the positive
`offset` exceeds the length of the string.
"""
return self.append_command(RequestType.GetBit, [key, str(offset)])

def object_encoding(self: TTransaction, key: str) -> TTransaction:
"""
Returns the internal encoding for the Redis object stored at `key`.
Expand Down
25 changes: 25 additions & 0 deletions python/python/tests/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4047,6 +4047,31 @@ async def test_setbit(self, redis_client: TRedisClient):
with pytest.raises(RequestError):
await redis_client.setbit(set_key, 0, 0)

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_getbit(self, redis_client: TRedisClient):
key = get_random_string(10)
non_existing_key = get_random_string(10)
set_key = get_random_string(10)
value = "foobar"

assert await redis_client.set(key, value) == OK
assert await redis_client.getbit(key, 1) == 1
assert await redis_client.getbit(key, 1000) == 0
assert await redis_client.getbit(non_existing_key, 1) == 0

assert await redis_client.setbit(key, 5, 0) == 1
assert await redis_client.getbit(key, 5) == 0

# invalid argument - offset can't be negative
with pytest.raises(RequestError):
assert await redis_client.getbit(key, -1) == 1

# key exists, but it is not a string
assert await redis_client.sadd(set_key, ["foo"]) == 1
with pytest.raises(RequestError):
await redis_client.getbit(set_key, 0)

@pytest.mark.parametrize("cluster_mode", [True, False])
@pytest.mark.parametrize("protocol", [ProtocolVersion.RESP2, ProtocolVersion.RESP3])
async def test_object_encoding(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 @@ -349,6 +349,8 @@ async def transaction_test(
args.append(0)
transaction.setbit(key19, 1, 0)
args.append(1)
transaction.getbit(key19, 1)
args.append(0)

transaction.geoadd(
key12,
Expand Down

0 comments on commit f27fae5

Please sign in to comment.