`json.dump` behaves incorrectly on invalid stream write bytes count.
Port, board and/or hardware
Unix
MicroPython version
MicroPython v1.28.0-preview.174.ga8b71559cf on 2026-02-20; linux [GCC 15.2.1] version
Reproduction
- Run the following minimised code snippet:
import io, json
class S(io.IOBase):
def write(self, buf):
return 2
json.dump({}, S())
Expected behaviour
The code should either reject stream writes with an unexpected number of bytes written or just ignore them.
Observed behaviour
The interpreter hangs due to repeated calls to io.IOBase.write, and after a while it will crash on certain targets.
Additional Information
CPython seems to ignore the return value of the stream callback and only checks for exceptions being raised. The test case code doesn't hang or crash on all recent CPython versions I've tried.
I understand this is an edge case that may not be worth fixing, but I didn't find anything similar in the issue tracker or in the known issues list present in the documentation.
Code of Conduct
Yes, I agree
tests/extmod/ujson_dump_iobase.py always fails when MICROPY_STREAMS_NON_BLOCK is disabled
In tests/extmod/ujson_dump_iobase.py, S.write() does not return the number of bytes written.
S.write() returns always None so it causes always EAGAIN error.
In the case MICROPY_STREAMS_NON_BLOCK is enabled, EAGAIN would be ignored thanks to mp_is_nonblocking_error(err) defined in py/stream.h and write() does its task anyway successfully, the result of the test is correct.
However, in my thought the last line of write() should be return len(buf) because it should return None only when writing to stream is impossible for some reason.