Skip to content

Commit 28964c1

Browse files
vladvildanovzs-neozhousheng06hauntsaninjadwdougherty
authored
Backport from master (5.3.0b5) (#3506)
* Fixed flacky TokenManager test (#3468) * Fixed flacky TokenManager test * Fixed additional flacky test * Removed token count assertion * Skipped test on version 3.9 * Fix incorrect attribute reuse (#3456) add CacheEntry Co-authored-by: zhousheng06 <zhousheng06@meituan.com> Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * Expand type for EncodedT (#3472) As of PEP 688, type checkers will no longer implicitly consider bytearray to be compatible with bytes * Moved self._lock initialisation to Pool constructor (#3473) * Moved self._lock initialisation to Pool constructor * Added test case * Codestyle fixes * Added correct annotations * DOC-4423: add TCEs for various command pages (#3476) Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * DOC-4345 added testable JSON search examples for home page (#3407) * DOC-4345 added testable JSON search examples for home page * DOC-4345 avoid possible non-deterministic results in tests * DOC-4345 close connection at end of example * DOC-4345 remove unnecessary blank lines * Adding unit text fixes to improve compatibility with MacOS. (#3486) * Adding unit text fixes to improve compatibility with MacOS. * Applying review comments * Unifying the exception msg validation pattern for both test_connection.py files --------- Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * Add return type to `close` functions (#3496) * Add types to ConnectionPool.from_url (#3495) Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * Add types to execute method of pipelines (#3494) Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * DOC-4796 fixed capped lists example (#3493) Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * typing for client __init__ (#3357) * typing for client __init__ * typing with string literals * retry_on_error more specific typing * retry typing * fix lint --------- Co-authored-by: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> * test: Updated CredentialProvider test infrastructure (#3502) * test: Updated CredentialProvider test infrastructure * Added linter exclusion * Updated dev dependency * Codestyle fixes * Updated async test infra * Added missing constant * Updated package version * Updated testing versions and docs * Updated server versions * Fixed test --------- Co-authored-by: zs-neo <48560952+zs-neo@users.noreply.github.com> Co-authored-by: zhousheng06 <zhousheng06@meituan.com> Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Co-authored-by: David Dougherty <dwdougherty@gmail.com> Co-authored-by: andy-stark-redis <164213578+andy-stark-redis@users.noreply.github.com> Co-authored-by: petyaslavova <petya.slavova@redis.com> Co-authored-by: Patrick Arminio <patrick.arminio@gmail.com> Co-authored-by: Artur Mostowski <artur.mostowski@protonmail.com>
1 parent 8056198 commit 28964c1

26 files changed

+670
-203
lines changed

.github/actions/run-tests/action.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ runs:
5656
5757
# Mapping of redis version to stack version
5858
declare -A redis_stack_version_mapping=(
59-
["7.4.1"]="7.4.0-v1"
60-
["7.2.6"]="7.2.0-v13"
61-
["6.2.16"]="6.2.6-v17"
59+
["7.4.2"]="7.4.0-v3"
60+
["7.2.7"]="7.2.0-v15"
61+
["6.2.17"]="6.2.6-v19"
6262
)
6363
6464
if [[ -v redis_stack_version_mapping[$REDIS_VERSION] ]]; then

.github/workflows/integration.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ env:
2929
COVERAGE_CORE: sysmon
3030
REDIS_IMAGE: redis:latest
3131
REDIS_STACK_IMAGE: redis/redis-stack-server:latest
32-
CURRENT_REDIS_VERSION: '7.4.1'
32+
CURRENT_REDIS_VERSION: '7.4.2'
3333

3434
jobs:
3535
dependency-audit:
@@ -74,7 +74,7 @@ jobs:
7474
max-parallel: 15
7575
fail-fast: false
7676
matrix:
77-
redis-version: [ '${{ needs.redis_version.outputs.CURRENT }}', '7.2.6', '6.2.16']
77+
redis-version: [ '${{ needs.redis_version.outputs.CURRENT }}', '7.2.7', '6.2.17']
7878
python-version: ['3.8', '3.12']
7979
parser-backend: ['plain']
8080
event-loop: ['asyncio']

dev_requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ uvloop
1616
vulture>=2.3.0
1717
wheel>=0.30.0
1818
numpy>=1.24.0
19-
redis-entraid==0.1.0b1
19+
redis-entraid==0.3.0b1

docker-compose.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ services:
103103
- all
104104

105105
redis-stack:
106-
image: ${REDIS_STACK_IMAGE:-redis/redis-stack-server:edge}
106+
image: ${REDIS_STACK_IMAGE:-redis/redis-stack-server:latest}
107107
container_name: redis-stack
108108
ports:
109109
- 6479:6379
@@ -112,6 +112,7 @@ services:
112112
profiles:
113113
- standalone
114114
- all-stack
115+
- all
115116

116117
redis-stack-graph:
117118
image: redis/redis-stack-server:6.2.6-v15

docs/advanced_features.rst

+7-8
Original file line numberDiff line numberDiff line change
@@ -471,31 +471,30 @@ command is received.
471471
Token-based authentication
472472
~~~~~~~~~~~~~~~~~~~~~~~~~~
473473

474-
Since redis-py version 5.3.0 new StreamableCredentialProvider interface was introduced.
475-
This interface describes a CredentialProvider with an ability to stream an events that will be handled by listener.
474+
Since redis-py version 5.3.0 new `StreamableCredentialProvider` interface was introduced.
475+
This interface describes a `CredentialProvider` with an ability to stream an events that will be handled by listener.
476476

477-
To keep redis-py with minimal dependencies needed to run it, we decided to separate StreamableCredentialProvider
477+
To keep redis-py with minimal dependencies needed to run it, we decided to separate `StreamableCredentialProvider`
478478
implementations in a separate packages. So If you're interested to try this feature please add them as a separate
479479
dependency to your project.
480480

481481
`EntraIdCredentialProvider` is a first implementation that allows you to integrate redis-py with Azure Cache for Redis
482-
service. It will allows you to obtain a tokens from Microsoft EntraID and authenticate/re-authenticate your connections
482+
service. It will allows you to obtain a tokens from `Microsoft EntraID` and authenticate/re-authenticate your connections
483483
with it in a background mode.
484484

485485
To get `EntraIdCredentialProvider` you need to install following package:
486486

487487
`pip install redis-entraid`
488488

489-
To setup a credential provider, first you have to create and configure an IdentityProvider and provide
490-
TokenAuthConfig object.
489+
To setup a credential provider, please use one of the factory methods bundled with package.
491490
`Here's a quick guide how to do this
492-
<https://github.com/redis-developer/redispy-entra-credentials?tab=readme-ov-file#usage>`_
491+
<https://github.com/redis/redis-py-entraid/blob/main/README.md>`_
493492

494493
Now all you have to do is to pass an instance of `EntraIdCredentialProvider` via constructor,
495494
available for sync and async clients:
496495

497496
.. code:: python
498497
499-
>>> cred_provider = EntraIdCredentialProvider(auth_config)
498+
>>> cred_provider = create_from_service_principal(CLIENT_ID, CLIENT_SECRET, TENANT_ID)
500499
>>> r = Redis(credential_provider=cred_provider)
501500
>>> r.ping()

doctests/cmds_cnxmgmt.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# EXAMPLE: cmds_cnxmgmt
2+
# HIDE_START
3+
import redis
4+
5+
r = redis.Redis(decode_responses=True)
6+
# HIDE_END
7+
8+
# STEP_START auth1
9+
# REMOVE_START
10+
r.config_set("requirepass", "temp_pass")
11+
# REMOVE_END
12+
res1 = r.auth(password="temp_pass")
13+
print(res1) # >>> True
14+
15+
res2 = r.auth(password="temp_pass", username="default")
16+
print(res2) # >>> True
17+
18+
# REMOVE_START
19+
assert res1 == True
20+
assert res2 == True
21+
r.config_set("requirepass", "")
22+
# REMOVE_END
23+
# STEP_END
24+
25+
# STEP_START auth2
26+
# REMOVE_START
27+
r.acl_setuser("test-user", enabled=True, passwords=["+strong_password"], commands=["+acl"])
28+
# REMOVE_END
29+
res = r.auth(username="test-user", password="strong_password")
30+
print(res) # >>> True
31+
32+
# REMOVE_START
33+
assert res == True
34+
r.acl_deluser("test-user")
35+
# REMOVE_END
36+
# STEP_END

doctests/cmds_hash.py

+24
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,27 @@
6161
r.delete("myhash")
6262
# REMOVE_END
6363
# STEP_END
64+
65+
# STEP_START hgetall
66+
res10 = r.hset("myhash", mapping={"field1": "Hello", "field2": "World"})
67+
68+
res11 = r.hgetall("myhash")
69+
print(res11) # >>> { "field1": "Hello", "field2": "World" }
70+
71+
# REMOVE_START
72+
assert res11 == { "field1": "Hello", "field2": "World" }
73+
r.delete("myhash")
74+
# REMOVE_END
75+
# STEP_END
76+
77+
# STEP_START hvals
78+
res10 = r.hset("myhash", mapping={"field1": "Hello", "field2": "World"})
79+
80+
res11 = r.hvals("myhash")
81+
print(res11) # >>> [ "Hello", "World" ]
82+
83+
# REMOVE_START
84+
assert res11 == [ "Hello", "World" ]
85+
r.delete("myhash")
86+
# REMOVE_END
87+
# STEP_END

doctests/cmds_list.py

+123
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# EXAMPLE: cmds_list
2+
# HIDE_START
3+
import redis
4+
5+
r = redis.Redis(decode_responses=True)
6+
# HIDE_END
7+
8+
# STEP_START lpush
9+
res1 = r.lpush("mylist", "world")
10+
print(res1) # >>> 1
11+
12+
res2 = r.lpush("mylist", "hello")
13+
print(res2) # >>> 2
14+
15+
res3 = r.lrange("mylist", 0, -1)
16+
print(res3) # >>> [ "hello", "world" ]
17+
18+
# REMOVE_START
19+
assert res3 == [ "hello", "world" ]
20+
r.delete("mylist")
21+
# REMOVE_END
22+
# STEP_END
23+
24+
# STEP_START lrange
25+
res4 = r.rpush("mylist", "one");
26+
print(res4) # >>> 1
27+
28+
res5 = r.rpush("mylist", "two")
29+
print(res5) # >>> 2
30+
31+
res6 = r.rpush("mylist", "three")
32+
print(res6) # >>> 3
33+
34+
res7 = r.lrange('mylist', 0, 0)
35+
print(res7) # >>> [ 'one' ]
36+
37+
res8 = r.lrange('mylist', -3, 2)
38+
print(res8) # >>> [ 'one', 'two', 'three' ]
39+
40+
res9 = r.lrange('mylist', -100, 100)
41+
print(res9) # >>> [ 'one', 'two', 'three' ]
42+
43+
res10 = r.lrange('mylist', 5, 10)
44+
print(res10) # >>> []
45+
46+
# REMOVE_START
47+
assert res7 == [ 'one' ]
48+
assert res8 == [ 'one', 'two', 'three' ]
49+
assert res9 == [ 'one', 'two', 'three' ]
50+
assert res10 == []
51+
r.delete('mylist')
52+
# REMOVE_END
53+
# STEP_END
54+
55+
# STEP_START llen
56+
res11 = r.lpush("mylist", "World")
57+
print(res11) # >>> 1
58+
59+
res12 = r.lpush("mylist", "Hello")
60+
print(res12) # >>> 2
61+
62+
res13 = r.llen("mylist")
63+
print(res13) # >>> 2
64+
65+
# REMOVE_START
66+
assert res13 == 2
67+
r.delete("mylist")
68+
# REMOVE_END
69+
# STEP_END
70+
71+
# STEP_START rpush
72+
res14 = r.rpush("mylist", "hello")
73+
print(res14) # >>> 1
74+
75+
res15 = r.rpush("mylist", "world")
76+
print(res15) # >>> 2
77+
78+
res16 = r.lrange("mylist", 0, -1)
79+
print(res16) # >>> [ "hello", "world" ]
80+
81+
# REMOVE_START
82+
assert res16 == [ "hello", "world" ]
83+
r.delete("mylist")
84+
# REMOVE_END
85+
# STEP_END
86+
87+
# STEP_START lpop
88+
res17 = r.rpush("mylist", *["one", "two", "three", "four", "five"])
89+
print(res17) # >>> 5
90+
91+
res18 = r.lpop("mylist")
92+
print(res18) # >>> "one"
93+
94+
res19 = r.lpop("mylist", 2)
95+
print(res19) # >>> ['two', 'three']
96+
97+
res17 = r.lrange("mylist", 0, -1)
98+
print(res17) # >>> [ "four", "five" ]
99+
100+
# REMOVE_START
101+
assert res17 == [ "four", "five" ]
102+
r.delete("mylist")
103+
# REMOVE_END
104+
# STEP_END
105+
106+
# STEP_START rpop
107+
res18 = r.rpush("mylist", *["one", "two", "three", "four", "five"])
108+
print(res18) # >>> 5
109+
110+
res19 = r.rpop("mylist")
111+
print(res19) # >>> "five"
112+
113+
res20 = r.rpop("mylist", 2)
114+
print(res20) # >>> ['four', 'three']
115+
116+
res21 = r.lrange("mylist", 0, -1)
117+
print(res21) # >>> [ "one", "two" ]
118+
119+
# REMOVE_START
120+
assert res21 == [ "one", "two" ]
121+
r.delete("mylist")
122+
# REMOVE_END
123+
# STEP_END

doctests/cmds_servermgmt.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# EXAMPLE: cmds_servermgmt
2+
# HIDE_START
3+
import redis
4+
5+
r = redis.Redis(decode_responses=True)
6+
# HIDE_END
7+
8+
# STEP_START flushall
9+
# REMOVE_START
10+
r.set("foo", "1")
11+
r.set("bar", "2")
12+
r.set("baz", "3")
13+
# REMOVE_END
14+
res1 = r.flushall(asynchronous=False)
15+
print(res1) # >>> True
16+
17+
res2 = r.keys()
18+
print(res2) # >>> []
19+
20+
# REMOVE_START
21+
assert res1 == True
22+
assert res2 == []
23+
# REMOVE_END
24+
# STEP_END
25+
26+
# STEP_START info
27+
res3 = r.info()
28+
print(res3)
29+
# >>> {'redis_version': '7.4.0', 'redis_git_sha1': 'c9d29f6a',...}
30+
# STEP_END

doctests/cmds_set.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# EXAMPLE: cmds_set
2+
# HIDE_START
3+
import redis
4+
5+
r = redis.Redis(decode_responses=True)
6+
# HIDE_END
7+
8+
# STEP_START sadd
9+
res1 = r.sadd("myset", "Hello", "World")
10+
print(res1) # >>> 2
11+
12+
res2 = r.sadd("myset", "World")
13+
print(res2) # >>> 0
14+
15+
res3 = r.smembers("myset")
16+
print(res3) # >>> {'Hello', 'World'}
17+
18+
# REMOVE_START
19+
assert res3 == {'Hello', 'World'}
20+
r.delete('myset')
21+
# REMOVE_END
22+
# STEP_END
23+
24+
# STEP_START smembers
25+
res4 = r.sadd("myset", "Hello", "World")
26+
print(res4) # >>> 2
27+
28+
res5 = r.smembers("myset")
29+
print(res5) # >>> {'Hello', 'World'}
30+
31+
# REMOVE_START
32+
assert res5 == {'Hello', 'World'}
33+
r.delete('myset')
34+
# REMOVE_END
35+
# STEP_END

doctests/dt_list.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,20 +165,20 @@
165165
# REMOVE_END
166166

167167
# STEP_START ltrim
168-
res27 = r.lpush("bikes:repairs", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5")
168+
res27 = r.rpush("bikes:repairs", "bike:1", "bike:2", "bike:3", "bike:4", "bike:5")
169169
print(res27) # >>> 5
170170

171171
res28 = r.ltrim("bikes:repairs", 0, 2)
172172
print(res28) # >>> True
173173

174174
res29 = r.lrange("bikes:repairs", 0, -1)
175-
print(res29) # >>> ['bike:5', 'bike:4', 'bike:3']
175+
print(res29) # >>> ['bike:1', 'bike:2', 'bike:3']
176176
# STEP_END
177177

178178
# REMOVE_START
179179
assert res27 == 5
180180
assert res28 is True
181-
assert res29 == ["bike:5", "bike:4", "bike:3"]
181+
assert res29 == ["bike:1", "bike:2", "bike:3"]
182182
r.delete("bikes:repairs")
183183
# REMOVE_END
184184

0 commit comments

Comments
 (0)