Skip to content

Commit 11f5a65

Browse files
gerzseagnesnatasya
authored andcommitted
Prepare for Redis 7.4 RC2 (redis#3303)
Adapt the code and some of the tests to match the changes done in the Redis 7.4 RC2 release.
1 parent 1fa726c commit 11f5a65

File tree

7 files changed

+52
-60
lines changed

7 files changed

+52
-60
lines changed

.github/workflows/integration.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ permissions:
2525

2626
env:
2727
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
28-
REDIS_IMAGE: redis/redis-stack-server:7.4.0-rc1
29-
REDIS_STACK_IMAGE: redis/redis-stack-server:7.4.0-rc1
28+
REDIS_IMAGE: redis:7.4-rc2
29+
REDIS_STACK_IMAGE: redis/redis-stack-server:7.4.0-rc2
3030

3131
jobs:
3232
dependency-audit:

redis/commands/core.py

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5157,9 +5157,8 @@ def hexpire(
51575157
lt: Set expiry only when the new expiry is less than the current one.
51585158
51595159
Returns:
5160-
If the key does not exist, returns an empty list. If the key exists, returns
5161-
a list which contains for each field in the request:
5162-
- `-2` if the field does not exist.
5160+
Returns a list which contains for each field in the request:
5161+
- `-2` if the field does not exist, or if the key does not exist.
51635162
- `0` if the specified NX | XX | GT | LT condition was not met.
51645163
- `1` if the expiration time was set or updated.
51655164
- `2` if the field was deleted because the specified expiration time is
@@ -5218,9 +5217,8 @@ def hpexpire(
52185217
lt: Set expiry only when the new expiry is less than the current one.
52195218
52205219
Returns:
5221-
If the key does not exist, returns an empty list. If the key exists, returns
5222-
a list which contains for each field in the request:
5223-
- `-2` if the field does not exist.
5220+
Returns a list which contains for each field in the request:
5221+
- `-2` if the field does not exist, or if the key does not exist.
52245222
- `0` if the specified NX | XX | GT | LT condition was not met.
52255223
- `1` if the expiration time was set or updated.
52265224
- `2` if the field was deleted because the specified expiration time is
@@ -5279,9 +5277,8 @@ def hexpireat(
52795277
lt: Set expiry only when the new expiry is less than the current one.
52805278
52815279
Returns:
5282-
If the key does not exist, returns an empty list. If the key exists, returns
5283-
a list which contains for each field in the request:
5284-
- `-2` if the field does not exist.
5280+
Returns a list which contains for each field in the request:
5281+
- `-2` if the field does not exist, or if the key does not exist.
52855282
- `0` if the specified NX | XX | GT | LT condition was not met.
52865283
- `1` if the expiration time was set or updated.
52875284
- `2` if the field was deleted because the specified expiration time is
@@ -5346,9 +5343,8 @@ def hpexpireat(
53465343
lt: Set expiry only when the new expiry is less than the current one.
53475344
53485345
Returns:
5349-
If the key does not exist, returns an empty list. If the key exists, returns
5350-
a list which contains for each field in the request:
5351-
- `-2` if the field does not exist.
5346+
Returns a list which contains for each field in the request:
5347+
- `-2` if the field does not exist, or if the key does not exist.
53525348
- `0` if the specified NX | XX | GT | LT condition was not met.
53535349
- `1` if the expiration time was set or updated.
53545350
- `2` if the field was deleted because the specified expiration time is
@@ -5393,9 +5389,8 @@ def hpersist(self, name: KeyT, *fields: str) -> ResponseT:
53935389
expiration time.
53945390
53955391
Returns:
5396-
If the key does not exist, returns an empty list. If the key exists, returns
5397-
a list which contains for each field in the request:
5398-
- `-2` if the field does not exist.
5392+
Returns a list which contains for each field in the request:
5393+
- `-2` if the field does not exist, or if the key does not exist.
53995394
- `-1` if the field exists but has no associated expiration time.
54005395
- `1` if the expiration time was successfully removed from the field.
54015396
"""
@@ -5413,9 +5408,8 @@ def hexpiretime(self, key: KeyT, *fields: str) -> ResponseT:
54135408
time.
54145409
54155410
Returns:
5416-
If the key does not exist, returns an empty list. If the key exists, returns
5417-
a list which contains for each field in the request:
5418-
- `-2` if the field does not exist.
5411+
Returns a list which contains for each field in the request:
5412+
- `-2` if the field does not exist, or if the key does not exist.
54195413
- `-1` if the field exists but has no associated expire time.
54205414
- A positive integer representing the expiration Unix timestamp in
54215415
seconds, if the field has an associated expiration time.
@@ -5436,9 +5430,8 @@ def hpexpiretime(self, key: KeyT, *fields: str) -> ResponseT:
54365430
time.
54375431
54385432
Returns:
5439-
If the key does not exist, returns an empty list. If the key exists, returns
5440-
a list which contains for each field in the request:
5441-
- `-2` if the field does not exist.
5433+
Returns a list which contains for each field in the request:
5434+
- `-2` if the field does not exist, or if the key does not exist.
54425435
- `-1` if the field exists but has no associated expire time.
54435436
- A positive integer representing the expiration Unix timestamp in
54445437
milliseconds, if the field has an associated expiration time.
@@ -5459,9 +5452,8 @@ def httl(self, key: KeyT, *fields: str) -> ResponseT:
54595452
fields: A list of fields within the hash for which to get the TTL.
54605453
54615454
Returns:
5462-
If the key does not exist, returns an empty list. If the key exists, returns
5463-
a list which contains for each field in the request:
5464-
- `-2` if the field does not exist.
5455+
Returns a list which contains for each field in the request:
5456+
- `-2` if the field does not exist, or if the key does not exist.
54655457
- `-1` if the field exists but has no associated expire time.
54665458
- A positive integer representing the TTL in seconds if the field has
54675459
an associated expiration time.
@@ -5482,9 +5474,8 @@ def hpttl(self, key: KeyT, *fields: str) -> ResponseT:
54825474
fields: A list of fields within the hash for which to get the TTL.
54835475
54845476
Returns:
5485-
If the key does not exist, returns an empty list. If the key exists, returns
5486-
a list which contains for each field in the request:
5487-
- `-2` if the field does not exist.
5477+
Returns a list which contains for each field in the request:
5478+
- `-2` if the field does not exist, or if the key does not exist.
54885479
- `-1` if the field exists but has no associated expire time.
54895480
- A positive integer representing the TTL in milliseconds if the field
54905481
has an associated expiration time.

tests/test_asyncio/test_hash.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async def test_hexpire_conditions(r):
4545
@skip_if_server_version_lt("7.3.240")
4646
async def test_hexpire_nonexistent_key_or_field(r):
4747
await r.delete("test:hash")
48-
assert await r.hexpire("test:hash", 1, "field1") == []
48+
assert await r.hexpire("test:hash", 1, "field1") == [-2]
4949
await r.hset("test:hash", "field1", "value1")
5050
assert await r.hexpire("test:hash", 1, "nonexistent_field") == [-2]
5151

@@ -105,7 +105,7 @@ async def test_hpexpire_conditions(r):
105105
@skip_if_server_version_lt("7.3.240")
106106
async def test_hpexpire_nonexistent_key_or_field(r):
107107
await r.delete("test:hash")
108-
assert await r.hpexpire("test:hash", 500, "field1") == []
108+
assert await r.hpexpire("test:hash", 500, "field1") == [-2]
109109
await r.hset("test:hash", "field1", "value1")
110110
assert await r.hpexpire("test:hash", 500, "nonexistent_field") == [-2]
111111

@@ -163,7 +163,7 @@ async def test_hexpireat_conditions(r):
163163
async def test_hexpireat_nonexistent_key_or_field(r):
164164
await r.delete("test:hash")
165165
future_exp_time = int((datetime.now() + timedelta(seconds=1)).timestamp())
166-
assert await r.hexpireat("test:hash", future_exp_time, "field1") == []
166+
assert await r.hexpireat("test:hash", future_exp_time, "field1") == [-2]
167167
await r.hset("test:hash", "field1", "value1")
168168
assert await r.hexpireat("test:hash", future_exp_time, "nonexistent_field") == [-2]
169169

@@ -228,7 +228,7 @@ async def test_hpexpireat_nonexistent_key_or_field(r):
228228
future_exp_time = int(
229229
(datetime.now() + timedelta(milliseconds=500)).timestamp() * 1000
230230
)
231-
assert await r.hpexpireat("test:hash", future_exp_time, "field1") == []
231+
assert await r.hpexpireat("test:hash", future_exp_time, "field1") == [-2]
232232
await r.hset("test:hash", "field1", "value1")
233233
assert await r.hpexpireat("test:hash", future_exp_time, "nonexistent_field") == [-2]
234234

tests/test_asyncio/test_json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ async def test_mset(decoded_r: redis.Redis):
131131
async def test_clear(decoded_r: redis.Redis):
132132
await decoded_r.json().set("arr", Path.root_path(), [0, 1, 2, 3, 4])
133133
assert 1 == await decoded_r.json().clear("arr", Path.root_path())
134-
assert_resp_response(decoded_r, await decoded_r.json().get("arr"), [], [[[]]])
134+
assert_resp_response(decoded_r, await decoded_r.json().get("arr"), [], [])
135135

136136

137137
@pytest.mark.redismod

tests/test_hash.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def test_hexpire_conditions(r):
4646
@skip_if_server_version_lt("7.3.240")
4747
def test_hexpire_nonexistent_key_or_field(r):
4848
r.delete("test:hash")
49-
assert r.hexpire("test:hash", 1, "field1") == []
49+
assert r.hexpire("test:hash", 1, "field1") == [-2]
5050
r.hset("test:hash", "field1", "value1")
5151
assert r.hexpire("test:hash", 1, "nonexistent_field") == [-2]
5252

@@ -115,7 +115,7 @@ def test_hpexpire_conditions(r):
115115
@skip_if_server_version_lt("7.3.240")
116116
def test_hpexpire_nonexistent_key_or_field(r):
117117
r.delete("test:hash")
118-
assert r.hpexpire("test:hash", 500, "field1") == []
118+
assert r.hpexpire("test:hash", 500, "field1") == [-2]
119119
r.hset("test:hash", "field1", "value1")
120120
assert r.hpexpire("test:hash", 500, "nonexistent_field") == [-2]
121121

@@ -182,7 +182,7 @@ def test_hexpireat_conditions(r):
182182
def test_hexpireat_nonexistent_key_or_field(r):
183183
r.delete("test:hash")
184184
future_exp_time = int((datetime.now() + timedelta(seconds=1)).timestamp())
185-
assert r.hexpireat("test:hash", future_exp_time, "field1") == []
185+
assert r.hexpireat("test:hash", future_exp_time, "field1") == [-2]
186186
r.hset("test:hash", "field1", "value1")
187187
assert r.hexpireat("test:hash", future_exp_time, "nonexistent_field") == [-2]
188188

@@ -257,7 +257,7 @@ def test_hpexpireat_nonexistent_key_or_field(r):
257257
future_exp_time = int(
258258
(datetime.now() + timedelta(milliseconds=500)).timestamp() * 1000
259259
)
260-
assert r.hpexpireat("test:hash", future_exp_time, "field1") == []
260+
assert r.hpexpireat("test:hash", future_exp_time, "field1") == [-2]
261261
r.hset("test:hash", "field1", "value1")
262262
assert r.hpexpireat("test:hash", future_exp_time, "nonexistent_field") == [-2]
263263

@@ -298,7 +298,7 @@ def test_hpersist_multiple_fields(r):
298298
@skip_if_server_version_lt("7.3.240")
299299
def test_hpersist_nonexistent_key(r):
300300
r.delete("test:hash")
301-
assert r.hpersist("test:hash", "field1", "field2", "field3") == []
301+
assert r.hpersist("test:hash", "field1", "field2", "field3") == [-2, -2, -2]
302302

303303

304304
@skip_if_server_version_lt("7.3.240")
@@ -315,7 +315,7 @@ def test_hexpiretime_multiple_fields_mixed_conditions(r):
315315
@skip_if_server_version_lt("7.3.240")
316316
def test_hexpiretime_nonexistent_key(r):
317317
r.delete("test:hash")
318-
assert r.hexpiretime("test:hash", "field1", "field2", "field3") == []
318+
assert r.hexpiretime("test:hash", "field1", "field2", "field3") == [-2, -2, -2]
319319

320320

321321
@skip_if_server_version_lt("7.3.240")
@@ -332,7 +332,7 @@ def test_hpexpiretime_multiple_fields_mixed_conditions(r):
332332
@skip_if_server_version_lt("7.3.240")
333333
def test_hpexpiretime_nonexistent_key(r):
334334
r.delete("test:hash")
335-
assert r.hpexpiretime("test:hash", "field1", "field2", "field3") == []
335+
assert r.hpexpiretime("test:hash", "field1", "field2", "field3") == [-2, -2, -2]
336336

337337

338338
@skip_if_server_version_lt("7.3.240")
@@ -349,7 +349,7 @@ def test_httl_multiple_fields_mixed_conditions(r):
349349
@skip_if_server_version_lt("7.3.240")
350350
def test_httl_nonexistent_key(r):
351351
r.delete("test:hash")
352-
assert r.httl("test:hash", "field1", "field2", "field3") == []
352+
assert r.httl("test:hash", "field1", "field2", "field3") == [-2, -2, -2]
353353

354354

355355
@skip_if_server_version_lt("7.3.240")
@@ -366,4 +366,4 @@ def test_hpttl_multiple_fields_mixed_conditions(r):
366366
@skip_if_server_version_lt("7.3.240")
367367
def test_hpttl_nonexistent_key(r):
368368
r.delete("test:hash")
369-
assert r.hpttl("test:hash", "field1", "field2", "field3") == []
369+
assert r.hpttl("test:hash", "field1", "field2", "field3") == [-2, -2, -2]

tests/test_json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def test_mset(client):
130130
def test_clear(client):
131131
client.json().set("arr", Path.root_path(), [0, 1, 2, 3, 4])
132132
assert 1 == client.json().clear("arr", Path.root_path())
133-
assert_resp_response(client, client.json().get("arr"), [], [[[]]])
133+
assert_resp_response(client, client.json().get("arr"), [], [])
134134

135135

136136
@pytest.mark.redismod

tests/test_search.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2369,27 +2369,27 @@ def test_search_missing_fields(client):
23692369

23702370
with pytest.raises(redis.exceptions.ResponseError) as e:
23712371
client.ft().search(
2372-
Query("ismissing(@title)").dialect(5).return_field("id").no_content()
2372+
Query("ismissing(@title)").dialect(2).return_field("id").no_content()
23732373
)
23742374
assert "to be defined with 'INDEXMISSING'" in e.value.args[0]
23752375

23762376
res = client.ft().search(
2377-
Query("ismissing(@features)").dialect(5).return_field("id").no_content()
2377+
Query("ismissing(@features)").dialect(2).return_field("id").no_content()
23782378
)
23792379
_assert_search_result(client, res, ["property:2"])
23802380

23812381
res = client.ft().search(
2382-
Query("-ismissing(@features)").dialect(5).return_field("id").no_content()
2382+
Query("-ismissing(@features)").dialect(2).return_field("id").no_content()
23832383
)
23842384
_assert_search_result(client, res, ["property:1", "property:3"])
23852385

23862386
res = client.ft().search(
2387-
Query("ismissing(@description)").dialect(5).return_field("id").no_content()
2387+
Query("ismissing(@description)").dialect(2).return_field("id").no_content()
23882388
)
23892389
_assert_search_result(client, res, ["property:3"])
23902390

23912391
res = client.ft().search(
2392-
Query("-ismissing(@description)").dialect(5).return_field("id").no_content()
2392+
Query("-ismissing(@description)").dialect(2).return_field("id").no_content()
23932393
)
23942394
_assert_search_result(client, res, ["property:1", "property:2"])
23952395

@@ -2438,27 +2438,29 @@ def test_search_empty_fields(client):
24382438

24392439
with pytest.raises(redis.exceptions.ResponseError) as e:
24402440
client.ft().search(
2441-
Query("@title:''").dialect(5).return_field("id").no_content()
2441+
Query("@title:''").dialect(2).return_field("id").no_content()
24422442
)
2443-
assert "to be defined with `INDEXEMPTY`" in e.value.args[0]
2443+
assert "Use `INDEXEMPTY` in field creation" in e.value.args[0]
24442444

24452445
res = client.ft().search(
2446-
Query("@features:{ }").dialect(5).return_field("id").no_content()
2446+
Query("@features:{$empty}").dialect(2).return_field("id").no_content(),
2447+
query_params={"empty": ""},
24472448
)
24482449
_assert_search_result(client, res, ["property:2"])
24492450

24502451
res = client.ft().search(
2451-
Query("-@features:{ }").dialect(5).return_field("id").no_content()
2452+
Query("-@features:{$empty}").dialect(2).return_field("id").no_content(),
2453+
query_params={"empty": ""},
24522454
)
24532455
_assert_search_result(client, res, ["property:1", "property:3"])
24542456

24552457
res = client.ft().search(
2456-
Query("@description:''").dialect(5).return_field("id").no_content()
2458+
Query("@description:''").dialect(2).return_field("id").no_content()
24572459
)
24582460
_assert_search_result(client, res, ["property:3"])
24592461

24602462
res = client.ft().search(
2461-
Query("-@description:''").dialect(5).return_field("id").no_content()
2463+
Query("-@description:''").dialect(2).return_field("id").no_content()
24622464
)
24632465
_assert_search_result(client, res, ["property:1", "property:2"])
24642466

@@ -2503,22 +2505,21 @@ def test_special_characters_in_fields(client):
25032505
)
25042506
_assert_search_result(client, res, ["resource:1"])
25052507

2506-
# with dialect 5 no need to escape the - even without params
2508+
# with double quotes exact match no need to escape the - even without params
25072509
res = client.ft().search(
2508-
Query("@uuid:{123e4567-e89b-12d3-a456-426614174000}").dialect(5)
2510+
Query('@uuid:{"123e4567-e89b-12d3-a456-426614174000"}').dialect(2)
25092511
)
25102512
_assert_search_result(client, res, ["resource:1"])
25112513

2512-
# also no need to escape ' with dialect 5
2513-
res = client.ft().search(Query("@tags:{new-year's-resolutions}").dialect(5))
2514+
res = client.ft().search(Query('@tags:{"new-year\'s-resolutions"}').dialect(2))
25142515
_assert_search_result(client, res, ["resource:2"])
25152516

25162517
# possible to search numeric fields by single value
25172518
res = client.ft().search(Query("@rating:[4]").dialect(2))
25182519
_assert_search_result(client, res, ["resource:2"])
25192520

25202521
# some chars still need escaping
2521-
res = client.ft().search(Query(r"@tags:{\$btc}").dialect(5))
2522+
res = client.ft().search(Query(r"@tags:{\$btc}").dialect(2))
25222523
_assert_search_result(client, res, ["resource:1"])
25232524

25242525

0 commit comments

Comments
 (0)