Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Changing the default protocol used to RESP3 keeping the responses for default config compatible with current RESP2 shape. Adding possibility to opt-in for unified responses for both protocol.#4052

Merged
petyaslavova merged 22 commits into
masterfrom
ps_resp3_default
May 5, 2026

Conversation

@petyaslavova

@petyaslavova petyaslavova commented Apr 30, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR changes redis-py 8.0 to use RESP3 on the wire by default while preserving legacy RESP2-compatible Python response shapes unless users explicitly opt into unified responses with legacy_responses=False. It adds the protocol/response-shape routing needed for the full matrix: default protocol(when it is not provided empty string is used to identify the case when we should use resp3 wire communication and return the responses in the legacy resp2 shape), protocol=2, and protocol=3, each with legacy and unified response modes.

The unified response implementation is expanded across core commands, cluster commands, JSON, Search, probabilistic commands, TimeSeries, and VectorSet. Response callbacks now normalize RESP2 and RESP3 wire replies into the approved unified shapes, while keeping legacy RESP2 and explicit native RESP3 behavior intact. Type hints and parser behavior were updated where unified responses introduce new structures.

Tests were updated to assert expected shapes using shared helpers for RESP2 legacy, RESP3 legacy, and unified responses. The test tasks now accept protocol and legacy-response combinations, emit distinct coverage/JUnit artifact names, and include matrix support for running all protocol/legacy combinations. This also includes fixes for cluster/default response configuration issues and a timing-sensitive XREADGROUP ... CLAIM test expectation.

Docs were refreshed for end users: README and RESP3 docs now describe the redis-py 8.0 defaults, and a new unified responses migration guide explains how to enable unified responses and what changes to expect. The old RESP unification docs/specs were replaced with unified-response-focused migration material.

protocol setting legacy_responses setting Wire protocol Python response shape
unset / default unset / default (True) RESP3 Legacy RESP2-compatible shape
unset / default False RESP3 Unified response shape
protocol=2 unset / default (True) RESP2 Legacy RESP2 shape
protocol=2 False RESP2 Unified response shape
protocol=3 unset / default (True) RESP3 Native RESP3 shape
protocol=3 False RESP3 Unified response shape

Note

High Risk
High risk because it changes default wire protocol behavior and introduces new callback routing that can affect response shapes across many core/module commands, plus expands CI coverage matrix that may surface previously untested incompatibilities.

Overview
Default behavior changes: the client now uses RESP3 on the wire by default while keeping legacy RESP2-compatible Python response shapes unless users opt into unified shapes via legacy_responses=False.

Response parsing/routing: introduces a centralized get_response_callbacks() selector (redis/_parsers/response_callbacks.py) and adds/adjusts parsers in redis/_parsers/helpers.py to support three modes: RESP2 legacy, RESP3 native, and unified responses (including RESP3→RESP2 legacy adapters for commands where RESP3 wire types differ).

CI + docs updates: GitHub Actions test runner now accepts <protocol>-<response-shape>-<topology> and runs a full matrix (default/2/3 × legacy/unified × standalone/cluster); documentation is refreshed to explain the new defaults and adds a new docs/unified_responses.rst migration guide while replacing the old RESP unification doc.

Reviewed by Cursor Bugbot for commit 76a465b. Bugbot is set up for automated code reviews on this repo. Configure here.

Comment thread redis/_parsers/helpers.py
Comment thread redis/_parsers/helpers.py
Comment thread redis/_parsers/response_callbacks.py
@jit-ci

jit-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

🛡️ Jit Security Scan Results

CRITICAL HIGH MEDIUM

✅ No security findings were detected in this PR


Security scan by Jit

