From 15afe7eb7a2c6e95b1925551286c80175817cf83 Mon Sep 17 00:00:00 2001 From: Cody-G Date: Wed, 22 Jan 2020 15:51:39 -0800 Subject: [PATCH 1/2] Support memoryview encoding (as a no-op) --- redis/connection.py | 8 ++++---- tests/test_commands.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/redis/connection.py b/redis/connection.py index b27bf217b3..b7d48186d4 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -92,7 +92,7 @@ class Encoder(object): - "Encode strings to bytes and decode bytes to strings" + "Encode strings to bytes-like and decode bytes-like to strings" def __init__(self, encoding, encoding_errors, decode_responses): self.encoding = encoding @@ -100,8 +100,8 @@ def __init__(self, encoding, encoding_errors, decode_responses): self.decode_responses = decode_responses def encode(self, value): - "Return a bytestring representation of the value" - if isinstance(value, bytes): + "Return a bytestring or bytes-like representation of the value" + if isinstance(value, bytes) or isinstance(value, memoryview): return value elif isinstance(value, bool): # special case bool since it is a subclass of int @@ -122,7 +122,7 @@ def encode(self, value): return value def decode(self, value, force=False): - "Return a unicode string from the byte representation" + "Return a unicode string from the bytes-like representation" if (self.decode_responses or force) and isinstance(value, bytes): value = value.decode(self.encoding, self.encoding_errors) return value diff --git a/tests/test_commands.py b/tests/test_commands.py index 00752fad5d..7b27d44ff6 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -2399,6 +2399,19 @@ def test_xread(self, r): # xread starting at the last message returns an empty list assert r.xread(streams={stream: m2}) == [] + # memoryviews + m3 = r.xadd(stream, {'boom': memoryview(b'bop')}) + expected = [ + [ + stream.encode(), + [ + get_stream_message(r, stream, m3), + ] + ] + ] + + assert r.xread(streams={stream: m2}) == expected + @skip_if_server_version_lt('5.0.0') def test_xreadgroup(self, r): stream = 'stream' From 09bf90f961fce9322dc2aa54d6f68e8eecfe9c87 Mon Sep 17 00:00:00 2001 From: Cody-G Date: Fri, 24 Jan 2020 09:55:49 -0800 Subject: [PATCH 2/2] convert memoryviews to bytes when they get string-joined in short commands --- redis/connection.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/redis/connection.py b/redis/connection.py index b7d48186d4..51be9ff3c5 100755 --- a/redis/connection.py +++ b/redis/connection.py @@ -738,6 +738,12 @@ def read_response(self): raise response return response + def _maybe_to_bytes(self, arg): + if isinstance(arg, memoryview): + return arg.tobytes() + else: + return arg + def pack_command(self, *args): "Pack a series of arguments into the Redis protocol" output = [] @@ -767,7 +773,7 @@ def pack_command(self, *args): else: buff = SYM_EMPTY.join( (buff, SYM_DOLLAR, str(arg_length).encode(), - SYM_CRLF, arg, SYM_CRLF)) + SYM_CRLF, self._maybe_to_bytes(arg), SYM_CRLF)) output.append(buff) return output