TypeError: hset() got an unexpected keyword argument 'mapping'
beheh opened this issue · 6 comments
As per redis-py's CHANGES as of 3.5.0 hset now accepts multiple keys at once, deprecating hmset. This is implemented through the backwards-compatible signature:
def hset(self, name, key=None, value=None, mapping=None)
Though on fakeredis 1.4.1, explicitly specifying the mapping kwarg through code like
redis.hset("key", mapping={"a": "val1", "b": "val2"})
fails with
TypeError: hset() got an unexpected keyword argument 'mapping'
I tried to build a pull request but I found the magic @command
handling very confusing and hard to work with.
Are you sure you're actually using redis-py 3.5? The hset
method on a FakeRedis object is simply inherited from the Redis object, so it looks like you're running an older redis version. Fakeredis should already support multi-element HSET.
This started happening to me after I upgraded my redis-py to 3.5, and then as per it's changelog migrated from hmset
to hset
.
The signature of hset
in redis-py 3.5 is what I put in the initial comment: https://github.com/andymccurdy/redis-py/blob/a9347cd0bc3c361cbdf4af6811ee465211eabdb0/redis/client.py#L3034-L3050
As I want to set multiple elements from my code at once, I'm therefore explicitly calling
redis.hset("key", mapping={"a": "val1", "b": "val2"})
...notice the kwarg mapping
. That's what fakeredis can't handle, the kwarg. I also cannot use
redis.hset("key", {"a": "val1", "b": "val2"})
...because while that might work in fakeredis, the real redis-py assumes that's my key
argument, as per the signature above.
The workaround for now is to continue using hmset
, but that is deprecated and to me it just looks like fakeredis needs updating to be compatible with the latest redis-py API here.
It's working for me:
In [1]: import fakeredis
In [2]: r=fakeredis.FakeRedis()
In [3]: r.hset("key", mapping={"a": "val1", "b": "val2"})
Out[3]: 2
Please post the output of the following:
import redis, fakeredis
redis.__version__
fakeredis.__version__
I see, I was using redis-py 3.3. Looking at the fakeredis code then it was unclear to me how that could possibly work without updating the fakeredis signature, but I guess that's the whole @command
stuff doing it's thing. Thanks for the fast response!
fakeredis implements the redis wire protocol (well, sort of) - so FakeRedis.hset is Redis.hset (by inheritance), and the code you're pointing at is what fakeredis implements after redis encodes and fakeredis decodes the wire protocol.
I see - thanks for the clarification!