From 2eceba39a59bd0ec34e0ae4ea108a40e33c159ed Mon Sep 17 00:00:00 2001 From: Nikolaus Schuetz Date: Tue, 21 Jul 2026 23:18:05 -0700 Subject: [PATCH] fix: accept memoryview in decode and decode_lazy rlp.decode rejected memoryview objects (is_bytes only accepts bytes and bytearray), and rlp.decode_lazy raised a TypeError because the lazy codec concatenates slices of the input (memoryview does not support +). Normalize a memoryview input to bytes at the top of both entry points, mirroring the existing bytearray handling, so memoryview is a first-class input like bytearray. Closes #115 --- rlp/codec.py | 3 +++ rlp/lazy.py | 3 +++ tests/core/test_memoryview.py | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 tests/core/test_memoryview.py diff --git a/rlp/codec.py b/rlp/codec.py index 63386fe..d9a5b8c 100644 --- a/rlp/codec.py +++ b/rlp/codec.py @@ -290,6 +290,9 @@ def decode(rlp, sedes=None, strict=True, recursive_cache=False, **kwargs): item and `strict` is true :raises: :exc:`rlp.DeserializationError` if the deserialization fails """ + if isinstance(rlp, memoryview): + rlp = bytes(rlp) + if not is_bytes(rlp): raise DecodingError( "Can only decode RLP bytes, got type %s" % type(rlp).__name__, rlp diff --git a/rlp/lazy.py b/rlp/lazy.py index 170bcc2..7a720cd 100644 --- a/rlp/lazy.py +++ b/rlp/lazy.py @@ -39,6 +39,9 @@ def decode_lazy(rlp, sedes=None, **sedes_kwargs): :returns: either the already decoded and deserialized object (if encoded as a string) or an instance of :class:`rlp.LazyList` """ + if isinstance(rlp, memoryview): + rlp = bytes(rlp) + item, end = consume_item_lazy(rlp, 0) if end != len(rlp): raise DecodingError("RLP length prefix announced wrong length", rlp) diff --git a/tests/core/test_memoryview.py b/tests/core/test_memoryview.py new file mode 100644 index 0000000..c22f20c --- /dev/null +++ b/tests/core/test_memoryview.py @@ -0,0 +1,24 @@ +from rlp import ( + decode, + decode_lazy, + encode, +) + + +def test_memoryview(): + e = encode(b"abc") + expected = decode(e) + actual = decode(memoryview(e)) + assert actual == expected + + +def test_memoryview_lazy(): + e = encode(b"abc") + expected = decode(e) + actual = decode_lazy(memoryview(e)) + assert expected == actual + + +def test_memoryview_nested_list(): + e = encode([b"cat", b"dog", [b"nested", b""]]) + assert decode(memoryview(e)) == decode(e)