Skip to content

hset and hmset unexpectedly mutates the list passed to items if key+value or mapping is also used #3052

Closed
@yvan-the-barbarian

Description

@yvan-the-barbarian

Version: redis-py 5.0.1 (Any Redis version)

Platform: Any platform

Description:
If the items parameter of the hset or hmset method is used in conjunction with the key and value, or with the mapping parameters, the list passed to the items parameter is unexpectedly mutated.

For example, using the code below:

from redis.client import Redis

redis = Redis.from_url('redis://127.0.0.1')

items = [
    'one', b'1',
    'two', b'2',
    'three', b'3',
]

redis.hset('test', items=items, key='four', value=b'4')

print(items)

redis.close()

After the method call, items is expectantly updated to ['one', b'1', 'two', b'2', 'three', b'3', 'four', b'4'].

Calling the method should, in principle, not change any of the objects sent as parameters.

As a suggestion, the code could be changed to:

        if key is None and not mapping and not items:
            raise DataError("'hset' with no key value pairs")

        sources = []
        
        if items:
            sources.append(items)
        
        if key is not None:
            sources.append((key, value))
        
        if mapping:
            sources.append(value for entry in mapping.items() for value in entry)

        return self.execute_command("HSET", name, *chain(*sources))

This would have the added benefit of allowing items to be any kind of Iterable object and not just lists.

(In the same vein of ideas, the mapping parameter could be changed to typing.Mapping to allow any mapping instead of just dicts)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions