Skip to content

Commit 1e903ed

Browse files
Merge branch 'master' of github.com:andy-stark-redis/redis-py
2 parents ac20f42 + 843c8d5 commit 1e903ed

File tree

10 files changed

+1087
-8
lines changed

10 files changed

+1087
-8
lines changed

redis/commands/core.py

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5094,6 +5094,374 @@ def hstrlen(self, name: str, key: str) -> Union[Awaitable[int], int]:
50945094
"""
50955095
return self.execute_command("HSTRLEN", name, key, keys=[name])
50965096

5097+
def hexpire(
5098+
self,
5099+
name: KeyT,
5100+
seconds: ExpiryT,
5101+
*fields: str,
5102+
nx: bool = False,
5103+
xx: bool = False,
5104+
gt: bool = False,
5105+
lt: bool = False,
5106+
) -> ResponseT:
5107+
"""
5108+
Sets or updates the expiration time for fields within a hash key, using relative
5109+
time in seconds.
5110+
5111+
If a field already has an expiration time, the behavior of the update can be
5112+
controlled using the `nx`, `xx`, `gt`, and `lt` parameters.
5113+
5114+
The return value provides detailed information about the outcome for each field.
5115+
5116+
For more information, see https://redis.io/commands/hexpire
5117+
5118+
Args:
5119+
name: The name of the hash key.
5120+
seconds: Expiration time in seconds, relative. Can be an integer, or a
5121+
Python `timedelta` object.
5122+
fields: List of fields within the hash to apply the expiration time to.
5123+
nx: Set expiry only when the field has no expiry.
5124+
xx: Set expiry only when the field has an existing expiry.
5125+
gt: Set expiry only when the new expiry is greater than the current one.
5126+
lt: Set expiry only when the new expiry is less than the current one.
5127+
5128+
Returns:
5129+
If the key does not exist, returns an empty list. If the key exists, returns
5130+
a list which contains for each field in the request:
5131+
- `-2` if the field does not exist.
5132+
- `0` if the specified NX | XX | GT | LT condition was not met.
5133+
- `1` if the expiration time was set or updated.
5134+
- `2` if the field was deleted because the specified expiration time is
5135+
in the past.
5136+
"""
5137+
conditions = [nx, xx, gt, lt]
5138+
if sum(conditions) > 1:
5139+
raise ValueError("Only one of 'nx', 'xx', 'gt', 'lt' can be specified.")
5140+
5141+
if isinstance(seconds, datetime.timedelta):
5142+
seconds = int(seconds.total_seconds())
5143+
5144+
options = []
5145+
if nx:
5146+
options.append("NX")
5147+
if xx:
5148+
options.append("XX")
5149+
if gt:
5150+
options.append("GT")
5151+
if lt:
5152+
options.append("LT")
5153+
5154+
return self.execute_command(
5155+
"HEXPIRE", name, seconds, *options, "FIELDS", len(fields), *fields
5156+
)
5157+
5158+
def hpexpire(
5159+
self,
5160+
name: KeyT,
5161+
milliseconds: ExpiryT,
5162+
*fields: str,
5163+
nx: bool = False,
5164+
xx: bool = False,
5165+
gt: bool = False,
5166+
lt: bool = False,
5167+
) -> ResponseT:
5168+
"""
5169+
Sets or updates the expiration time for fields within a hash key, using relative
5170+
time in milliseconds.
5171+
5172+
If a field already has an expiration time, the behavior of the update can be
5173+
controlled using the `nx`, `xx`, `gt`, and `lt` parameters.
5174+
5175+
The return value provides detailed information about the outcome for each field.
5176+
5177+
For more information, see https://redis.io/commands/hpexpire
5178+
5179+
Args:
5180+
name: The name of the hash key.
5181+
milliseconds: Expiration time in milliseconds, relative. Can be an integer,
5182+
or a Python `timedelta` object.
5183+
fields: List of fields within the hash to apply the expiration time to.
5184+
nx: Set expiry only when the field has no expiry.
5185+
xx: Set expiry only when the field has an existing expiry.
5186+
gt: Set expiry only when the new expiry is greater than the current one.
5187+
lt: Set expiry only when the new expiry is less than the current one.
5188+
5189+
Returns:
5190+
If the key does not exist, returns an empty list. If the key exists, returns
5191+
a list which contains for each field in the request:
5192+
- `-2` if the field does not exist.
5193+
- `0` if the specified NX | XX | GT | LT condition was not met.
5194+
- `1` if the expiration time was set or updated.
5195+
- `2` if the field was deleted because the specified expiration time is
5196+
in the past.
5197+
"""
5198+
conditions = [nx, xx, gt, lt]
5199+
if sum(conditions) > 1:
5200+
raise ValueError("Only one of 'nx', 'xx', 'gt', 'lt' can be specified.")
5201+
5202+
if isinstance(milliseconds, datetime.timedelta):
5203+
milliseconds = int(milliseconds.total_seconds() * 1000)
5204+
5205+
options = []
5206+
if nx:
5207+
options.append("NX")
5208+
if xx:
5209+
options.append("XX")
5210+
if gt:
5211+
options.append("GT")
5212+
if lt:
5213+
options.append("LT")
5214+
5215+
return self.execute_command(
5216+
"HPEXPIRE", name, milliseconds, *options, "FIELDS", len(fields), *fields
5217+
)
5218+
5219+
def hexpireat(
5220+
self,
5221+
name: KeyT,
5222+
unix_time_seconds: AbsExpiryT,
5223+
*fields: str,
5224+
nx: bool = False,
5225+
xx: bool = False,
5226+
gt: bool = False,
5227+
lt: bool = False,
5228+
) -> ResponseT:
5229+
"""
5230+
Sets or updates the expiration time for fields within a hash key, using an
5231+
absolute Unix timestamp in seconds.
5232+
5233+
If a field already has an expiration time, the behavior of the update can be
5234+
controlled using the `nx`, `xx`, `gt`, and `lt` parameters.
5235+
5236+
The return value provides detailed information about the outcome for each field.
5237+
5238+
For more information, see https://redis.io/commands/hexpireat
5239+
5240+
Args:
5241+
name: The name of the hash key.
5242+
unix_time_seconds: Expiration time as Unix timestamp in seconds. Can be an
5243+
integer or a Python `datetime` object.
5244+
fields: List of fields within the hash to apply the expiration time to.
5245+
nx: Set expiry only when the field has no expiry.
5246+
xx: Set expiry only when the field has an existing expiration time.
5247+
gt: Set expiry only when the new expiry is greater than the current one.
5248+
lt: Set expiry only when the new expiry is less than the current one.
5249+
5250+
Returns:
5251+
If the key does not exist, returns an empty list. If the key exists, returns
5252+
a list which contains for each field in the request:
5253+
- `-2` if the field does not exist.
5254+
- `0` if the specified NX | XX | GT | LT condition was not met.
5255+
- `1` if the expiration time was set or updated.
5256+
- `2` if the field was deleted because the specified expiration time is
5257+
in the past.
5258+
"""
5259+
conditions = [nx, xx, gt, lt]
5260+
if sum(conditions) > 1:
5261+
raise ValueError("Only one of 'nx', 'xx', 'gt', 'lt' can be specified.")
5262+
5263+
if isinstance(unix_time_seconds, datetime.datetime):
5264+
unix_time_seconds = int(unix_time_seconds.timestamp())
5265+
5266+
options = []
5267+
if nx:
5268+
options.append("NX")
5269+
if xx:
5270+
options.append("XX")
5271+
if gt:
5272+
options.append("GT")
5273+
if lt:
5274+
options.append("LT")
5275+
5276+
return self.execute_command(
5277+
"HEXPIREAT",
5278+
name,
5279+
unix_time_seconds,
5280+
*options,
5281+
"FIELDS",
5282+
len(fields),
5283+
*fields,
5284+
)
5285+
5286+
def hpexpireat(
5287+
self,
5288+
name: KeyT,
5289+
unix_time_milliseconds: AbsExpiryT,
5290+
*fields: str,
5291+
nx: bool = False,
5292+
xx: bool = False,
5293+
gt: bool = False,
5294+
lt: bool = False,
5295+
) -> ResponseT:
5296+
"""
5297+
Sets or updates the expiration time for fields within a hash key, using an
5298+
absolute Unix timestamp in milliseconds.
5299+
5300+
If a field already has an expiration time, the behavior of the update can be
5301+
controlled using the `nx`, `xx`, `gt`, and `lt` parameters.
5302+
5303+
The return value provides detailed information about the outcome for each field.
5304+
5305+
For more information, see https://redis.io/commands/hpexpireat
5306+
5307+
Args:
5308+
name: The name of the hash key.
5309+
unix_time_milliseconds: Expiration time as Unix timestamp in milliseconds.
5310+
Can be an integer or a Python `datetime` object.
5311+
fields: List of fields within the hash to apply the expiry.
5312+
nx: Set expiry only when the field has no expiry.
5313+
xx: Set expiry only when the field has an existing expiry.
5314+
gt: Set expiry only when the new expiry is greater than the current one.
5315+
lt: Set expiry only when the new expiry is less than the current one.
5316+
5317+
Returns:
5318+
If the key does not exist, returns an empty list. If the key exists, returns
5319+
a list which contains for each field in the request:
5320+
- `-2` if the field does not exist.
5321+
- `0` if the specified NX | XX | GT | LT condition was not met.
5322+
- `1` if the expiration time was set or updated.
5323+
- `2` if the field was deleted because the specified expiration time is
5324+
in the past.
5325+
"""
5326+
conditions = [nx, xx, gt, lt]
5327+
if sum(conditions) > 1:
5328+
raise ValueError("Only one of 'nx', 'xx', 'gt', 'lt' can be specified.")
5329+
5330+
if isinstance(unix_time_milliseconds, datetime.datetime):
5331+
unix_time_milliseconds = int(unix_time_milliseconds.timestamp() * 1000)
5332+
5333+
options = []
5334+
if nx:
5335+
options.append("NX")
5336+
if xx:
5337+
options.append("XX")
5338+
if gt:
5339+
options.append("GT")
5340+
if lt:
5341+
options.append("LT")
5342+
5343+
return self.execute_command(
5344+
"HPEXPIREAT",
5345+
name,
5346+
unix_time_milliseconds,
5347+
*options,
5348+
"FIELDS",
5349+
len(fields),
5350+
*fields,
5351+
)
5352+
5353+
def hpersist(self, name: KeyT, *fields: str) -> ResponseT:
5354+
"""
5355+
Removes the expiration time for each specified field in a hash.
5356+
5357+
For more information, see https://redis.io/commands/hpersist
5358+
5359+
Args:
5360+
name: The name of the hash key.
5361+
fields: A list of fields within the hash from which to remove the
5362+
expiration time.
5363+
5364+
Returns:
5365+
If the key does not exist, returns an empty list. If the key exists, returns
5366+
a list which contains for each field in the request:
5367+
- `-2` if the field does not exist.
5368+
- `-1` if the field exists but has no associated expiration time.
5369+
- `1` if the expiration time was successfully removed from the field.
5370+
"""
5371+
return self.execute_command("HPERSIST", name, "FIELDS", len(fields), *fields)
5372+
5373+
def hexpiretime(self, key: KeyT, *fields: str) -> ResponseT:
5374+
"""
5375+
Returns the expiration times of hash fields as Unix timestamps in seconds.
5376+
5377+
For more information, see https://redis.io/commands/hexpiretime
5378+
5379+
Args:
5380+
key: The hash key.
5381+
fields: A list of fields within the hash for which to get the expiration
5382+
time.
5383+
5384+
Returns:
5385+
If the key does not exist, returns an empty list. If the key exists, returns
5386+
a list which contains for each field in the request:
5387+
- `-2` if the field does not exist.
5388+
- `-1` if the field exists but has no associated expire time.
5389+
- A positive integer representing the expiration Unix timestamp in
5390+
seconds, if the field has an associated expiration time.
5391+
"""
5392+
return self.execute_command(
5393+
"HEXPIRETIME", key, "FIELDS", len(fields), *fields, keys=[key]
5394+
)
5395+
5396+
def hpexpiretime(self, key: KeyT, *fields: str) -> ResponseT:
5397+
"""
5398+
Returns the expiration times of hash fields as Unix timestamps in milliseconds.
5399+
5400+
For more information, see https://redis.io/commands/hpexpiretime
5401+
5402+
Args:
5403+
key: The hash key.
5404+
fields: A list of fields within the hash for which to get the expiration
5405+
time.
5406+
5407+
Returns:
5408+
If the key does not exist, returns an empty list. If the key exists, returns
5409+
a list which contains for each field in the request:
5410+
- `-2` if the field does not exist.
5411+
- `-1` if the field exists but has no associated expire time.
5412+
- A positive integer representing the expiration Unix timestamp in
5413+
milliseconds, if the field has an associated expiration time.
5414+
"""
5415+
return self.execute_command(
5416+
"HPEXPIRETIME", key, "FIELDS", len(fields), *fields, keys=[key]
5417+
)
5418+
5419+
def httl(self, key: KeyT, *fields: str) -> ResponseT:
5420+
"""
5421+
Returns the TTL (Time To Live) in seconds for each specified field within a hash
5422+
key.
5423+
5424+
For more information, see https://redis.io/commands/httl
5425+
5426+
Args:
5427+
key: The hash key.
5428+
fields: A list of fields within the hash for which to get the TTL.
5429+
5430+
Returns:
5431+
If the key does not exist, returns an empty list. If the key exists, returns
5432+
a list which contains for each field in the request:
5433+
- `-2` if the field does not exist.
5434+
- `-1` if the field exists but has no associated expire time.
5435+
- A positive integer representing the TTL in seconds if the field has
5436+
an associated expiration time.
5437+
"""
5438+
return self.execute_command(
5439+
"HTTL", key, "FIELDS", len(fields), *fields, keys=[key]
5440+
)
5441+
5442+
def hpttl(self, key: KeyT, *fields: str) -> ResponseT:
5443+
"""
5444+
Returns the TTL (Time To Live) in milliseconds for each specified field within a
5445+
hash key.
5446+
5447+
For more information, see https://redis.io/commands/hpttl
5448+
5449+
Args:
5450+
key: The hash key.
5451+
fields: A list of fields within the hash for which to get the TTL.
5452+
5453+
Returns:
5454+
If the key does not exist, returns an empty list. If the key exists, returns
5455+
a list which contains for each field in the request:
5456+
- `-2` if the field does not exist.
5457+
- `-1` if the field exists but has no associated expire time.
5458+
- A positive integer representing the TTL in milliseconds if the field
5459+
has an associated expiration time.
5460+
"""
5461+
return self.execute_command(
5462+
"HPTTL", key, "FIELDS", len(fields), *fields, keys=[key]
5463+
)
5464+
50975465

50985466
AsyncHashCommands = HashCommands
50995467

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
long_description_content_type="text/markdown",
99
keywords=["Redis", "key-value store", "database"],
1010
license="MIT",
11-
version="5.1.0b5",
11+
version="5.1.0b6",
1212
packages=find_packages(
1313
include=[
1414
"redis",

tests/test_asyncio/test_cluster.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,7 @@ async def test_memory_stats(self, r: RedisCluster) -> None:
14531453
assert isinstance(stats, dict)
14541454
for key, value in stats.items():
14551455
if key.startswith("db."):
1456-
assert isinstance(value, dict)
1456+
assert not isinstance(value, list)
14571457

14581458
@skip_if_server_version_lt("4.0.0")
14591459
async def test_memory_help(self, r: RedisCluster) -> None:

0 commit comments

Comments
 (0)