redis 5.3.0b4__py3-none-any.whl → 6.0.0__py3-none-any.whl

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 (51) hide show
  1. redis/__init__.py +2 -11
  2. redis/_parsers/base.py +14 -2
  3. redis/_parsers/resp3.py +2 -2
  4. redis/asyncio/client.py +103 -83
  5. redis/asyncio/cluster.py +147 -102
  6. redis/asyncio/connection.py +77 -24
  7. redis/asyncio/lock.py +26 -5
  8. redis/asyncio/retry.py +12 -0
  9. redis/asyncio/sentinel.py +11 -1
  10. redis/asyncio/utils.py +1 -1
  11. redis/auth/token.py +6 -2
  12. redis/backoff.py +15 -0
  13. redis/client.py +160 -138
  14. redis/cluster.py +211 -82
  15. redis/commands/cluster.py +1 -11
  16. redis/commands/core.py +219 -207
  17. redis/commands/helpers.py +19 -76
  18. redis/commands/json/__init__.py +1 -1
  19. redis/commands/redismodules.py +5 -17
  20. redis/commands/search/aggregation.py +3 -1
  21. redis/commands/search/commands.py +43 -16
  22. redis/commands/search/dialect.py +3 -0
  23. redis/commands/search/profile_information.py +14 -0
  24. redis/commands/search/query.py +5 -1
  25. redis/commands/timeseries/__init__.py +1 -1
  26. redis/commands/vectorset/__init__.py +46 -0
  27. redis/commands/vectorset/commands.py +367 -0
  28. redis/commands/vectorset/utils.py +94 -0
  29. redis/connection.py +89 -33
  30. redis/exceptions.py +4 -1
  31. redis/lock.py +24 -4
  32. redis/ocsp.py +2 -1
  33. redis/retry.py +12 -0
  34. redis/sentinel.py +3 -1
  35. redis/typing.py +1 -1
  36. redis/utils.py +114 -1
  37. {redis-5.3.0b4.dist-info → redis-6.0.0.dist-info}/METADATA +57 -23
  38. redis-6.0.0.dist-info/RECORD +78 -0
  39. {redis-5.3.0b4.dist-info → redis-6.0.0.dist-info}/WHEEL +1 -2
  40. redis/commands/graph/__init__.py +0 -263
  41. redis/commands/graph/commands.py +0 -313
  42. redis/commands/graph/edge.py +0 -91
  43. redis/commands/graph/exceptions.py +0 -3
  44. redis/commands/graph/execution_plan.py +0 -211
  45. redis/commands/graph/node.py +0 -88
  46. redis/commands/graph/path.py +0 -78
  47. redis/commands/graph/query_result.py +0 -588
  48. redis-5.3.0b4.dist-info/RECORD +0 -82
  49. redis-5.3.0b4.dist-info/top_level.txt +0 -1
  50. /redis/commands/search/{indexDefinition.py → index_definition.py} +0 -0
  51. {redis-5.3.0b4.dist-info → redis-6.0.0.dist-info/licenses}/LICENSE +0 -0
redis/client.py CHANGED
@@ -2,9 +2,19 @@ import copy
2
2
  import re
3
3
  import threading
4
4
  import time
5
- import warnings
6
5
  from itertools import chain
7
- from typing import Any, Callable, Dict, List, Optional, Type, Union
6
+ from typing import (
7
+ TYPE_CHECKING,
8
+ Any,
9
+ Callable,
10
+ Dict,
11
+ List,
12
+ Mapping,
13
+ Optional,
14
+ Set,
15
+ Type,
16
+ Union,
17
+ )
8
18
 
9
19
  from redis._parsers.encoders import Encoder
10
20
  from redis._parsers.helpers import (
@@ -13,6 +23,7 @@ from redis._parsers.helpers import (
13
23
  _RedisCallbacksRESP3,
14
24
  bool_ok,
15
25
  )
26
+ from redis.backoff import ExponentialWithJitterBackoff
16
27
  from redis.cache import CacheConfig, CacheInterface
17
28
  from redis.commands import (
18
29
  CoreCommands,
@@ -20,6 +31,7 @@ from redis.commands import (
20
31
  SentinelCommands,
21
32
  list_or_args,
22
33
  )
34
+ from redis.commands.core import Script
23
35
  from redis.connection import (
24
36
  AbstractConnection,
25
37
  ConnectionPool,
@@ -40,7 +52,6 @@ from redis.exceptions import (
40
52
  PubSubError,
41
53
  RedisError,
42
54
  ResponseError,
43
- TimeoutError,
44
55
  WatchError,
45
56
  )
46
57
  from redis.lock import Lock
@@ -48,11 +59,18 @@ from redis.retry import Retry
48
59
  from redis.utils import (
49
60
  HIREDIS_AVAILABLE,
50
61
  _set_info_logger,
62
+ deprecated_args,
51
63
  get_lib_version,
52
64
  safe_str,
53
65
  str_if_bytes,
66
+ truncate_text,
54
67
  )
55
68
 
69
+ if TYPE_CHECKING:
70
+ import ssl
71
+
72
+ import OpenSSL
73
+
56
74
  SYM_EMPTY = b""
57
75
  EMPTY_RESPONSE = "EMPTY_RESPONSE"
58
76
 
@@ -173,49 +191,54 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
173
191
  client.auto_close_connection_pool = True
174
192
  return client
175
193
 
194
+ @deprecated_args(
195
+ args_to_warn=["retry_on_timeout"],
196
+ reason="TimeoutError is included by default.",
197
+ version="6.0.0",
198
+ )
176
199
  def __init__(
177
200
  self,
178
- host="localhost",
179
- port=6379,
180
- db=0,
181
- password=None,
182
- socket_timeout=None,
183
- socket_connect_timeout=None,
184
- socket_keepalive=None,
185
- socket_keepalive_options=None,
186
- connection_pool=None,
187
- unix_socket_path=None,
188
- encoding="utf-8",
189
- encoding_errors="strict",
190
- charset=None,
191
- errors=None,
192
- decode_responses=False,
193
- retry_on_timeout=False,
194
- retry_on_error=None,
195
- ssl=False,
196
- ssl_keyfile=None,
197
- ssl_certfile=None,
198
- ssl_cert_reqs="required",
199
- ssl_ca_certs=None,
200
- ssl_ca_path=None,
201
- ssl_ca_data=None,
202
- ssl_check_hostname=False,
203
- ssl_password=None,
204
- ssl_validate_ocsp=False,
205
- ssl_validate_ocsp_stapled=False,
206
- ssl_ocsp_context=None,
207
- ssl_ocsp_expected_cert=None,
208
- ssl_min_version=None,
209
- ssl_ciphers=None,
210
- max_connections=None,
211
- single_connection_client=False,
212
- health_check_interval=0,
213
- client_name=None,
214
- lib_name="redis-py",
215
- lib_version=get_lib_version(),
216
- username=None,
217
- retry=None,
218
- redis_connect_func=None,
201
+ host: str = "localhost",
202
+ port: int = 6379,
203
+ db: int = 0,
204
+ password: Optional[str] = None,
205
+ socket_timeout: Optional[float] = None,
206
+ socket_connect_timeout: Optional[float] = None,
207
+ socket_keepalive: Optional[bool] = None,
208
+ socket_keepalive_options: Optional[Mapping[int, Union[int, bytes]]] = None,
209
+ connection_pool: Optional[ConnectionPool] = None,
210
+ unix_socket_path: Optional[str] = None,
211
+ encoding: str = "utf-8",
212
+ encoding_errors: str = "strict",
213
+ decode_responses: bool = False,
214
+ retry_on_timeout: bool = False,
215
+ retry: Retry = Retry(
216
+ backoff=ExponentialWithJitterBackoff(base=1, cap=10), retries=3
217
+ ),
218
+ retry_on_error: Optional[List[Type[Exception]]] = None,
219
+ ssl: bool = False,
220
+ ssl_keyfile: Optional[str] = None,
221
+ ssl_certfile: Optional[str] = None,
222
+ ssl_cert_reqs: Union[str, "ssl.VerifyMode"] = "required",
223
+ ssl_ca_certs: Optional[str] = None,
224
+ ssl_ca_path: Optional[str] = None,
225
+ ssl_ca_data: Optional[str] = None,
226
+ ssl_check_hostname: bool = True,
227
+ ssl_password: Optional[str] = None,
228
+ ssl_validate_ocsp: bool = False,
229
+ ssl_validate_ocsp_stapled: bool = False,
230
+ ssl_ocsp_context: Optional["OpenSSL.SSL.Context"] = None,
231
+ ssl_ocsp_expected_cert: Optional[str] = None,
232
+ ssl_min_version: Optional["ssl.TLSVersion"] = None,
233
+ ssl_ciphers: Optional[str] = None,
234
+ max_connections: Optional[int] = None,
235
+ single_connection_client: bool = False,
236
+ health_check_interval: int = 0,
237
+ client_name: Optional[str] = None,
238
+ lib_name: Optional[str] = "redis-py",
239
+ lib_version: Optional[str] = get_lib_version(),
240
+ username: Optional[str] = None,
241
+ redis_connect_func: Optional[Callable[[], None]] = None,
219
242
  credential_provider: Optional[CredentialProvider] = None,
220
243
  protocol: Optional[int] = 2,
221
244
  cache: Optional[CacheInterface] = None,
@@ -224,10 +247,24 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
224
247
  ) -> None:
225
248
  """
226
249
  Initialize a new Redis client.
227
- To specify a retry policy for specific errors, first set
228
- `retry_on_error` to a list of the error/s to retry on, then set
229
- `retry` to a valid `Retry` object.
230
- To retry on TimeoutError, `retry_on_timeout` can also be set to `True`.
250
+
251
+ To specify a retry policy for specific errors, you have two options:
252
+
253
+ 1. Set the `retry_on_error` to a list of the error/s to retry on, and
254
+ you can also set `retry` to a valid `Retry` object(in case the default
255
+ one is not appropriate) - with this approach the retries will be triggered
256
+ on the default errors specified in the Retry object enriched with the
257
+ errors specified in `retry_on_error`.
258
+
259
+ 2. Define a `Retry` object with configured 'supported_errors' and set
260
+ it to the `retry` parameter - with this approach you completely redefine
261
+ the errors on which retries will happen.
262
+
263
+ `retry_on_timeout` is deprecated - please include the TimeoutError
264
+ either in the Retry object or in the `retry_on_error` list.
265
+
266
+ When 'connection_pool' is provided - the retry configuration of the
267
+ provided pool will be used.
231
268
 
232
269
  Args:
233
270
 
@@ -240,24 +277,8 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
240
277
  else:
241
278
  self._event_dispatcher = event_dispatcher
242
279
  if not connection_pool:
243
- if charset is not None:
244
- warnings.warn(
245
- DeprecationWarning(
246
- '"charset" is deprecated. Use "encoding" instead'
247
- )
248
- )
249
- encoding = charset
250
- if errors is not None:
251
- warnings.warn(
252
- DeprecationWarning(
253
- '"errors" is deprecated. Use "encoding_errors" instead'
254
- )
255
- )
256
- encoding_errors = errors
257
280
  if not retry_on_error:
258
281
  retry_on_error = []
259
- if retry_on_timeout is True:
260
- retry_on_error.append(TimeoutError)
261
282
  kwargs = {
262
283
  "db": db,
263
284
  "username": username,
@@ -351,7 +372,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
351
372
  self.connection = None
352
373
  self._single_connection_client = single_connection_client
353
374
  if self._single_connection_client:
354
- self.connection = self.connection_pool.get_connection("_")
375
+ self.connection = self.connection_pool.get_connection()
355
376
  self._event_dispatcher.dispatch(
356
377
  AfterSingleConnectionInstantiationEvent(
357
378
  self.connection, ClientType.SYNC, self.single_connection_lock
@@ -379,10 +400,10 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
379
400
  """Get the connection's key-word arguments"""
380
401
  return self.connection_pool.connection_kwargs
381
402
 
382
- def get_retry(self) -> Optional["Retry"]:
403
+ def get_retry(self) -> Optional[Retry]:
383
404
  return self.get_connection_kwargs().get("retry")
384
405
 
385
- def set_retry(self, retry: "Retry") -> None:
406
+ def set_retry(self, retry: Retry) -> None:
386
407
  self.get_connection_kwargs().update({"retry": retry})
387
408
  self.connection_pool.set_retry(retry)
388
409
 
@@ -458,6 +479,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
458
479
  blocking_timeout: Optional[float] = None,
459
480
  lock_class: Union[None, Any] = None,
460
481
  thread_local: bool = True,
482
+ raise_on_release_error: bool = True,
461
483
  ):
462
484
  """
463
485
  Return a new Lock object using key ``name`` that mimics
@@ -504,6 +526,11 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
504
526
  thread-1 would see the token value as "xyz" and would be
505
527
  able to successfully release the thread-2's lock.
506
528
 
529
+ ``raise_on_release_error`` indicates whether to raise an exception when
530
+ the lock is no longer owned when exiting the context manager. By default,
531
+ this is True, meaning an exception will be raised. If False, the warning
532
+ will be logged and the exception will be suppressed.
533
+
507
534
  In some use cases it's necessary to disable thread local storage. For
508
535
  example, if you have code where one thread acquires a lock and passes
509
536
  that lock instance to a worker thread to release later. If thread
@@ -521,6 +548,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
521
548
  blocking=blocking,
522
549
  blocking_timeout=blocking_timeout,
523
550
  thread_local=thread_local,
551
+ raise_on_release_error=raise_on_release_error,
524
552
  )
525
553
 
526
554
  def pubsub(self, **kwargs):
@@ -548,9 +576,12 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
548
576
  self.close()
549
577
 
550
578
  def __del__(self):
551
- self.close()
579
+ try:
580
+ self.close()
581
+ except Exception:
582
+ pass
552
583
 
553
- def close(self):
584
+ def close(self) -> None:
554
585
  # In case a connection property does not yet exist
555
586
  # (due to a crash earlier in the Redis() constructor), return
556
587
  # immediately as there is nothing to clean-up.
@@ -572,18 +603,18 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
572
603
  conn.send_command(*args, **options)
573
604
  return self.parse_response(conn, command_name, **options)
574
605
 
575
- def _disconnect_raise(self, conn, error):
606
+ def _close_connection(self, conn) -> None:
576
607
  """
577
- Close the connection and raise an exception
578
- if retry_on_error is not set or the error
579
- is not one of the specified error types
608
+ Close the connection before retrying.
609
+
610
+ The supported exceptions are already checked in the
611
+ retry object so we don't need to do it here.
612
+
613
+ After we disconnect the connection, it will try to reconnect and
614
+ do a health check as part of the send_command logic(on connection level).
580
615
  """
616
+
581
617
  conn.disconnect()
582
- if (
583
- conn.retry_on_error is None
584
- or isinstance(error, tuple(conn.retry_on_error)) is False
585
- ):
586
- raise error
587
618
 
588
619
  # COMMAND EXECUTION AND PROTOCOL PARSING
589
620
  def execute_command(self, *args, **options):
@@ -593,7 +624,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
593
624
  """Execute a command and return a parsed response"""
594
625
  pool = self.connection_pool
595
626
  command_name = args[0]
596
- conn = self.connection or pool.get_connection(command_name, **options)
627
+ conn = self.connection or pool.get_connection()
597
628
 
598
629
  if self._single_connection_client:
599
630
  self.single_connection_lock.acquire()
@@ -602,7 +633,7 @@ class Redis(RedisModuleCommands, CoreCommands, SentinelCommands):
602
633
  lambda: self._send_command_parse_response(
603
634
  conn, command_name, *args, **options
604
635
  ),
605
- lambda error: self._disconnect_raise(conn, error),
636
+ lambda _: self._close_connection(conn),
606
637
  )
607
638
  finally:
608
639
  if self._single_connection_client:
@@ -652,7 +683,7 @@ class Monitor:
652
683
 
653
684
  def __init__(self, connection_pool):
654
685
  self.connection_pool = connection_pool
655
- self.connection = self.connection_pool.get_connection("MONITOR")
686
+ self.connection = self.connection_pool.get_connection()
656
687
 
657
688
  def __enter__(self):
658
689
  self.connection.send_command("MONITOR")
@@ -825,9 +856,7 @@ class PubSub:
825
856
  # subscribed to one or more channels
826
857
 
827
858
  if self.connection is None:
828
- self.connection = self.connection_pool.get_connection(
829
- "pubsub", self.shard_hint
830
- )
859
+ self.connection = self.connection_pool.get_connection()
831
860
  # register a callback that re-subscribes to any channels we
832
861
  # were listening to when we were disconnected
833
862
  self.connection.register_connect_callback(self.on_connect)
@@ -863,19 +892,14 @@ class PubSub:
863
892
  )
864
893
  ttl -= 1
865
894
 
866
- def _disconnect_raise_connect(self, conn, error) -> None:
895
+ def _reconnect(self, conn) -> None:
867
896
  """
868
- Close the connection and raise an exception
869
- if retry_on_error is not set or the error is not one
870
- of the specified error types. Otherwise, try to
871
- reconnect
897
+ The supported exceptions are already checked in the
898
+ retry object so we don't need to do it here.
899
+
900
+ In this error handler we are trying to reconnect to the server.
872
901
  """
873
902
  conn.disconnect()
874
- if (
875
- conn.retry_on_error is None
876
- or isinstance(error, tuple(conn.retry_on_error)) is False
877
- ):
878
- raise error
879
903
  conn.connect()
880
904
 
881
905
  def _execute(self, conn, command, *args, **kwargs):
@@ -888,7 +912,7 @@ class PubSub:
888
912
  """
889
913
  return conn.retry.call_with_retry(
890
914
  lambda: command(*args, **kwargs),
891
- lambda error: self._disconnect_raise_connect(conn, error),
915
+ lambda _: self._reconnect(conn),
892
916
  )
893
917
 
894
918
  def parse_response(self, block=True, timeout=0):
@@ -937,7 +961,7 @@ class PubSub:
937
961
  "did you forget to call subscribe() or psubscribe()?"
938
962
  )
939
963
 
940
- if conn.health_check_interval and time.time() > conn.next_health_check:
964
+ if conn.health_check_interval and time.monotonic() > conn.next_health_check:
941
965
  conn.send_command("PING", self.HEALTH_CHECK_MESSAGE, check_health=False)
942
966
  self.health_check_response_counter += 1
943
967
 
@@ -1087,12 +1111,12 @@ class PubSub:
1087
1111
  """
1088
1112
  if not self.subscribed:
1089
1113
  # Wait for subscription
1090
- start_time = time.time()
1114
+ start_time = time.monotonic()
1091
1115
  if self.subscribed_event.wait(timeout) is True:
1092
1116
  # The connection was subscribed during the timeout time frame.
1093
1117
  # The timeout should be adjusted based on the time spent
1094
1118
  # waiting for the subscription
1095
- time_spent = time.time() - start_time
1119
+ time_spent = time.monotonic() - start_time
1096
1120
  timeout = max(0.0, timeout - time_spent)
1097
1121
  else:
1098
1122
  # The connection isn't subscribed to any channels or patterns,
@@ -1257,7 +1281,8 @@ class Pipeline(Redis):
1257
1281
  in one transmission. This is convenient for batch processing, such as
1258
1282
  saving all the values in a list to Redis.
1259
1283
 
1260
- All commands executed within a pipeline are wrapped with MULTI and EXEC
1284
+ All commands executed within a pipeline(when running in transactional mode,
1285
+ which is the default behavior) are wrapped with MULTI and EXEC
1261
1286
  calls. This guarantees all commands executed in the pipeline will be
1262
1287
  executed atomically.
1263
1288
 
@@ -1278,9 +1303,10 @@ class Pipeline(Redis):
1278
1303
  self.response_callbacks = response_callbacks
1279
1304
  self.transaction = transaction
1280
1305
  self.shard_hint = shard_hint
1281
-
1282
1306
  self.watching = False
1283
- self.reset()
1307
+ self.command_stack = []
1308
+ self.scripts: Set[Script] = set()
1309
+ self.explicit_transaction = False
1284
1310
 
1285
1311
  def __enter__(self) -> "Pipeline":
1286
1312
  return self
@@ -1346,50 +1372,51 @@ class Pipeline(Redis):
1346
1372
  return self.immediate_execute_command(*args, **kwargs)
1347
1373
  return self.pipeline_execute_command(*args, **kwargs)
1348
1374
 
1349
- def _disconnect_reset_raise(self, conn, error) -> None:
1375
+ def _disconnect_reset_raise_on_watching(
1376
+ self,
1377
+ conn: AbstractConnection,
1378
+ error: Exception,
1379
+ ) -> None:
1350
1380
  """
1351
- Close the connection, reset watching state and
1352
- raise an exception if we were watching,
1353
- if retry_on_error is not set or the error is not one
1354
- of the specified error types.
1381
+ Close the connection reset watching state and
1382
+ raise an exception if we were watching.
1383
+
1384
+ The supported exceptions are already checked in the
1385
+ retry object so we don't need to do it here.
1386
+
1387
+ After we disconnect the connection, it will try to reconnect and
1388
+ do a health check as part of the send_command logic(on connection level).
1355
1389
  """
1356
1390
  conn.disconnect()
1391
+
1357
1392
  # if we were already watching a variable, the watch is no longer
1358
1393
  # valid since this connection has died. raise a WatchError, which
1359
1394
  # indicates the user should retry this transaction.
1360
1395
  if self.watching:
1361
1396
  self.reset()
1362
1397
  raise WatchError(
1363
- "A ConnectionError occurred on while watching one or more keys"
1398
+ f"A {type(error).__name__} occurred while watching one or more keys"
1364
1399
  )
1365
- # if retry_on_error is not set or the error is not one
1366
- # of the specified error types, raise it
1367
- if (
1368
- conn.retry_on_error is None
1369
- or isinstance(error, tuple(conn.retry_on_error)) is False
1370
- ):
1371
- self.reset()
1372
- raise
1373
1400
 
1374
1401
  def immediate_execute_command(self, *args, **options):
1375
1402
  """
1376
- Execute a command immediately, but don't auto-retry on a
1377
- ConnectionError if we're already WATCHing a variable. Used when
1378
- issuing WATCH or subsequent commands retrieving their values but before
1403
+ Execute a command immediately, but don't auto-retry on the supported
1404
+ errors for retry if we're already WATCHing a variable.
1405
+ Used when issuing WATCH or subsequent commands retrieving their values but before
1379
1406
  MULTI is called.
1380
1407
  """
1381
1408
  command_name = args[0]
1382
1409
  conn = self.connection
1383
1410
  # if this is the first call, we need a connection
1384
1411
  if not conn:
1385
- conn = self.connection_pool.get_connection(command_name, self.shard_hint)
1412
+ conn = self.connection_pool.get_connection()
1386
1413
  self.connection = conn
1387
1414
 
1388
1415
  return conn.retry.call_with_retry(
1389
1416
  lambda: self._send_command_parse_response(
1390
1417
  conn, command_name, *args, **options
1391
1418
  ),
1392
- lambda error: self._disconnect_reset_raise(conn, error),
1419
+ lambda error: self._disconnect_reset_raise_on_watching(conn, error),
1393
1420
  )
1394
1421
 
1395
1422
  def pipeline_execute_command(self, *args, **options) -> "Pipeline":
@@ -1501,7 +1528,7 @@ class Pipeline(Redis):
1501
1528
  def annotate_exception(self, exception, number, command):
1502
1529
  cmd = " ".join(map(safe_str, command))
1503
1530
  msg = (
1504
- f"Command # {number} ({cmd}) of pipeline "
1531
+ f"Command # {number} ({truncate_text(cmd)}) of pipeline "
1505
1532
  f"caused error: {exception.args[0]}"
1506
1533
  )
1507
1534
  exception.args = (msg,) + exception.args[1:]
@@ -1527,15 +1554,19 @@ class Pipeline(Redis):
1527
1554
  if not exist:
1528
1555
  s.sha = immediate("SCRIPT LOAD", s.script)
1529
1556
 
1530
- def _disconnect_raise_reset(
1557
+ def _disconnect_raise_on_watching(
1531
1558
  self,
1532
1559
  conn: AbstractConnection,
1533
1560
  error: Exception,
1534
1561
  ) -> None:
1535
1562
  """
1536
- Close the connection, raise an exception if we were watching,
1537
- and raise an exception if retry_on_error is not set or the
1538
- error is not one of the specified error types.
1563
+ Close the connection, raise an exception if we were watching.
1564
+
1565
+ The supported exceptions are already checked in the
1566
+ retry object so we don't need to do it here.
1567
+
1568
+ After we disconnect the connection, it will try to reconnect and
1569
+ do a health check as part of the send_command logic(on connection level).
1539
1570
  """
1540
1571
  conn.disconnect()
1541
1572
  # if we were watching a variable, the watch is no longer valid
@@ -1543,19 +1574,10 @@ class Pipeline(Redis):
1543
1574
  # indicates the user should retry this transaction.
1544
1575
  if self.watching:
1545
1576
  raise WatchError(
1546
- "A ConnectionError occurred on while watching one or more keys"
1577
+ f"A {type(error).__name__} occurred while watching one or more keys"
1547
1578
  )
1548
- # if retry_on_error is not set or the error is not one
1549
- # of the specified error types, raise it
1550
- if (
1551
- conn.retry_on_error is None
1552
- or isinstance(error, tuple(conn.retry_on_error)) is False
1553
- ):
1554
-
1555
- self.reset()
1556
- raise error
1557
1579
 
1558
- def execute(self, raise_on_error=True):
1580
+ def execute(self, raise_on_error: bool = True) -> List[Any]:
1559
1581
  """Execute all the commands in the current pipeline"""
1560
1582
  stack = self.command_stack
1561
1583
  if not stack and not self.watching:
@@ -1569,7 +1591,7 @@ class Pipeline(Redis):
1569
1591
 
1570
1592
  conn = self.connection
1571
1593
  if not conn:
1572
- conn = self.connection_pool.get_connection("MULTI", self.shard_hint)
1594
+ conn = self.connection_pool.get_connection()
1573
1595
  # assign to self.connection so reset() releases the connection
1574
1596
  # back to the pool after we're done
1575
1597
  self.connection = conn
@@ -1577,7 +1599,7 @@ class Pipeline(Redis):
1577
1599
  try:
1578
1600
  return conn.retry.call_with_retry(
1579
1601
  lambda: execute(conn, stack, raise_on_error),
1580
- lambda error: self._disconnect_raise_reset(conn, error),
1602
+ lambda error: self._disconnect_raise_on_watching(conn, error),
1581
1603
  )
1582
1604
  finally:
1583
1605
  self.reset()