Describe the bug
When using xread on an empty or non-existant stream with a blocking argument, the function incorrectly returns an empty list instead of blocking.
This is a regression of behavior from the real Redis client.
The source of the bug seems to be in _xread in streammixins.py. If the stream is empty, the function will return res which is an empty list.
When we call xread with a blocking argument, it wraps the function _xread with _blocking from _basefakesocket.py. Since the _xread returns list() instead of None, the blocking wrapper will not retry, as it only yields if the function returns a None.
Having _xread return None in the case of an empty stream could probably fix this issue, but I haven't verified if this doesn't create a regression elsewhere.
Describe the bug When using
xread
on an empty or non-existant stream with a blocking argument, the function incorrectly returns an empty list instead of blocking.This is a regression of behavior from the real Redis client.
The source of the bug seems to be in
_xread
instreammixins.py
. If the stream is empty, the function will returnres
which is an empty list.When we call
xread
with a blocking argument, it wraps the function_xread
with_blocking
from_basefakesocket.py
. Since the_xread
returnslist()
instead ofNone
, the blocking wrapper will not retry, as it only yields if the function returns aNone
.Having
_xread
returnNone
in the case of an empty stream could probably fix this issue, but I haven't verified if this doesn't create a regression elsewhere.To Reproduce Step to reproduce the behavior:
In fakeredis, this code immediately returns an empty list. The same is also true for the
async
version.Expected behavior The same line of code in
redis-py
yields forever until an event is added to the stream, and returns it.This is the proper behavior since count is
1
and we specified for it to block infinitely. It should never return a result without exactly one event.Desktop: