Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support for variadic commands introduced in 2.4.

A variable number of values can now be passed to the following
commands: SADD, HDEL, SREM, ZREM, ZADD, L/RPUSH to bring support
in line with Redis 2.4.

A caveat - for ZADD the original implementation of txRedis broke
from convention of 'ZADD key score value' to have the method accept
'zadd(key, value, score)' (for whatever reason). This mode is still
supported for backwards compatibility but if a sequence of arguments
are passed, we now support a more Redis-like convention of
'zadd(key, score1, value1, score2, value2)'.
  • Loading branch information...
commit f4602a252a1df637d31464e5ea2b7b6959dd6424 1 parent 4d89fb2
@rlotun rlotun authored
Showing with 189 additions and 21 deletions.
  1. +91 −21 txredis/protocol.py
  2. +98 −0 txredis/test/test_redis.py
View
112 txredis/protocol.py
@@ -720,12 +720,34 @@ def push(self, key, value, tail=False, no_create=False):
else:
return self.lpush(key, value)
- def lpush(self, key, value):
- self._send('LPUSH', key, value)
+ def lpush(self, key, *values, **kwargs):
+ """
+ Add string to head of list.
+ @param key : List key
+ @param values : Sequence of values to push
+ @param value : For backwards compatibility, a single value.
+ """
+ if not kwargs:
+ self._send('LPUSH', key, *values)
+ elif 'value' in kwargs:
+ self._send('LPUSH', key, kwargs['value'])
+ else:
+ raise InvalidCommand('Need arguments for LPUSH')
return self.getResponse()
- def rpush(self, key, value):
- self._send('RPUSH', key, value)
+ def rpush(self, key, *values, **kwargs):
+ """
+ Add string to end of list.
+ @param key : List key
+ @param values : Sequence of values to push
+ @param value : For backwards compatibility, a single value.
+ """
+ if not kwargs:
+ self._send('RPUSH', key, *values)
+ elif 'value' in kwargs:
+ self._send('RPUSH', key, kwargs['value'])
+ else:
+ raise InvalidCommand('Need arguments for RPUSH')
return self.getResponse()
def lpushx(self, key, value):
@@ -1014,18 +1036,34 @@ def _list_to_set(self, res):
return set(res)
return res
- def sadd(self, key, value):
+ def sadd(self, key, *values, **kwargs):
"""
Add a member to a set
- """
- self._send('SADD', key, value)
+ @param key : SET key to add values to.
+ @param values : sequence of values to add to set
+ @param value : For backwards compatibility, add one value.
+ """
+ if not kwargs:
+ self._send('SADD', key, *values)
+ elif 'value' in kwargs:
+ self._send('SADD', key, kwargs['value'])
+ else:
+ raise InvalidCommand('Need arguments for SADD')
return self.getResponse()
- def srem(self, key, value):
+ def srem(self, key, *values, **kwargs):
"""
Remove a member from a set
- """
- self._send('SREM', key, value)
+ @param key : Set key
+ @param values : Sequence of values to remove
+ @param value : For backwards compatibility, single value to remove.
+ """
+ if not kwargs:
+ self._send('SREM', key, *values)
+ elif 'value' in kwargs:
+ self._send('SREM', key, kwargs['value'])
+ else:
+ raise InvalidCommand('Need arguments for SREM')
return self.getResponse()
def spop(self, key):
@@ -1373,11 +1411,19 @@ def hexists(self, key, field):
self._send('HEXISTS', key, field)
return self.getResponse()
- def hdel(self, key, field):
+ def hdel(self, key, *fields, **kwargs):
"""
Removes field from the hash stored at key.
- """
- self._send('HDEL', key, field)
+ @param key : Hash key
+ @param fields : Sequence of fields to remvoe
+ @param field : For backwards compatibility. Single field to remove.
+ """
+ if not kwargs:
+ self._send('HDEL', key, *fields)
+ elif 'field' in kwargs:
+ self._send('HDEL', key, field)
+ else:
+ raise InvalidCommand('Need arguments for HDEL')
return self.getResponse()
hdelete = hdel # backwards compat for older txredis
@@ -1428,18 +1474,42 @@ def publish(self, channel, message):
# ZREMRANGEBYRANK
# ZREMRANGEBYSCORE
# ZUNIONSTORE / ZINTERSTORE
- def zadd(self, key, member, score):
- """
- Add a member to a sorted set, or update its score if it already exists
- """
- self._send('ZADD', key, score, member)
+ def zadd(self, key, *item_tuples, **kwargs):
+ """
+ Add members to a sorted set, or update its score if it already exists
+ @param key : Sorted set key
+ @param item_tuples : Sequence of score, value pairs.
+ e.g. zadd(key, score1, value1, score2, value2)
+ @param member : For backwards compatibility, member name.
+ @param score : For backwards compatibility, score.
+
+ NOTE: if there are only two arguments, the order is interpreted as (value, score)
+ for backwards compatibility reasons.
+ """
+ if not kwargs and len(item_tuples) == 2 and isinstance(item_tuples[0], basestring):
+ self._send('ZADD', key, item_tuples[1], item_tuples[0])
+ elif not kwargs:
+ self._send('ZADD', key, *item_tuples)
+ elif 'member' in kwargs and 'score' in kwargs:
+ score, member = item_tuples
+ self._send('ZADD', key, kwargs['score'], kwargs['member'])
+ else:
+ raise InvalidCommand('Need arguments for ZADD')
return self.getResponse()
- def zrem(self, key, member):
+ def zrem(self, key, *members, **kwargs):
"""
- Remove a member from a sorted set
+ Remove members from a sorted set
+ @param key : Sorted set key
+ @param members : Sequeunce of members to remove
+ @param member : For backwards compatibility - if specified remove one member.
"""
- self._send('ZREM', key, member)
+ if not kwargs:
+ self._send('ZREM', key, *members)
+ elif 'member' in kwargs:
+ self._send('ZREM', key, kwargs['member'])
+ else:
+ raise InvalidCommand('Need arguments for ZREM')
return self.getResponse()
def zremrangebyrank(self, key, start, end):
View
98 txredis/test/test_redis.py
@@ -716,6 +716,23 @@ def test_push(self):
t(a, ex)
@defer.inlineCallbacks
+ def test_push_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('l')
+ yield r.lpush('l', 'a', 'b', 'c', 'd')
+ a = yield r.llen('l')
+ ex = 4
+ t(a, ex)
+
+ yield r.rpush('l', 't', 'u', 'v', 'w')
+ a = yield r.llen('l')
+ ex = 8
+ t(a, ex)
+
+
+ @defer.inlineCallbacks
def test_llen(self):
r = self.redis
t = self.assertEqual
@@ -979,6 +996,18 @@ def test_sadd(self):
t(a, ex)
@defer.inlineCallbacks
+ def test_sadd_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('s')
+ a = yield r.sadd('s', 'a', 'b', 'c', 'd')
+ ex = 4
+ a = yield r.scard('s')
+ ex = 4
+ t(a, ex)
+
+ @defer.inlineCallbacks
def test_sdiff(self):
r = self.redis
t = self.assertEqual
@@ -1047,6 +1076,22 @@ def test_srem(self):
t(a, ex)
@defer.inlineCallbacks
+ def test_srem_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('s')
+ a = yield r.sadd('s', 'a', 'b', 'c', 'd')
+ ex = 4
+ t(a, ex)
+ a = yield r.srem('s', 'a', 'b')
+ ex = 2
+ t(a, ex)
+ a = yield r.scard('s')
+ ex = 2
+ t(a, ex)
+
+ @defer.inlineCallbacks
def test_spop(self):
r = self.redis
t = self.assertEqual
@@ -1379,6 +1424,21 @@ def test_basic(self):
t(a, ex)
@defer.inlineCallbacks
+ def test_hdel_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('d')
+ yield r.hset('d', 'a', 'vala')
+ yield r.hmset('d', {'a' : 'vala', 'b' : 'valb', 'c' : 'valc'})
+ a = yield r.hdel('d', 'a', 'b', 'c')
+ ex = 3
+ t(a, ex)
+ a = yield r.hgetall('d')
+ ex = {}
+ t(a, ex)
+
+ @defer.inlineCallbacks
def test_hincr(self):
r = self.redis
t = self.assertEqual
@@ -1611,6 +1671,44 @@ def test_zremrange(self):
t(a, ex)
@defer.inlineCallbacks
+ def test_add_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('z')
+ yield r.zadd('z', 'a', 1.0)
+ a = yield r.zcard('z')
+ ex = 1
+ t(a, ex)
+
+ # NB. note how for multiple argument it's score then val
+ yield r.zadd('z', 2.0, 'b', 3.0, 'c')
+ a = yield r.zcard('z')
+ ex = 3
+
+ @defer.inlineCallbacks
+ def test_zrem_variable(self):
+ r = self.redis
+ t = self.assertEqual
+
+ yield r.delete('z')
+ yield r.zadd('z', 'a', 1.0)
+ a = yield r.zcard('z')
+ ex = 1
+ t(a, ex)
+
+ # NB. note how for multiple argument it's score then val
+ yield r.zadd('z', 2.0, 'b', 3.0, 'c')
+ a = yield r.zcard('z')
+ ex = 3
+ t(a, ex)
+
+ yield r.zrem('z', 'a', 'b', 'c')
+ a = yield r.zcard('z')
+ ex = 0
+ t(a, ex)
+
+ @defer.inlineCallbacks
def test_zrangebyscore(self):
r = self.redis
t = self.assertEqual
Please sign in to comment.
Something went wrong with that request. Please try again.