fix(redis): unwrap decorated __init__s when deriving the from_url kwargs allowlist - #36654
Merged
yassin-berriai merged 4 commits intoAug 15, 2026
Conversation
chore(ci): promote internal staging to main
chore(ci): promote internal staging to main
chore(ci): promote internal staging to main
…rgs allowlist redis-py >= 7.4 decorates AbstractConnection.__init__ with @deprecated_args, whose wrapper is declared (self, *args, **kwargs). _init_arg_names introspects the wrapper directly, so from redis-py 7.4 the MRO walk loses every real connection parameter and the from_url allowlist silently drops socket_timeout and socket_connect_timeout again - the exact regression the allowlist rework fixed, reintroduced one dependency version later. A url-configured Redis that blackholes packets then blocks callers indefinitely instead of timing out. Follow the __wrapped__ chain with inspect.unwrap before introspecting; a no-op for undecorated __init__s. Measured across redis-py lines (socket_timeout present in the allowlist): 6.4.0 before/after: yes/yes. 7.1.0: yes/yes. 7.4.1: NO/yes. 8.1.0: NO/yes. tests/test_litellm/test_redis.py at redis-py 8.1.0: 10 failures before, 3 after (the residual trio is sentinel/cluster password handling, failing identically without this change). Two tests: a decorated-fake proving the unwrap mechanism, and a live-invariant assertion that the installed redis-py's allowlist carries the socket timeouts - the first thing to go red if a future redis-py changes signature declaration again.
Contributor
Greptile SummaryThis PR unwraps decorated Redis connection initializers before deriving URL-compatible keyword arguments, restoring socket timeout forwarding with newer redis-py releases
Confidence Score: 5/5The PR appears safe to merge, with no concrete changed-code failure identified The unwrap operation preserves undecorated behavior while recovering wrapped initializer signatures, and the new tests cover both the mechanism and resulting timeout allowlist
|
| Filename | Overview |
|---|---|
| litellm/_redis.py | Correctly unwraps decorated Redis initializer functions before collecting accepted positional and keyword-only parameters |
| tests/test_litellm/test_redis.py | Adds focused regression coverage without initiating Redis network traffic |
Reviews (1): Last reviewed commit: "fix(redis): unwrap decorated __init__s w..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Contributor
yassin-berriai
approved these changes
Aug 15, 2026
yassin-berriai
merged commit Aug 15, 2026
592564d
into
BerriAI:litellm_internal_staging
78 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The regression
redis-py >= 7.4 decorates
AbstractConnection.__init__with@deprecated_args(redis/utils.py), whose wrapper is declared(self, *args, **kwargs)._init_arg_namesintrospects the wrapper directly, so from redis-py 7.4 the MRO walk loses every real connection parameter and thefrom_urlallowlist silently dropssocket_timeout/socket_connect_timeoutagain — the exact regression the allowlist rework (#35273) fixed, reintroduced one dependency version later from the other side. A url-configured Redis that blackholes packets (NetworkPolicy misconfig) then blocks callers indefinitely instead of timing out.The fix
Follow the
__wrapped__chain withinspect.unwrapbefore introspecting each__init__.@deprecated_argsusesfunctools.wraps, so the chain leads to the true signature; unwrap is a no-op for undecorated__init__s.Measured (socket_timeout present in the derived allowlist, before -> after)
tests/test_litellm/test_redis.pyat redis-py 8.1.0: 10 failures before, 3 after — the residual trio (sentinel/cluster password handling) fails identically without this change and at 6.4.0, so it is unrelated. At 6.4.0 the module result is unchanged by this PR.Tests added
test_init_arg_names_sees_through_decorated_inits— decorated-fake class proving the unwrap mechanism without depending on the installed redis-py.test_url_allowlist_always_carries_socket_timeouts— live invariant against the installed redis-py; the first assertion to go red if a future release changes signature declaration again.Found while pinning a downstream consumer's redis version: we bisected the allowlist across 6.4/7.1/7.4.1/8.1.0 and traced the loss to the decorator's signature shadowing.