…lients and connections to 3 (#4031)"

This reverts commit 0984334.
The default RESP protocol on the wire is now RESP3 (was RESP2). To keep
existing applications working unchanged, response shapes still match
today's RESP2-style Python objects by default, controlled by a new
legacy_responses=True parameter on the public clients.

* redis/utils.py
  - DEFAULT_RESP_VERSION lives here (moved from redis.connection) and is
    set to 3
  - check_protocol_version() resolves protocol=None to
    DEFAULT_RESP_VERSION before comparison, so a missing protocol is
    treated as RESP3-capable

* redis/connection.py, redis/asyncio/connection.py
  - import DEFAULT_RESP_VERSION from redis.utils (still re-exported from
    redis.connection for backward compatibility)
  - AbstractConnection.__init__: protocol default 2 -> None, new
    legacy_responses: bool = True stored as self.legacy_responses
  - URL_QUERY_ARGUMENT_PARSERS accepts protocol and
    legacy_responses, so both can be passed in connection URLs via
    redis://...?protocol=3&legacy_responses=false

* redis/client.py, redis/asyncio/client.py
  - Redis.__init__: protocol default 2 -> None, new legacy_responses
    parameter, both forwarded into the connection pool kwargs
  - client-side caching and maintenance-notifications gating switched
    to check_protocol_version(...) so a missing protocol is treated
    as RESP3

* redis/asyncio/cluster.py
  - RedisCluster.__init__: protocol default 2 -> None, new
    legacy_responses parameter, both placed in the cluster connection
    kwargs

* redis/cluster.py
  - REDIS_ALLOWED_KEYS includes legacy_responses so it propagates
    through cleanup_kwargs() to per-node Redis instances

A user-supplied protocol=None is preserved on the pool / connection
kwargs; only the wire-level HELLO handshake resolves it to the concrete
DEFAULT_RESP_VERSION.
…s. Updating some of the unified forms to the correct ones
Comment thread redis/_parsers/helpers.py
Comment thread redis/_parsers/helpers.py Outdated
Comment thread redis/_parsers/helpers.py
@jit-ci

jit-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Comment thread redis/_parsers/response_callbacks.py
@jit-ci

jit-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

Comment thread redis/_parsers/helpers.py
@jit-ci

jit-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@petyaslavova petyaslavova added the breakingchange API or Breaking Change label Apr 30, 2026
Comment thread redis/_parsers/helpers.py
@jit-ci

jit-ci Bot commented Apr 30, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@petyaslavova

Copy link
Copy Markdown
Collaborator Author

@sera bypass

Comment thread redis/_parsers/response_callbacks.py
@jit-ci

jit-ci Bot commented May 1, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 05742f8. Configure here.

Comment thread redis/_parsers/helpers.py
def parse_sentinel_master_unified_resp3(response, **options):
state = parse_sentinel_state_resp3(response, **options)
_add_derived_sentinel_booleans(state, state["flags"])
return state

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant _add_derived_sentinel_booleans calls in unified RESP3 parsers

Low Severity

parse_sentinel_master_unified_resp3, parse_sentinel_masters_unified_resp3, and parse_sentinel_slaves_and_sentinels_unified_resp3 all call _add_derived_sentinel_booleans(state, state["flags"]) after parse_sentinel_state_resp3 already calls _add_derived_sentinel_booleans(result, flags) internally. The second call is completely redundant — it overwrites the same boolean keys with the same values. This adds confusion about whether the inner call does something different from the outer call.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 05742f8. Configure here.

Comment thread redis/_parsers/response_callbacks.py
@jit-ci

jit-ci Bot commented May 2, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@jit-ci

jit-ci Bot commented May 3, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@petyaslavova

Copy link
Copy Markdown
Collaborator Author

@sera bypass

Comment thread docs/resp3_features.rst
Comment thread redis/asyncio/connection.py Outdated
Comment thread redis/asyncio/cluster.py
Comment thread redis/commands/core.py Outdated
Comment thread redis/_parsers/helpers.py
Comment thread docs/examples/asyncio_examples.ipynb Outdated
Comment thread docs/unified_responses.rst
Comment thread docs/unified_responses.rst Outdated
@jit-ci

jit-ci Bot commented May 4, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@jit-ci

jit-ci Bot commented May 4, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@petyaslavova

Copy link
Copy Markdown
Collaborator Author

@sera bypass

@vladvildanov

Copy link
Copy Markdown
Collaborator

@petyaslavova Could you please also update README.md to bring some context? We need to reflect that we recommend to opt-out legacy responses and point to migration guides

@jit-ci

jit-ci Bot commented May 5, 2026

Copy link
Copy Markdown

❌ Jit Scanner failed - Our team is investigating

Jit Scanner failed - Our team has been notified and is working to resolve the issue. Please contact support if you have any questions.


💡 Need to bypass this check? Comment @sera bypass to override.

@petyaslavova

Copy link
Copy Markdown
Collaborator Author

@sera bypass

@petyaslavova petyaslavova merged commit f4ea084 into master May 5, 2026
675 of 680 checks passed
@petyaslavova petyaslavova deleted the ps_resp3_default branch May 5, 2026 15:34
petyaslavova added a commit that referenced this pull request May 26, 2026
… default config compatible with current RESP2 shape. Adding possibility to opt-in for unified responses for both protocol. (#4052)

* Revert "Changing the default RESP protocol configurations for Redis clients and connections to 3 (#4031)"

This reverts commit 0984334.

* Revert "RESP2 and RESP3 response unification (#4025)"

This reverts commit de8a47a.

* Fixing newly added test to be compatible with the old style responses

* Default to RESP3 wire protocol, add legacy_responses opt-out

The default RESP protocol on the wire is now RESP3 (was RESP2). To keep
existing applications working unchanged, response shapes still match
today's RESP2-style Python objects by default, controlled by a new
legacy_responses=True parameter on the public clients.

* redis/utils.py
  - DEFAULT_RESP_VERSION lives here (moved from redis.connection) and is
    set to 3
  - check_protocol_version() resolves protocol=None to
    DEFAULT_RESP_VERSION before comparison, so a missing protocol is
    treated as RESP3-capable

* redis/connection.py, redis/asyncio/connection.py
  - import DEFAULT_RESP_VERSION from redis.utils (still re-exported from
    redis.connection for backward compatibility)
  - AbstractConnection.__init__: protocol default 2 -> None, new
    legacy_responses: bool = True stored as self.legacy_responses
  - URL_QUERY_ARGUMENT_PARSERS accepts protocol and
    legacy_responses, so both can be passed in connection URLs via
    redis://...?protocol=3&legacy_responses=false

* redis/client.py, redis/asyncio/client.py
  - Redis.__init__: protocol default 2 -> None, new legacy_responses
    parameter, both forwarded into the connection pool kwargs
  - client-side caching and maintenance-notifications gating switched
    to check_protocol_version(...) so a missing protocol is treated
    as RESP3

* redis/asyncio/cluster.py
  - RedisCluster.__init__: protocol default 2 -> None, new
    legacy_responses parameter, both placed in the cluster connection
    kwargs

* redis/cluster.py
  - REDIS_ALLOWED_KEYS includes legacy_responses so it propagates
    through cleanup_kwargs() to per-node Redis instances

A user-supplied protocol=None is preserved on the pool / connection
kwargs; only the wire-level HELLO handshake resolves it to the concrete
DEFAULT_RESP_VERSION.

* Adding test fixes

* Adding changes for first several commands and test helpers

* Adding changes for batches 5 and 6

* Adding the rest of the base commands.

* Adding changes for probabilistic and timeseries modules

* Adding changes for search and json modules. Adding docs and test fixes. Updating some of the unified forms to the correct ones

* Adding test_xreadgroup_with_claim_min_idle_time fix

* Adding pipeline test coverage for all combinations of protocol and legacy_responses

* Applying review comments

* Applying review comments

* Applying review comments and fixing failing tests

* Applying review comments and fixing failing tests

* Add flaky test fix

* Add flaky test fix- second try, same test - fails for just one job

* Fixing unstable in CI tests

* Applying review comments

* Fixing linters and spelling error

* Applying review comments
sundb pushed a commit to redis/redis that referenced this pull request Jun 1, 2026
## Issue

The vector set Python tests intentionally use two clients: 
- the default client (`self.redis`) for the existing RESP2-oriented test
expectations
- `self.redis3` for RESP3-specific coverage.

However, the default client did not explicitly set a protocol, so it
depended on redis-py's default behavior. With newer redis-py versions,
RESP3 is now the default
protocol(redis/redis-py#4052). In particular,
vector set replies such as `VSIM ... WITHSCORES` may be parsed into
map/dict-like structures instead of the RESP2 flat-array shape assumed
by existing tests.

## Changes

Explicitly create the default primary and replica Redis clients with
`protocol=2`.
`self.redis3` is left unchanged and continues to use `protocol=3` for
RESP3-specific test coverage.
sundb pushed a commit to sundb/redis that referenced this pull request Jun 4, 2026
## Issue

The vector set Python tests intentionally use two clients:
- the default client (`self.redis`) for the existing RESP2-oriented test
expectations
- `self.redis3` for RESP3-specific coverage.

However, the default client did not explicitly set a protocol, so it
depended on redis-py's default behavior. With newer redis-py versions,
RESP3 is now the default
protocol(redis/redis-py#4052). In particular,
vector set replies such as `VSIM ... WITHSCORES` may be parsed into
map/dict-like structures instead of the RESP2 flat-array shape assumed
by existing tests.

## Changes

Explicitly create the default primary and replica Redis clients with
`protocol=2`.
`self.redis3` is left unchanged and continues to use `protocol=3` for
RESP3-specific test coverage.

(cherry picked from commit 8fcf3dc)
sundb pushed a commit to redis/redis that referenced this pull request Jun 4, 2026
## Issue

The vector set Python tests intentionally use two clients:
- the default client (`self.redis`) for the existing RESP2-oriented test
expectations
- `self.redis3` for RESP3-specific coverage.

However, the default client did not explicitly set a protocol, so it
depended on redis-py's default behavior. With newer redis-py versions,
RESP3 is now the default
protocol(redis/redis-py#4052). In particular,
vector set replies such as `VSIM ... WITHSCORES` may be parsed into
map/dict-like structures instead of the RESP2 flat-array shape assumed
by existing tests.

## Changes

Explicitly create the default primary and replica Redis clients with
`protocol=2`.
`self.redis3` is left unchanged and continues to use `protocol=3` for
RESP3-specific test coverage.

(cherry picked from commit 8fcf3dc)
petyaslavova added a commit that referenced this pull request Jun 12, 2026
…4109)

* fix(search): parse RESP3 FT.SEARCH responses with bytes-typed keys

Since the wire protocol default switched to RESP3 (#4052), the server
returns FT.SEARCH responses as RESP3 maps.  When a client is opened with
``decode_responses=False`` the map keys arrive as ``bytes`` rather than
``str``, but ``Result.from_resp3`` looked them up as plain strings:

    instance.total = res.get("total_results", 0)
    for result_item in res.get("results", []):
        ...

Because ``b"total_results" != "total_results"``, every lookup missed and
the search appeared to return ``Result{0 total, docs: []}`` even though
the server had matched documents.

Normalise the top-level map and each per-result map to string keys
before reading them, mirroring the pattern already used by
``_parse_hybrid_search_resp3`` in ``redis/commands/search/commands.py``
("Top-level keys are normalised to strings").

Adds ``tests/test_search_result.py`` with regression tests covering
str-keyed, bytes-keyed, and mixed maps, plus the empty/None edge cases.
The tests fail on the unfixed code for the bytes and mixed cases.

Fixes #4107

* fix(search): extend bytes-key normalisation to AGGREGATE and SPELLCHECK

The RESP3 callbacks for FT.SEARCH (`Result.from_resp3`) were taught to
normalise top-level structural map keys to strings so that responses
parsed correctly on connections opened with `decode_responses=False`.
`_parse_aggregate_resp3` (FT.AGGREGATE / FT.CURSOR READ /
FT.PROFILE AGGREGATE) and `_parse_spellcheck_resp3` (FT.SPELLCHECK)
still read `"total_results"`, `"results"` and `"warning"` as
plain strings, so a byte-keyed RESP3 response missed every lookup and
silently parsed as an empty AggregateResult / `{}` even when the
server had returned data.

Apply the same `str_if_bytes` normalisation that
`Result.from_resp3` and `_parse_hybrid_search_resp3` already use:

- normalise the top-level map and (for aggregate) the per-result-item
  map; document data inside `extra_attributes` is left as-is so the
  caller still sees bytes when `decode_responses=False`, mirroring the
  RESP2 shape;
- normalise the outer `results` key for spellcheck; the inner term keys
  match the RESP2 `decode_responses=False` shape and stay as bytes.

Adds regression tests for both parsers in
`tests/test_search_result.py`, plus integration tests in
`tests/test_search.py` that exercise the three affected Search
callbacks (FT.SEARCH, FT.AGGREGATE, FT.SPELLCHECK) against a real
RESP3 wire with a `decode_responses=False` client.

* fix(search): apply petyaslavova review feedback

- _parse_spellcheck_resp3 now preserves the suggestion value as-is so
  it keeps the decode_responses shape RESP2 would produce (str when
  decoded, bytes otherwise) instead of wrapping bytes in str().
- waitForIndex now accepts both str and bytes structural keys in
  FT.INFO responses.  execute_command bypasses the search module's
  callbacks, so the helper has to handle the raw RESP3 dict/RESP2
  list shapes for decode_responses=False clients.  This unblocks the
  previously failing fixed-clients CI matrix entry.
- The bytes-keys integration tests are now parametrised over
  protocol=2 (anchors the legacy output shape) and the default
  protocol (the path that actually exercises the changed parsers in
  _RedisCallbacksRESP3toRESP2Legacy).  Explicit protocol=3 was
  routing through _RedisCallbacksRESP3 and bypassing the fix.
- Spellcheck assertion is stricter: it pins the term key to
  b"impornant" and the suggestion value to b"important".
- Mirror the suggestion-bytes assertion in the
  test_search_result.py unit test.

* test(search): tidy review nits in RESP3 bytes-key tests

- Rephrase the parametrisation comment so it explains *why* the two
  protocol arms exist in terms of the parsers being exercised
  (_parse_search_resp3 / _parse_aggregate_resp3 /
  _parse_spellcheck_resp3) rather than "the changed methods", which
  was only meaningful relative to this PR's diff.
- Reorder decorators on TestSearchResp3BytesKeys methods so the
  test-scope marks (redismod, fixed_client) stay grouped and
  @pytest.mark.parametrize sits last, matching the prevailing style
  for parametrised tests.

---------

Co-authored-by: petyaslavova <[email protected]>
petyaslavova added a commit that referenced this pull request Jun 23, 2026
…4109)

* fix(search): parse RESP3 FT.SEARCH responses with bytes-typed keys

Since the wire protocol default switched to RESP3 (#4052), the server
returns FT.SEARCH responses as RESP3 maps.  When a client is opened with
``decode_responses=False`` the map keys arrive as ``bytes`` rather than
``str``, but ``Result.from_resp3`` looked them up as plain strings:

    instance.total = res.get("total_results", 0)
    for result_item in res.get("results", []):
        ...

Because ``b"total_results" != "total_results"``, every lookup missed and
the search appeared to return ``Result{0 total, docs: []}`` even though
the server had matched documents.

Normalise the top-level map and each per-result map to string keys
before reading them, mirroring the pattern already used by
``_parse_hybrid_search_resp3`` in ``redis/commands/search/commands.py``
("Top-level keys are normalised to strings").

Adds ``tests/test_search_result.py`` with regression tests covering
str-keyed, bytes-keyed, and mixed maps, plus the empty/None edge cases.
The tests fail on the unfixed code for the bytes and mixed cases.

Fixes #4107

* fix(search): extend bytes-key normalisation to AGGREGATE and SPELLCHECK

The RESP3 callbacks for FT.SEARCH (`Result.from_resp3`) were taught to
normalise top-level structural map keys to strings so that responses
parsed correctly on connections opened with `decode_responses=False`.
`_parse_aggregate_resp3` (FT.AGGREGATE / FT.CURSOR READ /
FT.PROFILE AGGREGATE) and `_parse_spellcheck_resp3` (FT.SPELLCHECK)
still read `"total_results"`, `"results"` and `"warning"` as
plain strings, so a byte-keyed RESP3 response missed every lookup and
silently parsed as an empty AggregateResult / `{}` even when the
server had returned data.

Apply the same `str_if_bytes` normalisation that
`Result.from_resp3` and `_parse_hybrid_search_resp3` already use:

- normalise the top-level map and (for aggregate) the per-result-item
  map; document data inside `extra_attributes` is left as-is so the
  caller still sees bytes when `decode_responses=False`, mirroring the
  RESP2 shape;
- normalise the outer `results` key for spellcheck; the inner term keys
  match the RESP2 `decode_responses=False` shape and stay as bytes.

Adds regression tests for both parsers in
`tests/test_search_result.py`, plus integration tests in
`tests/test_search.py` that exercise the three affected Search
callbacks (FT.SEARCH, FT.AGGREGATE, FT.SPELLCHECK) against a real
RESP3 wire with a `decode_responses=False` client.

* fix(search): apply petyaslavova review feedback

- _parse_spellcheck_resp3 now preserves the suggestion value as-is so
  it keeps the decode_responses shape RESP2 would produce (str when
  decoded, bytes otherwise) instead of wrapping bytes in str().
- waitForIndex now accepts both str and bytes structural keys in
  FT.INFO responses.  execute_command bypasses the search module's
  callbacks, so the helper has to handle the raw RESP3 dict/RESP2
  list shapes for decode_responses=False clients.  This unblocks the
  previously failing fixed-clients CI matrix entry.
- The bytes-keys integration tests are now parametrised over
  protocol=2 (anchors the legacy output shape) and the default
  protocol (the path that actually exercises the changed parsers in
  _RedisCallbacksRESP3toRESP2Legacy).  Explicit protocol=3 was
  routing through _RedisCallbacksRESP3 and bypassing the fix.
- Spellcheck assertion is stricter: it pins the term key to
  b"impornant" and the suggestion value to b"important".
- Mirror the suggestion-bytes assertion in the
  test_search_result.py unit test.

* test(search): tidy review nits in RESP3 bytes-key tests

- Rephrase the parametrisation comment so it explains *why* the two
  protocol arms exist in terms of the parsers being exercised
  (_parse_search_resp3 / _parse_aggregate_resp3 /
  _parse_spellcheck_resp3) rather than "the changed methods", which
  was only meaningful relative to this PR's diff.
- Reorder decorators on TestSearchResp3BytesKeys methods so the
  test-scope marks (redismod, fixed_client) stay grouped and
  @pytest.mark.parametrize sits last, matching the prevailing style
  for parametrised tests.

---------

Co-authored-by: petyaslavova <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breakingchange API or Breaking Change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants