-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert #2104, provide way to disable disconnects in read_response()
#2506
Revert #2104, provide way to disable disconnects in read_response()
#2506
Conversation
Codecov ReportPatch coverage:
📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more Additional details and impacted files@@ Coverage Diff @@
## master #2506 +/- ##
===========================================
- Coverage 92.29% 60.49% -31.81%
===========================================
Files 116 116
Lines 29890 29935 +45
===========================================
- Hits 27588 18110 -9478
- Misses 2302 11825 +9523
... and 73 files with indirect coverage changes Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
tests/test_asyncio/test_commands.py
Outdated
try: | ||
async with async_timeout.timeout(0.1): | ||
assert await task == "done" | ||
except asyncio.TimeoutError: | ||
task.cancel() | ||
await task |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a 2nd phase of the same test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure exactly what you're referring to. The 'helper´ gets interrupted, then does another request. The main function then sets out to wait for the 'helper' to finish. The timeout is there to ensure that we finish, even if the helper task hangs.
tests/test_commands.py
Outdated
print("start") | ||
|
||
def helper(): | ||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit - even though it's not the test itself, can replace with
try: | |
with pytest.raises(CancelledError): |
print("canc") | ||
pass # we got some BaseException. | ||
# if all is well, we can continue. | ||
r.set("status", "down") # should not hang |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this also exercise the "command expects int but got back str" scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. It excercises the originally reported scenario: A blocking wait is initiated, and even though a new command is sent on the channel, the server is still in blocking wait mode.
It is harder to interrupt a half-read response, although not impossible by using mocking. I can look into that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That scenario doesn't require half-read. It's an interrupt between send_command and parse_response:
send_command("EXISTS foo")
<interrupt>
send_command("GET foo")
parse_response() --> expected str, got int (from previous command)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a half-read test case.
""" | ||
print("start") | ||
|
||
def helper(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def helper(): | |
def helper() -> None: |
IIUC there's no way to get a retval from a thread, though you can pass a mutable object and use that to communicate.
In particular it might be that we need to marshal errors to avoid them being silently ignored? e.g. https://github.com/bjoluc/pytest-reraise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is relying on the thread actually finishing. There is no way to interrupt a hanging thread in python. If these tests fail, the test suite hangs. I'm open to suggestions on how to avoid that. I suppose that an old-school timeout can be added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, there is no type hinting in redis-py, not going to start adding that to unit tests :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I mostly just meant for you to remove the retval. No need to type-annotate, though I do notice that some stuff is type-annotated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, there is the odd type hinting, but It is not consistently applied. I guess people add it to help their dev tools with code completion.
Note that this is not enough to fix everything broken by #2104. At least the other callsites of |
I saw the other
but overall I'd think those would also do well to be consolidated under a single pattern |
Also, might be good to remove the |
Which one is that? |
tests/test_commands.py
Outdated
# blocking pop | ||
with patch.object( | ||
socket.socket, "recv_into", side_effect=CancelledError | ||
) as mock_recv: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
) as mock_recv: | |
): |
unless you use mock_recv
later
tests/test_commands.py
Outdated
def helper(): | ||
try: | ||
with pytest.raises(BaseException): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that unless you propagate exceptions from the thread to the test, we'd be unaware of this pytest.raises assertion failing.
Since you seem really determined to go down this route: You now disconnect on the outside for any exception. Are you sure this is correct? This will at least disconnect twice sometimes. And are there really no exceptions that should go through without disconnect? Since you are against rolling back #2104, you should denote the API change in the functions affected, because they now have a rather surprising API. If you succeed with #2510, that comment could change on the async response functions to explaining that if the Exception was a CancellationException, the connection is not undefined, but still holds the previous response. If it is another Exception like KeyboardInterrupt, the connection will still be broken. |
Do we agree that under all scenarios, interrupted
So expecting Arguments in favor of making
Maybe a side-note, but when interruption can happen at any point, as it is with |
Would it be easier to just roll back #2104? |
@tobymao no, because it was done for a reason |
# if all is well, we can continue. The following should not hang. | ||
await r.set("status", "down") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still tbd to validate that not only you don't "hang", but also that the next read response matches the command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, a separate test which continues an interrupted read seems proper.
Before #2104 this seemed to work quite well. |
You can't guarantee that |
In production, where this matters nobody is pressing Ctrl-C. And if they are, they should know not to press it twice if they want sensible shutdown. In the important scenario, like the one you explained before, the exception is raised by a framework. Obviously it should only raise a single one. |
Right, this needs to be BaseException (naked Ok, let's give this PR another whirl. |
This is incorrect. It it is only in the case of BaseExceptions that it is kept open, exceptions that are not handled or caught anywhere and typically result in an exit. (In async code, the TimeoutError does result in a (We could, if we wanted, create a different api which could be restarted when a Timeout has previously occurred.)
Fair point. Yes, a timeout on read_response really should mean that the application can retry, and that should be documented, I guess, if the opposite is already undocumented. Otherwise, in all APIs that I am familiar with, a |
Yes: "That was previously the case with all exceptions while reading a response". You extended the scope of the try-catch. Now, for example, any exception raised by a response callback will also disconnect the connection. That was not previously the case. |
Okay, I think it is simplest that I restore the original behaviour of connection.parse_response(), since there simply seem to be too many cases that rely on it. Even though none of them was caught by the test suite. I'll modify this PR so that the BaseException behaviour becomes optional. |
7dccb43
to
1985884
Compare
read_response()
redis/asyncio/connection.py
Outdated
# The send_packed_command api does not support re-trying a partially | ||
# sent message, so there is no point in keeping the connection open. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider: The lack of support is really RESP's (the wire protocol).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually no. You can keep the buffer of data (the message) around in a send buffer. the actual socket.send() message lets you know how much of this has been successfully delivered to underlying layers. So a re-triable API could, for example, accept a None
as the data, and then continue sending from where it left off, if it has a buffer in place. Consider this api:
def send_packed_command(message: Optional[str]):
""" Send the packed command, or, if None, a previous call must not have completed and the function will
will resume sending that data over the wire.
"""
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, on the Python side (e.g. in Connection
) we could choose to implement a write buffer and "continue where we left off". As I mentioned before, the problem with a write buffer would be the potential of flushing out a command that's stale from an app code's perspective.
What I'd rather see, is being able to, instead of flushing a command that can be stale, to send a short control sequence that would cancel a command that's half-written into the socket, turning it into a no-op. This is the feature that RESP protocol doesn't support.
So:
- Write buffer: Not an inherent limitation in Python, we simply don't want to do it because it's bad UX.
- Cancel a half-written command: Inherent limitation of RESP.
Hence the "problem" is RESP, not send_packed_command
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you are saying, but I'm not even thinking about the "cancel" of the command. That's something I've never seen and in my mind completely unnecessary. For that, you can simply disconnect. I'm primarily thinking about Timeouts, where the transmitting of the command over the wire times out, and you want to maybe do some housekeeping and then continue trying to send the rest of the command.
In the context of this PR, do you suggest that I change this comment somehow? Is it confusing? I always find that code comments help future contributors. A similar comment would have probably caused me to do my original PR differently :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I'm discussing how we phrase the comment :) I think I understand now.
My perspective:
I called send
and caught an exception. Next time I call send
, it might be a different command, at a different time, on a different thread. I wouldn't want send_packed_command
to flush my previous command at an arbitrary time in the future. I would settle for flushing a short "cancel sequence" instead, but RESP doesn't support that, so instead I'd like it to disconnect.
From that perspective, it's a RESP limitation.
Your perspective:
I called send
and caught an exception. Now I want to retry immediately, but send_packed_command
didn't tell me where it stopped nor allows me to resume half-way.
From that perspective, it's a send_packed_command
limitation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I understand. Let me try to formulate the comment better.
redis/asyncio/connection.py
Outdated
except BaseException: | ||
# The send_packed_command api does not support re-trying a partially | ||
# sent message, so there is no point in keeping the connection open. | ||
# An unknown number of bytes has been sent and the connection is therefore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if you knew how many bytes were sent (I think you can know), the problem is you can't "take them back".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not about "taking them back", its about "trying again to send the rest". This could (theoretically) be done in case of a timeout, and is the way that many socket.sendall()
implementations work. (the underlying socket.send()
sends a potential subset of the data and needs to be retried.)
send_packed_api() could be architected in a similar way, but maintain an internal buffer of unsent data so that it can be re-tried.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But of course it's not reasonable to flush a command after an arbitrary delay (could be milliseconds, could be days). The "workaround" supported by RESP is not reasonable for what Redis is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand what you mean. All I'm saying is that sometimes your send()
can time out, for various reasons, buffers, server responsiveness, or whatever. It's technically possible to engineer things such that you can at least be sure that you've delivered all of your payload down to the OS to deliver over the wire. What happens after that is anyone's guess. Typically, then, you'd listen for the response, and time out in the listening phase if nothing happens.
This is in no way dissimilar to http, and doesn't have anything to do with RESP as such.
Anyway, I thought I'd comment on that, a different API, allowing one to retry a partially completed send()
operation, could mean that it would make sense to keep the connection open. But the current API has no semantics that woudl allow a "retry".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, see the above discussion :)
@kristjanvalur I see the green passes. Ready for a review? |
Yes, this has been ready for a long time. The non-green are the spurious failures that the test suite has. |
@chayim Can you review this? |
I'm investigating the test failure. |
This is new behaviour with the 3.11 timeout context manager. It doesn't work if there has been a previous cancel on the task. |
Oh dear. Now it is hanging because it is no longer possible to cancel an operation, due to this code: return await asyncio.shield(
self._try_send_command_parse_response(conn, *args, **options)
) in client.py. |
This happened in pr #2666 |
This issue is your white whale. I'm sorry :) but thanks for the efforts. |
Oh my. This here PR actually fixes all the other problems, including #2624 and is a much simpler and cleaner fix than the change from #2666 and related commits. I have started a new pr, #2695 , to move this forward and undo those other changes. It would have saved a lot of trouble if I had been pinged about those other issues, I could have pointed to this PR which has been lingering for months. |
Closed this now that #2695 has been merged (a re-creation of this PR) |
Bumps [redis](https://github.com/redis/redis-py) from 4.6.0 to 5.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/releases">redis's releases</a>.</em></p> <blockquote> <h2>5.0.0</h2> <h2>What's new?</h2> <h3>Triggers and Functions support</h3> <p>Triggers and Functions allow you to execute server-side functions triggered when key values are modified or created in Redis, a stream entry arrival, or explicitly calling them. Simply put, you can replace Lua scripts with easy-to-develop JavaScript or TypeScript code. Move your business logic closer to the data to ensure a lower latency, and forget about updating dependent key values manually in your code. <a href="https://redis.io/docs/interact/programmability/triggers-and-functions/quick_start/">Try it for yourself with Quick start</a></p> <h3>Full Redis 7.2 and <a href="https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md">RESP3 support</a></h3> <h3>Python 3.7 End-of-Life</h3> <p><a href="https://devguide.python.org/versions/">Python 3.7 has reached its end-of-life (EOL) as of June 2023</a>. This means that starting from this date, Python 3.7 will no longer receive any updates, including security patches, bug fixes, or improvements. If you continue to use Python 3.7 post-EOL, you may expose your projects and systems to potential security vulnerabilities. We ended its support in this version and strongly recommend migrating to Python 3.10.</p> <h2>🐛 Bug Fixes</h2> <ul> <li>Fix timeout retrying on pipeline execution (<a href="https://github.com/redis/redis-py/issues/2812">#2812</a>)</li> <li>Fix socket garbage collection (<a href="https://github.com/redis/redis-py/issues/2859">#2859</a>)</li> </ul> <h2>🧰 Maintenance</h2> <ul> <li>Updating client license to clear, MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li>Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li>Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li>Fix type hints in SearchCommands (<a href="https://github.com/redis/redis-py/issues/2817">#2817</a>)</li> <li>Add sync modules (except search) tests to cluster CI (<a href="https://github.com/redis/redis-py/issues/2850">#2850</a>)</li> <li>Fix a duplicate word in <code>CONTRIBUTING.md</code> (<a href="https://github.com/redis/redis-py/issues/2848">#2848</a>)</li> <li>Fixing doc builds (<a href="https://github.com/redis/redis-py/issues/2869">#2869</a>)</li> <li>Change cluster docker to edge and enable debug command (<a href="https://github.com/redis/redis-py/issues/2853">#2853</a>)</li> </ul> <h2>Contributors</h2> <p>We'd like to thank all the contributors who worked on this release!</p> <p><a href="https://github.com/JoanFM"><code>@JoanFM</code></a>, <a href="https://github.com/Ovsyanka83"><code>@Ovsyanka83</code></a>, <a href="https://github.com/chayim"><code>@chayim</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/dvora-h"><code>@dvora-h</code></a>, <a href="https://github.com/kristjanvalur"><code>@kristjanvalur</code></a>, <a href="https://github.com/kurtmckee"><code>@kurtmckee</code></a>, <a href="https://github.com/pall-j"><code>@pall-j</code></a> and <a href="https://github.com/shacharPash"><code>@shacharPash</code></a></p> <h2>5.0.0rc2</h2> <h2>Changes</h2> <h2>🧰 Maintenance</h2> <ul> <li>RESP3 response-callbacks cleanup (<a href="https://github.com/redis/redis-py/issues/2841">#2841</a>)</li> <li>Merge master to 5.0 (<a href="https://github.com/redis/redis-py/issues/2827">#2827</a>)</li> </ul> <h2>5.0.0rc1</h2> <h2>Changes</h2> <h2>🔥 Breaking Changes</h2> <ul> <li>Change <code>SISMEMBER</code> return type to int by (<a href="https://github.com/redis/redis-py/issues/2813">#2813</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/blob/master/CHANGES">redis's changelog</a>.</em></p> <blockquote> <pre><code>* Fix [#2831](redis/redis-py#2831), add auto_close_connection_pool=True arg to asyncio.Redis.from_url() * Fix incorrect redis.asyncio.Cluster type hint for `retry_on_error` * Fix dead weakref in sentinel connection causing ReferenceError ([#2767](redis/redis-py#2767)) * Fix [#2768](redis/redis-py#2768), Fix KeyError: 'first-entry' in parse_xinfo_stream. * Fix [#2749](redis/redis-py#2749), remove unnecessary __del__ logic to close connections. * Fix [#2754](redis/redis-py#2754), adding a missing argument to SentinelManagedConnection * Fix `xadd` command to accept non-negative `maxlen` including 0 * Revert [#2104](redis/redis-py#2104), [#2673](redis/redis-py#2673), add `disconnect_on_error` option to `read_response()` (issues [#2506](redis/redis-py#2506), [#2624](redis/redis-py#2624)) * Add `address_remap` parameter to `RedisCluster` * Fix incorrect usage of once flag in async Sentinel * asyncio: Fix memory leak caused by hiredis ([#2693](redis/redis-py#2693)) * Allow data to drain from async PythonParser when reading during a disconnect() * Use asyncio.timeout() instead of async_timeout.timeout() for python >= 3.11 ([#2602](redis/redis-py#2602)) * Add a Dependabot configuration to auto-update GitHub action versions. * Add test and fix async HiredisParser when reading during a disconnect() ([#2349](redis/redis-py#2349)) * Use hiredis-py pack_command if available. * Support `.unlink()` in ClusterPipeline * Simplify synchronous SocketBuffer state management * Fix string cleanse in Redis Graph * Make PythonParser resumable in case of error ([#2510](redis/redis-py#2510)) * Add `timeout=None` in `SentinelConnectionManager.read_response` * Documentation fix: password protected socket connection ([#2374](redis/redis-py#2374)) * Allow `timeout=None` in `PubSub.get_message()` to wait forever * add `nowait` flag to `asyncio.Connection.disconnect()` * Update README.md links * Fix timezone handling for datetime to unixtime conversions * Fix start_id type for XAUTOCLAIM * Remove verbose logging from cluster.py * Add retry mechanism to async version of Connection * Compare commands case-insensitively in the asyncio command parser * Allow negative `retries` for `Retry` class to retry forever * Add `items` parameter to `hset` signature * Create codeql-analysis.yml ([#1988](redis/redis-py#1988)). Thanks @chayim * Add limited support for Lua scripting with RedisCluster * Implement `.lock()` method on RedisCluster * Fix cursor returned by SCAN for RedisCluster & change default target to PRIMARIES * Fix scan_iter for RedisCluster * Remove verbose logging when initializing ClusterPubSub, ClusterPipeline or RedisCluster * Fix broken connection writer lock-up for asyncio ([#2065](redis/redis-py#2065)) * Fix auth bug when provided with no username ([#2086](redis/redis-py#2086)) * Fix missing ClusterPipeline._lock ([#2189](redis/redis-py#2189)) * Added dynaminc_startup_nodes configuration to RedisCluster * Fix reusing the old nodes' connections when cluster topology refresh is being done * Fix RedisCluster to immediately raise AuthenticationError without a retry * ClusterPipeline Doesn't Handle ConnectionError for Dead Hosts ([#2225](redis/redis-py#2225)) * Remove compatibility code for old versions of Hiredis, drop Packaging dependency * The `deprecated` library is no longer a dependency * Failover handling improvements for RedisCluster and Async RedisCluster ([#2377](redis/redis-py#2377)) * Fixed "cannot pickle '_thread.lock' object" bug ([#2354](redis/redis-py#2354), [#2297](redis/redis-py#2297)) * Added CredentialsProvider class to support password rotation </code></pre> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/redis/redis-py/commit/28cc65c18cc4fb37ef14497c963eb181dba8d25d"><code>28cc65c</code></a> Updating all client licenses to clearly be MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/2f679261b7ef0e7372868cacd8ba8721406eb495"><code>2f67926</code></a> Version 5.0.0 (<a href="https://github.com/redis/redis-py/issues/2874">#2874</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/f121cf29e7d7fb5c85c5915ba5ce10a20826e8c0"><code>f121cf2</code></a> Add support for <code>CLIENT SETINFO</code> (<a href="https://github.com/redis/redis-py/issues/2857">#2857</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/d5c2d1d42ed9f653d450e6127cb6f673f43fb2d0"><code>d5c2d1d</code></a> Adding support for triggered functions (TFUNCTION) (<a href="https://github.com/redis/redis-py/issues/2861">#2861</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/b0abd555770bba42c57881b488b5fe5b188f088e"><code>b0abd55</code></a> RESP 3 feature documentation (<a href="https://github.com/redis/redis-py/issues/2872">#2872</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/a532f89adcd5b790e2811588a2d7c34a79b095d5"><code>a532f89</code></a> Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/673617d2cbac265c6c8d43280d5e6898df4572b6"><code>673617d</code></a> Bump actions/upload-artifact from 2 to 3 (<a href="https://github.com/redis/redis-py/issues/2877">#2877</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/0ed807777cfab129904fd72fbada793f21ea0a9c"><code>0ed8077</code></a> Bump pypa/gh-action-pip-audit from 1.0.0 to 1.0.8 (<a href="https://github.com/redis/redis-py/issues/2879">#2879</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/38c7de617a482c9dd2d40699fbdd7ce44736cae9"><code>38c7de6</code></a> Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/8370c4ac20835002fd1044e1742986072f19289c"><code>8370c4a</code></a> Add a Dependabot config to auto-update GitHub action versions (<a href="https://github.com/redis/redis-py/issues/2847">#2847</a>)</li> <li>Additional commits viewable in <a href="https://github.com/redis/redis-py/compare/v4.6.0...v5.0.0">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=redis&package-manager=pip&previous-version=4.6.0&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [redis](https://github.com/redis/redis-py) from 4.5.4 to 5.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/releases">redis's releases</a>.</em></p> <blockquote> <h2>5.0.0</h2> <h2>What's new?</h2> <h3>Triggers and Functions support</h3> <p>Triggers and Functions allow you to execute server-side functions triggered when key values are modified or created in Redis, a stream entry arrival, or explicitly calling them. Simply put, you can replace Lua scripts with easy-to-develop JavaScript or TypeScript code. Move your business logic closer to the data to ensure a lower latency, and forget about updating dependent key values manually in your code. <a href="https://redis.io/docs/interact/programmability/triggers-and-functions/quick_start/">Try it for yourself with Quick start</a></p> <h3>Full <a href="https://redis.com/blog/introducing-redis-7-2/">Redis 7.2</a> and <a href="https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md">RESP3 support</a></h3> <h3>Python 3.7 End-of-Life</h3> <p><a href="https://devguide.python.org/versions/">Python 3.7 has reached its end-of-life (EOL) as of June 2023</a>. This means that starting from this date, Python 3.7 will no longer receive any updates, including security patches, bug fixes, or improvements. If you continue to use Python 3.7 post-EOL, you may expose your projects and systems to potential security vulnerabilities. We ended its support in this version and strongly recommend migrating to Python 3.10.</p> <h2>🐛 Bug Fixes</h2> <ul> <li>Fix timeout retrying on pipeline execution (<a href="https://github.com/redis/redis-py/issues/2812">#2812</a>)</li> <li>Fix socket garbage collection (<a href="https://github.com/redis/redis-py/issues/2859">#2859</a>)</li> </ul> <h2>🧰 Maintenance</h2> <ul> <li>Updating client license to clear, MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li>Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li>Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li>Fix type hints in SearchCommands (<a href="https://github.com/redis/redis-py/issues/2817">#2817</a>)</li> <li>Add sync modules (except search) tests to cluster CI (<a href="https://github.com/redis/redis-py/issues/2850">#2850</a>)</li> <li>Fix a duplicate word in <code>CONTRIBUTING.md</code> (<a href="https://github.com/redis/redis-py/issues/2848">#2848</a>)</li> <li>Fixing doc builds (<a href="https://github.com/redis/redis-py/issues/2869">#2869</a>)</li> <li>Change cluster docker to edge and enable debug command (<a href="https://github.com/redis/redis-py/issues/2853">#2853</a>)</li> </ul> <h2>Contributors</h2> <p>We'd like to thank all the contributors who worked on this release!</p> <p><a href="https://github.com/JoanFM"><code>@JoanFM</code></a>, <a href="https://github.com/Ovsyanka83"><code>@Ovsyanka83</code></a>, <a href="https://github.com/chayim"><code>@chayim</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/dvora-h"><code>@dvora-h</code></a>, <a href="https://github.com/kristjanvalur"><code>@kristjanvalur</code></a>, <a href="https://github.com/kurtmckee"><code>@kurtmckee</code></a>, <a href="https://github.com/pall-j"><code>@pall-j</code></a> and <a href="https://github.com/shacharPash"><code>@shacharPash</code></a></p> <h2>5.0.0rc2</h2> <h2>Changes</h2> <h2>🧰 Maintenance</h2> <ul> <li>RESP3 response-callbacks cleanup (<a href="https://github.com/redis/redis-py/issues/2841">#2841</a>)</li> <li>Merge master to 5.0 (<a href="https://github.com/redis/redis-py/issues/2827">#2827</a>)</li> </ul> <h2>5.0.0rc1</h2> <h2>Changes</h2> <h2>🔥 Breaking Changes</h2> <ul> <li>Change <code>SISMEMBER</code> return type to int by (<a href="https://github.com/redis/redis-py/issues/2813">#2813</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/blob/master/CHANGES">redis's changelog</a>.</em></p> <blockquote> <pre><code>* Fix [#2831](redis/redis-py#2831), add auto_close_connection_pool=True arg to asyncio.Redis.from_url() * Fix incorrect redis.asyncio.Cluster type hint for `retry_on_error` * Fix dead weakref in sentinel connection causing ReferenceError ([#2767](redis/redis-py#2767)) * Fix [#2768](redis/redis-py#2768), Fix KeyError: 'first-entry' in parse_xinfo_stream. * Fix [#2749](redis/redis-py#2749), remove unnecessary __del__ logic to close connections. * Fix [#2754](redis/redis-py#2754), adding a missing argument to SentinelManagedConnection * Fix `xadd` command to accept non-negative `maxlen` including 0 * Revert [#2104](redis/redis-py#2104), [#2673](redis/redis-py#2673), add `disconnect_on_error` option to `read_response()` (issues [#2506](redis/redis-py#2506), [#2624](redis/redis-py#2624)) * Add `address_remap` parameter to `RedisCluster` * Fix incorrect usage of once flag in async Sentinel * asyncio: Fix memory leak caused by hiredis ([#2693](redis/redis-py#2693)) * Allow data to drain from async PythonParser when reading during a disconnect() * Use asyncio.timeout() instead of async_timeout.timeout() for python >= 3.11 ([#2602](redis/redis-py#2602)) * Add a Dependabot configuration to auto-update GitHub action versions. * Add test and fix async HiredisParser when reading during a disconnect() ([#2349](redis/redis-py#2349)) * Use hiredis-py pack_command if available. * Support `.unlink()` in ClusterPipeline * Simplify synchronous SocketBuffer state management * Fix string cleanse in Redis Graph * Make PythonParser resumable in case of error ([#2510](redis/redis-py#2510)) * Add `timeout=None` in `SentinelConnectionManager.read_response` * Documentation fix: password protected socket connection ([#2374](redis/redis-py#2374)) * Allow `timeout=None` in `PubSub.get_message()` to wait forever * add `nowait` flag to `asyncio.Connection.disconnect()` * Update README.md links * Fix timezone handling for datetime to unixtime conversions * Fix start_id type for XAUTOCLAIM * Remove verbose logging from cluster.py * Add retry mechanism to async version of Connection * Compare commands case-insensitively in the asyncio command parser * Allow negative `retries` for `Retry` class to retry forever * Add `items` parameter to `hset` signature * Create codeql-analysis.yml ([#1988](redis/redis-py#1988)). Thanks @chayim * Add limited support for Lua scripting with RedisCluster * Implement `.lock()` method on RedisCluster * Fix cursor returned by SCAN for RedisCluster & change default target to PRIMARIES * Fix scan_iter for RedisCluster * Remove verbose logging when initializing ClusterPubSub, ClusterPipeline or RedisCluster * Fix broken connection writer lock-up for asyncio ([#2065](redis/redis-py#2065)) * Fix auth bug when provided with no username ([#2086](redis/redis-py#2086)) * Fix missing ClusterPipeline._lock ([#2189](redis/redis-py#2189)) * Added dynaminc_startup_nodes configuration to RedisCluster * Fix reusing the old nodes' connections when cluster topology refresh is being done * Fix RedisCluster to immediately raise AuthenticationError without a retry * ClusterPipeline Doesn't Handle ConnectionError for Dead Hosts ([#2225](redis/redis-py#2225)) * Remove compatibility code for old versions of Hiredis, drop Packaging dependency * The `deprecated` library is no longer a dependency * Failover handling improvements for RedisCluster and Async RedisCluster ([#2377](redis/redis-py#2377)) * Fixed "cannot pickle '_thread.lock' object" bug ([#2354](redis/redis-py#2354), [#2297](redis/redis-py#2297)) * Added CredentialsProvider class to support password rotation </code></pre> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/redis/redis-py/commit/28cc65c18cc4fb37ef14497c963eb181dba8d25d"><code>28cc65c</code></a> Updating all client licenses to clearly be MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/2f679261b7ef0e7372868cacd8ba8721406eb495"><code>2f67926</code></a> Version 5.0.0 (<a href="https://github.com/redis/redis-py/issues/2874">#2874</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/f121cf29e7d7fb5c85c5915ba5ce10a20826e8c0"><code>f121cf2</code></a> Add support for <code>CLIENT SETINFO</code> (<a href="https://github.com/redis/redis-py/issues/2857">#2857</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/d5c2d1d42ed9f653d450e6127cb6f673f43fb2d0"><code>d5c2d1d</code></a> Adding support for triggered functions (TFUNCTION) (<a href="https://github.com/redis/redis-py/issues/2861">#2861</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/b0abd555770bba42c57881b488b5fe5b188f088e"><code>b0abd55</code></a> RESP 3 feature documentation (<a href="https://github.com/redis/redis-py/issues/2872">#2872</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/a532f89adcd5b790e2811588a2d7c34a79b095d5"><code>a532f89</code></a> Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/673617d2cbac265c6c8d43280d5e6898df4572b6"><code>673617d</code></a> Bump actions/upload-artifact from 2 to 3 (<a href="https://github.com/redis/redis-py/issues/2877">#2877</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/0ed807777cfab129904fd72fbada793f21ea0a9c"><code>0ed8077</code></a> Bump pypa/gh-action-pip-audit from 1.0.0 to 1.0.8 (<a href="https://github.com/redis/redis-py/issues/2879">#2879</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/38c7de617a482c9dd2d40699fbdd7ce44736cae9"><code>38c7de6</code></a> Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/8370c4ac20835002fd1044e1742986072f19289c"><code>8370c4a</code></a> Add a Dependabot config to auto-update GitHub action versions (<a href="https://github.com/redis/redis-py/issues/2847">#2847</a>)</li> <li>Additional commits viewable in <a href="https://github.com/redis/redis-py/compare/v4.5.4...v5.0.0">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=redis&package-manager=pip&previous-version=4.5.4&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [redis](https://github.com/redis/redis-py) from 4.6.0 to 5.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/releases">redis's releases</a>.</em></p> <blockquote> <h2>5.0.0</h2> <h2>What's new?</h2> <h3>Triggers and Functions support</h3> <p>Triggers and Functions allow you to execute server-side functions triggered when key values are modified or created in Redis, a stream entry arrival, or explicitly calling them. Simply put, you can replace Lua scripts with easy-to-develop JavaScript or TypeScript code. Move your business logic closer to the data to ensure a lower latency, and forget about updating dependent key values manually in your code. <a href="https://redis.io/docs/interact/programmability/triggers-and-functions/quick_start/">Try it for yourself with Quick start</a></p> <h3>Full <a href="https://redis.com/blog/introducing-redis-7-2/">Redis 7.2</a> and <a href="https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md">RESP3 support</a></h3> <h3>Python 3.7 End-of-Life</h3> <p><a href="https://devguide.python.org/versions/">Python 3.7 has reached its end-of-life (EOL) as of June 2023</a>. This means that starting from this date, Python 3.7 will no longer receive any updates, including security patches, bug fixes, or improvements. If you continue to use Python 3.7 post-EOL, you may expose your projects and systems to potential security vulnerabilities. We ended its support in this version and strongly recommend migrating to Python 3.10.</p> <h2>🐛 Bug Fixes</h2> <ul> <li>Fix timeout retrying on pipeline execution (<a href="https://github.com/redis/redis-py/issues/2812">#2812</a>)</li> <li>Fix socket garbage collection (<a href="https://github.com/redis/redis-py/issues/2859">#2859</a>)</li> </ul> <h2>🧰 Maintenance</h2> <ul> <li>Updating client license to clear, MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li>Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li>Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li>Fix type hints in SearchCommands (<a href="https://github.com/redis/redis-py/issues/2817">#2817</a>)</li> <li>Add sync modules (except search) tests to cluster CI (<a href="https://github.com/redis/redis-py/issues/2850">#2850</a>)</li> <li>Fix a duplicate word in <code>CONTRIBUTING.md</code> (<a href="https://github.com/redis/redis-py/issues/2848">#2848</a>)</li> <li>Fixing doc builds (<a href="https://github.com/redis/redis-py/issues/2869">#2869</a>)</li> <li>Change cluster docker to edge and enable debug command (<a href="https://github.com/redis/redis-py/issues/2853">#2853</a>)</li> </ul> <h2>Contributors</h2> <p>We'd like to thank all the contributors who worked on this release!</p> <p><a href="https://github.com/JoanFM"><code>@JoanFM</code></a>, <a href="https://github.com/Ovsyanka83"><code>@Ovsyanka83</code></a>, <a href="https://github.com/chayim"><code>@chayim</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>, <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot], <a href="https://github.com/dvora-h"><code>@dvora-h</code></a>, <a href="https://github.com/kristjanvalur"><code>@kristjanvalur</code></a>, <a href="https://github.com/kurtmckee"><code>@kurtmckee</code></a>, <a href="https://github.com/pall-j"><code>@pall-j</code></a> and <a href="https://github.com/shacharPash"><code>@shacharPash</code></a></p> <h2>5.0.0rc2</h2> <h2>Changes</h2> <h2>🧰 Maintenance</h2> <ul> <li>RESP3 response-callbacks cleanup (<a href="https://github.com/redis/redis-py/issues/2841">#2841</a>)</li> <li>Merge master to 5.0 (<a href="https://github.com/redis/redis-py/issues/2827">#2827</a>)</li> </ul> <h2>5.0.0rc1</h2> <h2>Changes</h2> <h2>🔥 Breaking Changes</h2> <ul> <li>Change <code>SISMEMBER</code> return type to int by (<a href="https://github.com/redis/redis-py/issues/2813">#2813</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/redis/redis-py/blob/master/CHANGES">redis's changelog</a>.</em></p> <blockquote> <pre><code>* Fix [#2831](redis/redis-py#2831), add auto_close_connection_pool=True arg to asyncio.Redis.from_url() * Fix incorrect redis.asyncio.Cluster type hint for `retry_on_error` * Fix dead weakref in sentinel connection causing ReferenceError ([#2767](redis/redis-py#2767)) * Fix [#2768](redis/redis-py#2768), Fix KeyError: 'first-entry' in parse_xinfo_stream. * Fix [#2749](redis/redis-py#2749), remove unnecessary __del__ logic to close connections. * Fix [#2754](redis/redis-py#2754), adding a missing argument to SentinelManagedConnection * Fix `xadd` command to accept non-negative `maxlen` including 0 * Revert [#2104](redis/redis-py#2104), [#2673](redis/redis-py#2673), add `disconnect_on_error` option to `read_response()` (issues [#2506](redis/redis-py#2506), [#2624](redis/redis-py#2624)) * Add `address_remap` parameter to `RedisCluster` * Fix incorrect usage of once flag in async Sentinel * asyncio: Fix memory leak caused by hiredis ([#2693](redis/redis-py#2693)) * Allow data to drain from async PythonParser when reading during a disconnect() * Use asyncio.timeout() instead of async_timeout.timeout() for python >= 3.11 ([#2602](redis/redis-py#2602)) * Add a Dependabot configuration to auto-update GitHub action versions. * Add test and fix async HiredisParser when reading during a disconnect() ([#2349](redis/redis-py#2349)) * Use hiredis-py pack_command if available. * Support `.unlink()` in ClusterPipeline * Simplify synchronous SocketBuffer state management * Fix string cleanse in Redis Graph * Make PythonParser resumable in case of error ([#2510](redis/redis-py#2510)) * Add `timeout=None` in `SentinelConnectionManager.read_response` * Documentation fix: password protected socket connection ([#2374](redis/redis-py#2374)) * Allow `timeout=None` in `PubSub.get_message()` to wait forever * add `nowait` flag to `asyncio.Connection.disconnect()` * Update README.md links * Fix timezone handling for datetime to unixtime conversions * Fix start_id type for XAUTOCLAIM * Remove verbose logging from cluster.py * Add retry mechanism to async version of Connection * Compare commands case-insensitively in the asyncio command parser * Allow negative `retries` for `Retry` class to retry forever * Add `items` parameter to `hset` signature * Create codeql-analysis.yml ([#1988](redis/redis-py#1988)). Thanks @chayim * Add limited support for Lua scripting with RedisCluster * Implement `.lock()` method on RedisCluster * Fix cursor returned by SCAN for RedisCluster & change default target to PRIMARIES * Fix scan_iter for RedisCluster * Remove verbose logging when initializing ClusterPubSub, ClusterPipeline or RedisCluster * Fix broken connection writer lock-up for asyncio ([#2065](redis/redis-py#2065)) * Fix auth bug when provided with no username ([#2086](redis/redis-py#2086)) * Fix missing ClusterPipeline._lock ([#2189](redis/redis-py#2189)) * Added dynaminc_startup_nodes configuration to RedisCluster * Fix reusing the old nodes' connections when cluster topology refresh is being done * Fix RedisCluster to immediately raise AuthenticationError without a retry * ClusterPipeline Doesn't Handle ConnectionError for Dead Hosts ([#2225](redis/redis-py#2225)) * Remove compatibility code for old versions of Hiredis, drop Packaging dependency * The `deprecated` library is no longer a dependency * Failover handling improvements for RedisCluster and Async RedisCluster ([#2377](redis/redis-py#2377)) * Fixed "cannot pickle '_thread.lock' object" bug ([#2354](redis/redis-py#2354), [#2297](redis/redis-py#2297)) * Added CredentialsProvider class to support password rotation </code></pre> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/redis/redis-py/commit/28cc65c18cc4fb37ef14497c963eb181dba8d25d"><code>28cc65c</code></a> Updating all client licenses to clearly be MIT (<a href="https://github.com/redis/redis-py/issues/2884">#2884</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/2f679261b7ef0e7372868cacd8ba8721406eb495"><code>2f67926</code></a> Version 5.0.0 (<a href="https://github.com/redis/redis-py/issues/2874">#2874</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/f121cf29e7d7fb5c85c5915ba5ce10a20826e8c0"><code>f121cf2</code></a> Add support for <code>CLIENT SETINFO</code> (<a href="https://github.com/redis/redis-py/issues/2857">#2857</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/d5c2d1d42ed9f653d450e6127cb6f673f43fb2d0"><code>d5c2d1d</code></a> Adding support for triggered functions (TFUNCTION) (<a href="https://github.com/redis/redis-py/issues/2861">#2861</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/b0abd555770bba42c57881b488b5fe5b188f088e"><code>b0abd55</code></a> RESP 3 feature documentation (<a href="https://github.com/redis/redis-py/issues/2872">#2872</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/a532f89adcd5b790e2811588a2d7c34a79b095d5"><code>a532f89</code></a> Add py.typed in accordance with PEP-561 (<a href="https://github.com/redis/redis-py/issues/2738">#2738</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/673617d2cbac265c6c8d43280d5e6898df4572b6"><code>673617d</code></a> Bump actions/upload-artifact from 2 to 3 (<a href="https://github.com/redis/redis-py/issues/2877">#2877</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/0ed807777cfab129904fd72fbada793f21ea0a9c"><code>0ed8077</code></a> Bump pypa/gh-action-pip-audit from 1.0.0 to 1.0.8 (<a href="https://github.com/redis/redis-py/issues/2879">#2879</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/38c7de617a482c9dd2d40699fbdd7ce44736cae9"><code>38c7de6</code></a> Dependabot label change (<a href="https://github.com/redis/redis-py/issues/2880">#2880</a>)</li> <li><a href="https://github.com/redis/redis-py/commit/8370c4ac20835002fd1044e1742986072f19289c"><code>8370c4a</code></a> Add a Dependabot config to auto-update GitHub action versions (<a href="https://github.com/redis/redis-py/issues/2847">#2847</a>)</li> <li>Additional commits viewable in <a href="https://github.com/redis/redis-py/compare/v4.6.0...v5.0.0">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=redis&package-manager=pip&previous-version=4.6.0&new-version=5.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Pull Request check-list
Please make sure to review and check all of these items:
$ tox
pass with this change (including linting)?NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.
Description of change
PR #2104, a fix to #2103 caused a regression for issue #1128. This has been dicussed in issue #2499.
This PR provides
Exception
and notBaseException
in theConnection
#2104, along with comments in the codeConnection.read_response()
A lot of code uses the Command/Response pattern and if an exception occurs during that, the conneciton is in an
indeterminate state:
Connection.send_command()
has no way to continue sending a command if there is a benign interrupt, e.g. a Timeout. Ensuring that the connection is closed in this case is prudent, because some code does capture BaseExceptions, e.g.gevent
style code.send_command()
andread_response()
and even if the error happens inread_response()
(which is in principle resumable), application code has no way of knowing and so closing the connection is necessary.To support
PubSub
, and other cases where an application may want to properly handle Timeouts and other errors while reading reponses, a new argument is added toread_response()
, which disables the automaticdisconnect()
of the connection when an exception is occurred. It is then the responsibility of the caller to take appropriate action.