redis 5.3.0b5__tar.gz → 6.0.0b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. redis-6.0.0b2/.gitignore +28 -0
  2. {redis-5.3.0b5/redis.egg-info → redis-6.0.0b2}/PKG-INFO +57 -17
  3. {redis-5.3.0b5 → redis-6.0.0b2}/README.md +40 -5
  4. redis-6.0.0b2/dev_requirements.txt +16 -0
  5. redis-6.0.0b2/pyproject.toml +124 -0
  6. {redis-5.3.0b5 → redis-6.0.0b2}/redis/__init__.py +2 -11
  7. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/base.py +14 -2
  8. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/client.py +27 -14
  9. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/cluster.py +85 -59
  10. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/connection.py +76 -23
  11. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/lock.py +26 -5
  12. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/sentinel.py +11 -1
  13. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/utils.py +1 -1
  14. {redis-5.3.0b5 → redis-6.0.0b2}/redis/auth/token.py +6 -2
  15. {redis-5.3.0b5 → redis-6.0.0b2}/redis/backoff.py +15 -0
  16. {redis-5.3.0b5 → redis-6.0.0b2}/redis/client.py +23 -14
  17. {redis-5.3.0b5 → redis-6.0.0b2}/redis/cluster.py +112 -48
  18. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/cluster.py +1 -11
  19. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/core.py +219 -207
  20. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/helpers.py +0 -70
  21. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/redismodules.py +5 -17
  22. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/aggregation.py +3 -1
  23. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/commands.py +41 -14
  24. redis-6.0.0b2/redis/commands/search/dialect.py +3 -0
  25. redis-6.0.0b2/redis/commands/search/profile_information.py +14 -0
  26. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/query.py +5 -1
  27. redis-6.0.0b2/redis/commands/vectorset/__init__.py +46 -0
  28. redis-6.0.0b2/redis/commands/vectorset/commands.py +367 -0
  29. redis-6.0.0b2/redis/commands/vectorset/utils.py +94 -0
  30. {redis-5.3.0b5 → redis-6.0.0b2}/redis/connection.py +76 -27
  31. {redis-5.3.0b5 → redis-6.0.0b2}/redis/exceptions.py +4 -1
  32. {redis-5.3.0b5 → redis-6.0.0b2}/redis/lock.py +24 -4
  33. {redis-5.3.0b5 → redis-6.0.0b2}/redis/ocsp.py +2 -1
  34. {redis-5.3.0b5 → redis-6.0.0b2}/redis/sentinel.py +3 -1
  35. {redis-5.3.0b5 → redis-6.0.0b2}/redis/utils.py +114 -1
  36. {redis-5.3.0b5 → redis-6.0.0b2}/tests/conftest.py +10 -139
  37. redis-6.0.0b2/tests/entraid_utils.py +173 -0
  38. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/conftest.py +4 -160
  39. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_cluster.py +167 -15
  40. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_commands.py +218 -16
  41. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_connection.py +1 -1
  42. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_connection_pool.py +32 -32
  43. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_credentials.py +20 -4
  44. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_encoding.py +1 -1
  45. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_hash.py +276 -0
  46. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_lock.py +35 -4
  47. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_pipeline.py +16 -0
  48. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_retry.py +2 -2
  49. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_scripting.py +8 -8
  50. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_search.py +119 -15
  51. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_sentinel.py +1 -1
  52. redis-6.0.0b2/tests/test_asyncio/test_utils.py +8 -0
  53. redis-6.0.0b2/tests/test_asyncio/test_vsets.py +858 -0
  54. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_auth/test_token.py +2 -2
  55. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_auth/test_token_manager.py +9 -11
  56. redis-6.0.0b2/tests/test_backoff.py +18 -0
  57. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_cache.py +3 -3
  58. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_cluster.py +175 -62
  59. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_commands.py +241 -70
  60. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_connection.py +0 -1
  61. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_connection_pool.py +52 -37
  62. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_credentials.py +20 -4
  63. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_hash.py +247 -0
  64. redis-6.0.0b2/tests/test_helpers.py +42 -0
  65. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_lock.py +31 -4
  66. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_multiprocessing.py +54 -14
  67. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_pipeline.py +16 -0
  68. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_pubsub.py +2 -2
  69. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_retry.py +2 -2
  70. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_search.py +360 -76
  71. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_sentinel.py +1 -1
  72. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_utils.py +7 -0
  73. redis-6.0.0b2/tests/test_vsets.py +856 -0
  74. redis-5.3.0b5/INSTALL +0 -6
  75. redis-5.3.0b5/MANIFEST.in +0 -6
  76. redis-5.3.0b5/PKG-INFO +0 -208
  77. redis-5.3.0b5/redis/commands/graph/__init__.py +0 -263
  78. redis-5.3.0b5/redis/commands/graph/commands.py +0 -313
  79. redis-5.3.0b5/redis/commands/graph/edge.py +0 -91
  80. redis-5.3.0b5/redis/commands/graph/exceptions.py +0 -3
  81. redis-5.3.0b5/redis/commands/graph/execution_plan.py +0 -211
  82. redis-5.3.0b5/redis/commands/graph/node.py +0 -88
  83. redis-5.3.0b5/redis/commands/graph/path.py +0 -78
  84. redis-5.3.0b5/redis/commands/graph/query_result.py +0 -588
  85. redis-5.3.0b5/redis.egg-info/SOURCES.txt +0 -157
  86. redis-5.3.0b5/redis.egg-info/dependency_links.txt +0 -1
  87. redis-5.3.0b5/redis.egg-info/requires.txt +0 -12
  88. redis-5.3.0b5/redis.egg-info/top_level.txt +0 -1
  89. redis-5.3.0b5/setup.cfg +0 -4
  90. redis-5.3.0b5/setup.py +0 -64
  91. redis-5.3.0b5/tests/test_asyncio/test_graph.py +0 -527
  92. redis-5.3.0b5/tests/test_graph.py +0 -657
  93. redis-5.3.0b5/tests/test_graph_utils/test_edge.py +0 -75
  94. redis-5.3.0b5/tests/test_graph_utils/test_node.py +0 -51
  95. redis-5.3.0b5/tests/test_graph_utils/test_path.py +0 -90
  96. redis-5.3.0b5/tests/test_helpers.py +0 -90
  97. {redis-5.3.0b5 → redis-6.0.0b2}/LICENSE +0 -0
  98. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/__init__.py +0 -0
  99. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/commands.py +0 -0
  100. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/encoders.py +0 -0
  101. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/helpers.py +0 -0
  102. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/hiredis.py +0 -0
  103. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/resp2.py +0 -0
  104. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/resp3.py +0 -0
  105. {redis-5.3.0b5 → redis-6.0.0b2}/redis/_parsers/socket.py +0 -0
  106. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/__init__.py +0 -0
  107. {redis-5.3.0b5 → redis-6.0.0b2}/redis/asyncio/retry.py +0 -0
  108. {redis-5.3.0b5 → redis-6.0.0b2}/redis/auth/__init__.py +0 -0
  109. {redis-5.3.0b5 → redis-6.0.0b2}/redis/auth/err.py +0 -0
  110. {redis-5.3.0b5 → redis-6.0.0b2}/redis/auth/idp.py +0 -0
  111. {redis-5.3.0b5 → redis-6.0.0b2}/redis/auth/token_manager.py +0 -0
  112. {redis-5.3.0b5 → redis-6.0.0b2}/redis/cache.py +0 -0
  113. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/__init__.py +0 -0
  114. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/bf/__init__.py +0 -0
  115. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/bf/commands.py +0 -0
  116. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/bf/info.py +0 -0
  117. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/json/__init__.py +0 -0
  118. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/json/_util.py +0 -0
  119. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/json/commands.py +0 -0
  120. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/json/decoders.py +0 -0
  121. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/json/path.py +0 -0
  122. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/__init__.py +0 -0
  123. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/_util.py +0 -0
  124. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/document.py +0 -0
  125. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/field.py +0 -0
  126. /redis-5.3.0b5/redis/commands/search/indexDefinition.py → /redis-6.0.0b2/redis/commands/search/index_definition.py +0 -0
  127. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/querystring.py +0 -0
  128. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/reducers.py +0 -0
  129. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/result.py +0 -0
  130. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/search/suggestion.py +0 -0
  131. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/sentinel.py +0 -0
  132. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/timeseries/__init__.py +0 -0
  133. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/timeseries/commands.py +0 -0
  134. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/timeseries/info.py +0 -0
  135. {redis-5.3.0b5 → redis-6.0.0b2}/redis/commands/timeseries/utils.py +0 -0
  136. {redis-5.3.0b5 → redis-6.0.0b2}/redis/crc.py +0 -0
  137. {redis-5.3.0b5 → redis-6.0.0b2}/redis/credentials.py +0 -0
  138. {redis-5.3.0b5 → redis-6.0.0b2}/redis/event.py +0 -0
  139. /redis-5.3.0b5/tests/__init__.py → /redis-6.0.0b2/redis/py.typed +0 -0
  140. {redis-5.3.0b5 → redis-6.0.0b2}/redis/retry.py +0 -0
  141. {redis-5.3.0b5 → redis-6.0.0b2}/redis/typing.py +0 -0
  142. {redis-5.3.0b5/tests/test_asyncio → redis-6.0.0b2/tests}/__init__.py +0 -0
  143. {redis-5.3.0b5 → redis-6.0.0b2}/tests/mocks.py +0 -0
  144. {redis-5.3.0b5 → redis-6.0.0b2}/tests/ssl_utils.py +0 -0
  145. {redis-5.3.0b5/tests/test_auth → redis-6.0.0b2/tests/test_asyncio}/__init__.py +0 -0
  146. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/compat.py +0 -0
  147. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/mocks.py +0 -0
  148. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_bloom.py +0 -0
  149. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_connect.py +0 -0
  150. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_cwe_404.py +0 -0
  151. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_json.py +0 -0
  152. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_monitor.py +0 -0
  153. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_pubsub.py +0 -0
  154. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_sentinel_managed_connection.py +0 -0
  155. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/test_timeseries.py +0 -0
  156. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/testdata/jsontestdata.py +0 -0
  157. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/testdata/titles.csv +0 -0
  158. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_asyncio/testdata/will_play_text.csv.bz2 +0 -0
  159. {redis-5.3.0b5/tests/test_graph_utils → redis-6.0.0b2/tests/test_auth}/__init__.py +0 -0
  160. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_bloom.py +0 -0
  161. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_command_parser.py +0 -0
  162. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_connect.py +0 -0
  163. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_encoding.py +0 -0
  164. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_function.py +0 -0
  165. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_json.py +0 -0
  166. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_monitor.py +0 -0
  167. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_parsers/test_helpers.py +0 -0
  168. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_scripting.py +0 -0
  169. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_ssl.py +0 -0
  170. {redis-5.3.0b5 → redis-6.0.0b2}/tests/test_timeseries.py +0 -0
  171. {redis-5.3.0b5 → redis-6.0.0b2}/tests/testdata/jsontestdata.py +0 -0
  172. {redis-5.3.0b5 → redis-6.0.0b2}/tests/testdata/titles.csv +0 -0
  173. {redis-5.3.0b5 → redis-6.0.0b2}/tests/testdata/will_play_text.csv.bz2 +0 -0
