How to change the buffering mode of sys.stdout and sys.stderr?

I noticed that JupyterLab notebook uses wrong buffering (for interactive output) for stdout and stderr. For example this cell:

for i in range(2): print(f'stdout: {i}'); print(f'stderr: {i}', file=sys.stderr)

produces the output below. Notice that first the whole stdout is printed, then the whole stderr is printed. As a result the order of the lines is incorrect:

stdout: 0
stdout: 1
stderr: 0
stderr: 1

In the plain IPython (the same version as used by Jupyter) I get the expected result. Probably the streams use line buffering or no buffering:

In [2]: for i in range(2): print(f'stdout: {i}'); print(f'stderr: {i}', file=sys.stderr)
stdout: 0
stderr: 0
stdout: 1
stderr: 1

In JupyterLab if I flush the stream buffer after every print I get the expected output too:

for i in range(2): print(f'stdout: {i}', flush=True); print(f'stderr: {i}', file=sys.stderr, flush=True)
stdout: 0
stderr: 0
stdout: 1
stderr: 1

This suggests that there is no fundamental problem like stdout and stderr being printed only after the execution of the cell finishes. This rather points to a wrong buffering mode of the two streams.

Unfortunately I am not able to change the buffering mode of the streams the usual way because they are instances of a special type ipykernel.iostream.OutStream which does not have the standard interface method io.TextIOWrapper.reconfigure().

How can I fix this unexpected behaviour?

I am using: Python 3.10.4, IPython 8.4.0, ipykernel 6.13.0, jupyter_core 4.10.0.

I noticed this bug report for IPython (from 2015!): buffering problem(?) with print_traceback in the qtconsole