Cannot instantiate FrameBuffer from a bytes object
Port, board and/or hardware
RP2, Pyboard 1.1
MicroPython version
MicroPython v1.22.1 on 2024-01-05; Raspberry Pi Pico with RP2040
Reproduction
Enter the following at the REPL:
from framebuf import FrameBuffer, GS8
b = b'\x00' * 100
f = FrameBuffer(b, 10, 10, GS8)
Expected behaviour
I would expect the instantiation of the FrameBuffer to succeed (as it does if a bytearray is passed).
Observed behaviour
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object with buffer protocol required
Additional Information
Use case:
Instantiating from a bytes object (or a memoryview of bytes) would enable graphical objects frozen as bytecode to be blitted onto an existing frame buffer.
A further observation: the error message is most misleading.
Code of Conduct
Yes, I agree
frambuf initalizes with ValueError
Port, board and/or hardware
all variants that use the framebuf module
MicroPython version
MicroPython v1.24.0-preview.149.g6007f3e20 on 2024-07-26; Raspberry Pi Pico W with RP2040
Reproduction
I'm using a simple frambuffer with one bit per pixel. This code segment used to work on earlier micropython versions but fails now:
import framebuf
w=21; h=8
data = bytearray(w*h // 8)
fb = framebuf.FrameBuffer(data, w, h, framebuf.MONO_HMSB)
Expected behaviour
Expected to accept the input buffer without a ValueError
Observed behaviour
this causes a
File "<stdin>", line 1, in <module>
ValueError:
ValueError is raised with no further details
Additional Information
I tracked this due to this input validation here:
https://github.com/micropython/micropython/blob/master/extmod/modframebuf.c#L318
and I think that's due to
https://github.com/micropython/micropython/blob/master/extmod/modframebuf.c#L294
which modifies the stride value to be 24 ((21 + 7) & ~7 == 24) and therefore the provided input buffer is too small. Modifying the example above with a input buffer of 24 then works as expected.
I'm not sure why this check was introduced. Maybe due to other functionalities in the framebuffer. But in any case it's now difficult to provide a matching input buffer size without the knowledge of what is checked inside the module.
This could be addressed via a doc update. Or raise a ValueError that indicates what went wrong (e.g. "expected buffer length of xxx, got yyy")
Code of Conduct
Yes, I agree