@@ -0,0 +1,28 @@
1
+ *.pyc
2
+ redis.egg-info
3
+ build/
4
+ dist/
5
+ dump.rdb
6
+ _build
7
+ vagrant/.vagrant
8
+ .python-version
9
+ .cache
10
+ .eggs
11
+ .idea
12
+ .coverage
13
+ env
14
+ venv
15
+ coverage.xml
16
+ .venv*
17
+ *.xml
18
+ .coverage*
19
+ prof
20
+ profile_output*
21
+ docker/stunnel/keys
22
+ /dockers/*/node-*/*
23
+ /dockers/*/tls/*
24
+ /dockers/standalone/
25
+ /dockers/cluster/
26
+ /dockers/replica/
27
+ /dockers/sentinel/
28
+ /dockers/redis-stack/
@@ -1,17 +1,16 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: redis
3
- Version: 5.3.0b5
3
+ Version: 6.0.0b2
4
4
  Summary: Python client for Redis database and key-value store
5
- Home-page: https://github.com/redis/redis-py
6
- Author: Redis Inc.
7
- Author-email: oss@redis.com
8
- License: MIT
9
- Project-URL: Documentation, https://redis.readthedocs.io/en/latest/
10
5
  Project-URL: Changes, https://github.com/redis/redis-py/releases
11
6
  Project-URL: Code, https://github.com/redis/redis-py
7
+ Project-URL: Documentation, https://redis.readthedocs.io/en/latest/
8
+ Project-URL: Homepage, https://github.com/redis/redis-py
12
9
  Project-URL: Issue tracker, https://github.com/redis/redis-py/issues
13
- Keywords: Redis,key-value store,database
14
- Platform: UNKNOWN
10
+ Author-email: "Redis Inc." <oss@redis.com>
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: Redis,database,key-value-store
15
14
  Classifier: Development Status :: 5 - Production/Stable
16
15
  Classifier: Environment :: Console
17
16
  Classifier: Intended Audience :: Developers
@@ -25,13 +24,20 @@ Classifier: Programming Language :: Python :: 3.9
25
24
  Classifier: Programming Language :: Python :: 3.10
26
25
  Classifier: Programming Language :: Python :: 3.11
27
26
  Classifier: Programming Language :: Python :: 3.12
27
+ Classifier: Programming Language :: Python :: 3.13
28
28
  Classifier: Programming Language :: Python :: Implementation :: CPython
29
29
  Classifier: Programming Language :: Python :: Implementation :: PyPy
30
30
  Requires-Python: >=3.8
31
- Description-Content-Type: text/markdown
31
+ Requires-Dist: async-timeout>=4.0.3; python_full_version < '3.11.3'
32
32
  Provides-Extra: hiredis
33
+ Requires-Dist: hiredis>=3.0.0; extra == 'hiredis'
34
+ Provides-Extra: jwt
35
+ Requires-Dist: pyjwt~=2.9.0; extra == 'jwt'
33
36
  Provides-Extra: ocsp
34
- License-File: LICENSE
37
+ Requires-Dist: cryptography>=36.0.1; extra == 'ocsp'
38
+ Requires-Dist: pyopenssl>=20.0.1; extra == 'ocsp'
39
+ Requires-Dist: requests>=2.31.0; extra == 'ocsp'
40
+ Description-Content-Type: text/markdown
35
41
 
36
42
  # redis-py
37
43
 
@@ -48,13 +54,13 @@ The Python interface to the Redis key-value store.
48
54
 
49
55
  ---------------------------------------------
50
56
 
51
- **Note: ** redis-py 5.0 will be the last version of redis-py to support Python 3.7, as it has reached [end of life](https://devguide.python.org/versions/). redis-py 5.1 will support Python 3.8+.
57
+ **Note:** redis-py 5.0 will be the last version of redis-py to support Python 3.7, as it has reached [end of life](https://devguide.python.org/versions/). redis-py 5.1 will support Python 3.8+.
52
58
 
53
59
  ---------------------------------------------
54
60
 
55
61
  ## How do I Redis?
56
62
 
57
- [Learn for free at Redis University](https://redis.io/university/)
63
+ [Learn for free at Redis University](https://redis.io/learn/university)
58
64
 
59
65
  [Try the Redis Cloud](https://redis.io/try-free/)
60
66
 
@@ -89,7 +95,7 @@ Looking for a high-level library to handle object mapping? See [redis-om-python]
89
95
 
90
96
  ## Supported Redis Versions
91
97
 
92
- The most recent version of this library supports redis version [5.0](https://github.com/redis/redis/blob/5.0/00-RELEASENOTES), [6.0](https://github.com/redis/redis/blob/6.0/00-RELEASENOTES), [6.2](https://github.com/redis/redis/blob/6.2/00-RELEASENOTES), [7.0](https://github.com/redis/redis/blob/7.0/00-RELEASENOTES), [7.2](https://github.com/redis/redis/blob/7.2/00-RELEASENOTES) and [7.4](https://github.com/redis/redis/blob/7.4/00-RELEASENOTES).
98
+ The most recent version of this library supports redis version [7.2](https://github.com/redis/redis/blob/7.2/00-RELEASENOTES), [7.4](https://github.com/redis/redis/blob/7.4/00-RELEASENOTES) and [8.0](https://github.com/redis/redis/blob/8.0/00-RELEASENOTES).
93
99
 
94
100
  The table below highlights version compatibility of the most-recent library versions and redis versions.
95
101
 
@@ -97,7 +103,8 @@ The table below highlights version compatibility of the most-recent library vers
97
103
  |-----------------|-------------------|
98
104
  | 3.5.3 | <= 6.2 Family of releases |
99
105
  | >= 4.5.0 | Version 5.0 to 7.0 |
100
- | >= 5.0.0 | Version 5.0 to current |
106
+ | >= 5.0.0 | Version 5.0 to 7.4 |
107
+ | >= 6.0.0 | Version 7.2 to current |
101
108
 
102
109
 
103
110
  ## Usage
@@ -187,8 +194,42 @@ The following example shows how to utilize [Redis Pub/Sub](https://redis.io/docs
187
194
  {'pattern': None, 'type': 'subscribe', 'channel': b'my-second-channel', 'data': 1}
188
195
  ```
189
196
 
197
+ ### Redis’ search and query capabilities default dialect
198
+
199
+ Release 6.0.0 introduces a client-side default dialect for Redis’ search and query capabilities.
200
+ By default, the client now overrides the server-side dialect with version 2, automatically appending *DIALECT 2* to commands like *FT.AGGREGATE* and *FT.SEARCH*.
190
201
 
191
- --------------------------
202
+ **Important**: Be aware that the query dialect may impact the results returned. If needed, you can revert to a different dialect version by configuring the client accordingly.
203
+
204
+ ``` python
205
+ >>> from redis.commands.search.field import TextField
206
+ >>> from redis.commands.search.query import Query
207
+ >>> from redis.commands.search.index_definition import IndexDefinition
208
+ >>> import redis
209
+
210
+ >>> r = redis.Redis(host='localhost', port=6379, db=0)
211
+ >>> r.ft().create_index(
212
+ >>> (TextField("name"), TextField("lastname")),
213
+ >>> definition=IndexDefinition(prefix=["test:"]),
214
+ >>> )
215
+
216
+ >>> r.hset("test:1", "name", "James")
217
+ >>> r.hset("test:1", "lastname", "Brown")
218
+
219
+ >>> # Query with default DIALECT 2
220
+ >>> query = "@name: James Brown"
221
+ >>> q = Query(query)
222
+ >>> res = r.ft().search(q)
223
+
224
+ >>> # Query with explicit DIALECT 1
225
+ >>> query = "@name: James Brown"
226
+ >>> q = Query(query).dialect(1)
227
+ >>> res = r.ft().search(q)
228
+ ```
229
+
230
+ You can find further details in the [query dialect documentation](https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/dialects/).
231
+
232
+ ---------------------------------------------
192
233
 
193
234
  ### Author
194
235
 
@@ -205,4 +246,3 @@ Special thanks to:
205
246
  - Paul Hubbard for initial packaging support.
206
247
 
207
248
  [![Redis](./docs/_static/logo-redis.svg)](https://redis.io)
208
-
@@ -13,13 +13,13 @@ The Python interface to the Redis key-value store.
13
13
 
14
14
  ---------------------------------------------
15
15
 
16
- **Note: ** redis-py 5.0 will be the last version of redis-py to support Python 3.7, as it has reached [end of life](https://devguide.python.org/versions/). redis-py 5.1 will support Python 3.8+.
16
+ **Note:** redis-py 5.0 will be the last version of redis-py to support Python 3.7, as it has reached [end of life](https://devguide.python.org/versions/). redis-py 5.1 will support Python 3.8+.
17
17
 
18
18
  ---------------------------------------------
19
19
 
20
20
  ## How do I Redis?
21
21
 
22
- [Learn for free at Redis University](https://redis.io/university/)
22
+ [Learn for free at Redis University](https://redis.io/learn/university)
23
23
 
24
24
  [Try the Redis Cloud](https://redis.io/try-free/)
25
25
 
@@ -54,7 +54,7 @@ Looking for a high-level library to handle object mapping? See [redis-om-python]
54
54
 
55
55
  ## Supported Redis Versions
56
56
 
57
- The most recent version of this library supports redis version [5.0](https://github.com/redis/redis/blob/5.0/00-RELEASENOTES), [6.0](https://github.com/redis/redis/blob/6.0/00-RELEASENOTES), [6.2](https://github.com/redis/redis/blob/6.2/00-RELEASENOTES), [7.0](https://github.com/redis/redis/blob/7.0/00-RELEASENOTES), [7.2](https://github.com/redis/redis/blob/7.2/00-RELEASENOTES) and [7.4](https://github.com/redis/redis/blob/7.4/00-RELEASENOTES).
57
+ The most recent version of this library supports redis version [7.2](https://github.com/redis/redis/blob/7.2/00-RELEASENOTES), [7.4](https://github.com/redis/redis/blob/7.4/00-RELEASENOTES) and [8.0](https://github.com/redis/redis/blob/8.0/00-RELEASENOTES).
58
58
 
59
59
  The table below highlights version compatibility of the most-recent library versions and redis versions.
60
60
 
@@ -62,7 +62,8 @@ The table below highlights version compatibility of the most-recent library vers
62
62
  |-----------------|-------------------|
63
63
  | 3.5.3 | <= 6.2 Family of releases |
64
64
  | >= 4.5.0 | Version 5.0 to 7.0 |
65
- | >= 5.0.0 | Version 5.0 to current |
65
+ | >= 5.0.0 | Version 5.0 to 7.4 |
66
+ | >= 6.0.0 | Version 7.2 to current |
66
67
 
67
68
 
68
69
  ## Usage
@@ -152,8 +153,42 @@ The following example shows how to utilize [Redis Pub/Sub](https://redis.io/docs
152
153
  {'pattern': None, 'type': 'subscribe', 'channel': b'my-second-channel', 'data': 1}
153
154
  ```
154
155
 
156
+ ### Redis’ search and query capabilities default dialect
155
157
 
156
- --------------------------
158
+ Release 6.0.0 introduces a client-side default dialect for Redis’ search and query capabilities.
159
+ By default, the client now overrides the server-side dialect with version 2, automatically appending *DIALECT 2* to commands like *FT.AGGREGATE* and *FT.SEARCH*.
160
+
161
+ **Important**: Be aware that the query dialect may impact the results returned. If needed, you can revert to a different dialect version by configuring the client accordingly.
162
+
163
+ ``` python
164
+ >>> from redis.commands.search.field import TextField
165
+ >>> from redis.commands.search.query import Query
166
+ >>> from redis.commands.search.index_definition import IndexDefinition
167
+ >>> import redis
168
+
169
+ >>> r = redis.Redis(host='localhost', port=6379, db=0)
170
+ >>> r.ft().create_index(
171
+ >>> (TextField("name"), TextField("lastname")),
172
+ >>> definition=IndexDefinition(prefix=["test:"]),
173
+ >>> )
174
+
175
+ >>> r.hset("test:1", "name", "James")
176
+ >>> r.hset("test:1", "lastname", "Brown")
177
+
178
+ >>> # Query with default DIALECT 2
179
+ >>> query = "@name: James Brown"
180
+ >>> q = Query(query)
181
+ >>> res = r.ft().search(q)
182
+
183
+ >>> # Query with explicit DIALECT 1
184
+ >>> query = "@name: James Brown"
185
+ >>> q = Query(query).dialect(1)
186
+ >>> res = r.ft().search(q)
187
+ ```
188
+
189
+ You can find further details in the [query dialect documentation](https://redis.io/docs/latest/develop/interact/search-and-query/advanced-concepts/dialects/).
190
+
191
+ ---------------------------------------------
157
192
 
158
193
  ### Author
159
194
 
@@ -0,0 +1,16 @@
1
+ build
2
+ click==8.0.4
3
+ invoke==2.2.0
4
+ mock
5
+ packaging>=20.4
6
+ pytest
7
+ pytest-asyncio>=0.23.0
8
+ pytest-cov
9
+ pytest-profiling==1.8.1
10
+ pytest-timeout
11
+ ruff==0.9.6
12
+ ujson>=4.2.0
13
+ uvloop
14
+ vulture>=2.3.0
15
+ numpy>=1.24.0
16
+ redis-entraid==0.4.0b2
@@ -0,0 +1,124 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "redis"
7
+ dynamic = ["version"]
8
+ description = "Python client for Redis database and key-value store"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.8"
12
+ authors = [{ name = "Redis Inc.", email = "oss@redis.com" }]
13
+ keywords = ["Redis", "database", "key-value-store"]
14
+ classifiers = [
15
+ "Development Status :: 5 - Production/Stable",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ "Programming Language :: Python",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3 :: Only",
23
+ "Programming Language :: Python :: 3.8",
24
+ "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
29
+ "Programming Language :: Python :: Implementation :: CPython",
30
+ "Programming Language :: Python :: Implementation :: PyPy",
31
+ ]
32
+ dependencies = ['async-timeout>=4.0.3; python_full_version<"3.11.3"']
33
+
34
+ [project.optional-dependencies]
35
+ hiredis = [
36
+ "hiredis>=3.0.0",
37
+ ]
38
+ ocsp = [
39
+ "cryptography>=36.0.1",
40
+ "pyopenssl>=20.0.1",
41
+ "requests>=2.31.0",
42
+ ]
43
+ jwt = [
44
+ "PyJWT~=2.9.0",
45
+ ]
46
+
47
+ [project.urls]
48
+ Changes = "https://github.com/redis/redis-py/releases"
49
+ Code = "https://github.com/redis/redis-py"
50
+ Documentation = "https://redis.readthedocs.io/en/latest/"
51
+ Homepage = "https://github.com/redis/redis-py"
52
+ "Issue tracker" = "https://github.com/redis/redis-py/issues"
53
+
54
+ [tool.hatch.version]
55
+ path = "redis/__init__.py"
56
+
57
+ [tool.hatch.build.targets.sdist]
58
+ include = ["/redis", "/tests", "dev_requirements.txt"]
59
+
60
+ [tool.hatch.build.targets.wheel]
61
+ include = ["/redis"]
62
+
63
+ [tool.pytest.ini_options]
64
+ addopts = "-s"
65
+ markers = [
66
+ "redismod: run only the redis module tests",
67
+ "pipeline: pipeline tests",
68
+ "onlycluster: marks tests to be run only with cluster mode redis",
69
+ "onlynoncluster: marks tests to be run only with standalone redis",
70
+ "ssl: marker for only the ssl tests",
71
+ "asyncio: marker for async tests",
72
+ "replica: replica tests",
73
+ "experimental: run only experimental tests",
74
+ "cp_integration: credential provider integration tests",
75
+ ]
76
+ asyncio_default_fixture_loop_scope = "function"
77
+ asyncio_mode = "auto"
78
+ timeout = 30
79
+ filterwarnings = [
80
+ "always",
81
+ # Ignore a coverage warning when COVERAGE_CORE=sysmon for Pythons < 3.12.
82
+ "ignore:sys.monitoring isn't available:coverage.exceptions.CoverageWarning",
83
+ ]
84
+
85
+ [tool.ruff]
86
+ target-version = "py38"
87
+ line-length = 88
88
+ exclude = [
89
+ "*.egg-info",
90
+ "*.pyc",
91
+ ".git",
92
+ ".venv*",
93
+ "build",
94
+ "dist",
95
+ "docker",
96
+ "docs/*",
97
+ "doctests/*",
98
+ "tasks.py",
99
+ "venv*",
100
+ "whitelist.py",
101
+ ]
102
+
103
+ [tool.ruff.lint]
104
+ ignore = [
105
+ "E501", # line too long (taken care of with ruff format)
106
+ "E741", # ambiguous variable name
107
+ "N818", # Errors should have Error suffix
108
+ ]
109
+
110
+ select = ["E", "F", "FLY", "I", "N", "W"]
111
+
112
+ [tool.ruff.lint.per-file-ignores]
113
+ "redis/commands/bf/*" = [
114
+ # the `bf` module uses star imports, so this is required there.
115
+ "F405", # name may be undefined, or defined from star imports
116
+ ]
117
+ "redis/commands/{bf,timeseries,json,search}/*" = ["N"]
118
+ "tests/*" = [
119
+ "I", # TODO: could be enabled, plenty of changes
120
+ "N801", # class name should use CapWords convention
121
+ "N803", # argument name should be lowercase
122
+ "N802", # function name should be lowercase
123
+ "N806", # variable name should be lowercase
124
+ ]
@@ -1,5 +1,3 @@
1
- from importlib import metadata
2
-
3
1
  from redis import asyncio # noqa
4
2
  from redis.backoff import default_backoff
5
3
  from redis.client import Redis, StrictRedis
@@ -44,16 +42,9 @@ def int_or_str(value):
44
42
  return value
45
43
 
46
44
 
47
- try:
48
- __version__ = metadata.version("redis")
49
- except metadata.PackageNotFoundError:
50
- __version__ = "99.99.99"
51
-
45
+ __version__ = "6.0.0b2"
46
+ VERSION = tuple(map(int_or_str, __version__.split(".")))
52
47
 
53
- try:
54
- VERSION = tuple(map(int_or_str, __version__.split(".")))
55
- except AttributeError:
56
- VERSION = tuple([99, 99, 99])
57
48
 
58
49
  __all__ = [
59
50
  "AuthenticationError",
@@ -9,26 +9,32 @@ else:
9
9
  from async_timeout import timeout as async_timeout
10
10
 
11
11
  from ..exceptions import (
12
+ AskError,
12
13
  AuthenticationError,
13
14
  AuthenticationWrongNumberOfArgsError,
14
15
  BusyLoadingError,
16
+ ClusterCrossSlotError,
17
+ ClusterDownError,
15
18
  ConnectionError,
16
19
  ExecAbortError,
20
+ MasterDownError,
17
21
  ModuleError,
22
+ MovedError,
18
23
  NoPermissionError,
19
24
  NoScriptError,
20
25
  OutOfMemoryError,
21
26
  ReadOnlyError,
22
27
  RedisError,
23
28
  ResponseError,
29
+ TryAgainError,
24
30
  )
25
31
  from ..typing import EncodableT
26
32
  from .encoders import Encoder
27
33
  from .socket import SERVER_CLOSED_CONNECTION_ERROR, SocketBuffer
28
34
 
29
- MODULE_LOAD_ERROR = "Error loading the extension. " "Please check the server logs."
35
+ MODULE_LOAD_ERROR = "Error loading the extension. Please check the server logs."
30
36
  NO_SUCH_MODULE_ERROR = "Error unloading module: no such module with that name"
31
- MODULE_UNLOAD_NOT_POSSIBLE_ERROR = "Error unloading module: operation not " "possible."
37
+ MODULE_UNLOAD_NOT_POSSIBLE_ERROR = "Error unloading module: operation not possible."
32
38
  MODULE_EXPORTS_DATA_TYPES_ERROR = (
33
39
  "Error unloading module: the module "
34
40
  "exports one or more module-side data "
@@ -72,6 +78,12 @@ class BaseParser(ABC):
72
78
  "READONLY": ReadOnlyError,
73
79
  "NOAUTH": AuthenticationError,
74
80
  "NOPERM": NoPermissionError,
81
+ "ASK": AskError,
82
+ "TRYAGAIN": TryAgainError,
83
+ "MOVED": MovedError,
84
+ "CLUSTERDOWN": ClusterDownError,
85
+ "CROSSSLOT": ClusterCrossSlotError,
86
+ "MASTERDOWN": MasterDownError,
75
87
  }
76
88
 
77
89
  @classmethod
@@ -2,7 +2,6 @@ import asyncio
2
2
  import copy
3
3
  import inspect
4
4
  import re
5
- import ssl
6
5
  import warnings
7
6
  from typing import (
8
7
  TYPE_CHECKING,
@@ -72,13 +71,21 @@ from redis.exceptions import (
72
71
  from redis.typing import ChannelT, EncodableT, KeyT
73
72
  from redis.utils import (
74
73
  HIREDIS_AVAILABLE,
74
+ SSL_AVAILABLE,
75
75
  _set_info_logger,
76
76
  deprecated_function,
77
77
  get_lib_version,
78
78
  safe_str,
79
79
  str_if_bytes,
80
+ truncate_text,
80
81
  )
81
82
 
83
+ if TYPE_CHECKING and SSL_AVAILABLE:
84
+ from ssl import TLSVersion, VerifyMode
85
+ else:
86
+ TLSVersion = None
87
+ VerifyMode = None
88
+
82
89
  PubSubHandler = Callable[[Dict[str, str]], Awaitable[None]]
83
90
  _KeyT = TypeVar("_KeyT", bound=KeyT)
84
91
  _ArgT = TypeVar("_ArgT", KeyT, EncodableT)
@@ -222,11 +229,11 @@ class Redis(
222
229
  ssl: bool = False,
223
230
  ssl_keyfile: Optional[str] = None,
224
231
  ssl_certfile: Optional[str] = None,
225
- ssl_cert_reqs: str = "required",
232
+ ssl_cert_reqs: Union[str, VerifyMode] = "required",
226
233
  ssl_ca_certs: Optional[str] = None,
227
234
  ssl_ca_data: Optional[str] = None,
228
235
  ssl_check_hostname: bool = False,
229
- ssl_min_version: Optional[ssl.TLSVersion] = None,
236
+ ssl_min_version: Optional[TLSVersion] = None,
230
237
  ssl_ciphers: Optional[str] = None,
231
238
  max_connections: Optional[int] = None,
232
239
  single_connection_client: bool = False,
@@ -375,7 +382,7 @@ class Redis(
375
382
  if self.single_connection_client:
376
383
  async with self._single_conn_lock:
377
384
  if self.connection is None:
378
- self.connection = await self.connection_pool.get_connection("_")
385
+ self.connection = await self.connection_pool.get_connection()
379
386
 
380
387
  self._event_dispatcher.dispatch(
381
388
  AfterSingleConnectionInstantiationEvent(
@@ -478,6 +485,7 @@ class Redis(
478
485
  blocking_timeout: Optional[float] = None,
479
486
  lock_class: Optional[Type[Lock]] = None,
480
487
  thread_local: bool = True,
488
+ raise_on_release_error: bool = True,
481
489
  ) -> Lock:
482
490
  """
483
491
  Return a new Lock object using key ``name`` that mimics
@@ -524,6 +532,11 @@ class Redis(
524
532
  thread-1 would see the token value as "xyz" and would be
525
533
  able to successfully release the thread-2's lock.
526
534
 
535
+ ``raise_on_release_error`` indicates whether to raise an exception when
536
+ the lock is no longer owned when exiting the context manager. By default,
537
+ this is True, meaning an exception will be raised. If False, the warning
538
+ will be logged and the exception will be suppressed.
539
+
527
540
  In some use cases it's necessary to disable thread local storage. For
528
541
  example, if you have code where one thread acquires a lock and passes
529
542
  that lock instance to a worker thread to release later. If thread
@@ -541,6 +554,7 @@ class Redis(
541
554
  blocking=blocking,
542
555
  blocking_timeout=blocking_timeout,
543
556
  thread_local=thread_local,
557
+ raise_on_release_error=raise_on_release_error,
544
558
  )
545
559
 
546
560
  def pubsub(self, **kwargs) -> "PubSub":
@@ -638,7 +652,7 @@ class Redis(
638
652
  await self.initialize()
639
653
  pool = self.connection_pool
640
654
  command_name = args[0]
641
- conn = self.connection or await pool.get_connection(command_name, **options)
655
+ conn = self.connection or await pool.get_connection()
642
656
 
643
657
  if self.single_connection_client:
644
658
  await self._single_conn_lock.acquire()
@@ -712,7 +726,7 @@ class Monitor:
712
726
 
713
727
  async def connect(self):
714
728
  if self.connection is None:
715
- self.connection = await self.connection_pool.get_connection("MONITOR")
729
+ self.connection = await self.connection_pool.get_connection()
716
730
 
717
731
  async def __aenter__(self):
718
732
  await self.connect()
@@ -900,9 +914,7 @@ class PubSub:
900
914
  Ensure that the PubSub is connected
901
915
  """
902
916
  if self.connection is None:
903
- self.connection = await self.connection_pool.get_connection(
904
- "pubsub", self.shard_hint
905
- )
917
+ self.connection = await self.connection_pool.get_connection()
906
918
  # register a callback that re-subscribes to any channels we
907
919
  # were listening to when we were disconnected
908
920
  self.connection.register_connect_callback(self.on_connect)
@@ -1370,9 +1382,7 @@ class Pipeline(Redis): # lgtm [py/init-calls-subclass]
1370
1382
  conn = self.connection
1371
1383
  # if this is the first call, we need a connection
1372
1384
  if not conn:
1373
- conn = await self.connection_pool.get_connection(
1374
- command_name, self.shard_hint
1375
- )
1385
+ conn = await self.connection_pool.get_connection()
1376
1386
  self.connection = conn
1377
1387
 
1378
1388
  return await conn.retry.call_with_retry(
@@ -1505,7 +1515,10 @@ class Pipeline(Redis): # lgtm [py/init-calls-subclass]
1505
1515
  self, exception: Exception, number: int, command: Iterable[object]
1506
1516
  ) -> None:
1507
1517
  cmd = " ".join(map(safe_str, command))
1508
- msg = f"Command # {number} ({cmd}) of pipeline caused error: {exception.args}"
1518
+ msg = (
1519
+ f"Command # {number} ({truncate_text(cmd)}) "
1520
+ "of pipeline caused error: {exception.args}"
1521
+ )
1509
1522
  exception.args = (msg,) + exception.args[1:]
1510
1523
 
1511
1524
  async def parse_response(
@@ -1568,7 +1581,7 @@ class Pipeline(Redis): # lgtm [py/init-calls-subclass]
1568
1581
 
1569
1582
  conn = self.connection
1570
1583
  if not conn:
1571
- conn = await self.connection_pool.get_connection("MULTI", self.shard_hint)
1584
+ conn = await self.connection_pool.get_connection()
1572
1585
  # assign to self.connection so reset() releases the connection
1573
1586
  # back to the pool after we're done
1574
1587
  self.connection = conn