[Python-modules-commits] [python-fakeredis] 01/03: Import python-fakeredis_0.8.1.orig.tar.gz

Peter Lisák peterlisak-guest at moszumanska.debian.org
Tue Aug 23 10:47:17 UTC 2016


This is an automated email from the git hooks/post-receive script.

peterlisak-guest pushed a commit to branch master
in repository python-fakeredis.

commit 611a458a23f6ce3d615b7c1e262437becf02cd7f
Author: Peter Lisák <peter.lisak at gmail.com>
Date:   Mon Aug 22 10:21:37 2016 +0200

    Import python-fakeredis_0.8.1.orig.tar.gz
---
 .travis.yml       |   1 +
 README.rst        |   6 +-
 fakeredis.py      | 110 ++++++++++++++++++-----
 setup.py          |   2 +-
 test_fakeredis.py | 255 ++++++++++++++++++++++++++++++++++++++++++++++++------
 5 files changed, 325 insertions(+), 49 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index ef9df07..4e6cd9d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ python:
   - "2.7"
   - "3.3"
   - "3.4"
+  - "3.5"
 sudo: false
 cache:
   - pip
diff --git a/README.rst b/README.rst
index ec298b1..dd6965f 100644
--- a/README.rst
+++ b/README.rst
@@ -126,8 +126,6 @@ generic
 
  * restore
  * dump
- * pexpireat
- * pexpire
  * migrate
  * object
  * wait
@@ -219,6 +217,9 @@ Contributing
 Contributions are welcome.  Please see the `contributing guide`_ for
 more details.
 
+If you'd like to help out, you can start with any of the issues
+labeled with `HelpWanted`_.
+
 
 Running the Tests
 =================
@@ -268,3 +269,4 @@ they have all been tagged as 'slow' so you can skip them by running::
 
 .. _redis-py: http://redis-py.readthedocs.org/en/latest/index.html
 .. _contributing guide: https://github.com/jamesls/fakeredis/blob/master/CONTRIBUTING.rst
+.. _HelpWanted: https://github.com/jamesls/fakeredis/issues?q=is%3Aissue+is%3Aopen+label%3AHelpWanted
diff --git a/fakeredis.py b/fakeredis.py
index 97b0ca9..e5f76aa 100644
--- a/fakeredis.py
+++ b/fakeredis.py
@@ -9,6 +9,7 @@ from datetime import datetime, timedelta
 import operator
 import sys
 import time
+import types
 import re
 
 import redis
@@ -28,7 +29,7 @@ if not PY2:
     long = int
 
 
-__version__ = '0.7.0'
+__version__ = '0.8.1'
 
 
 if sys.version_info[0] == 2:
@@ -171,6 +172,39 @@ class _Hash(_StrKeyDict):
     redis_type = b'hash'
 
 
+def DecodeGenerator(gen):
+    for item in gen:
+        yield _decode(item)
+
+
+def _decode(value):
+    if isinstance(value, bytes):
+        value = value.decode()
+    elif isinstance(value, dict):
+        value = dict((_decode(k), _decode(v)) for k, v in value.items())
+    elif isinstance(value, (list, set, tuple)):
+        value = value.__class__(_decode(x) for x in value)
+    elif isinstance(value, types.GeneratorType):
+        value = DecodeGenerator(value)
+    return value
+
+
+def _make_decode_func(func):
+    def decode_response(*args, **kwargs):
+        val = _decode(func(*args, **kwargs))
+        return val
+    return decode_response
+
+
+def _patch_responses(obj):
+    for attr_name in dir(obj):
+        attr = getattr(obj, attr_name)
+        if not callable(attr) or attr_name.startswith('_'):
+            continue
+        func = _make_decode_func(attr)
+        setattr(obj, attr_name, func)
+
+
 class FakeStrictRedis(object):
     @classmethod
     def from_url(cls, url, db=None, **kwargs):
@@ -182,7 +216,8 @@ class FakeStrictRedis(object):
                 db = 0
         return cls(db=db)
 
-    def __init__(self, db=0, charset='utf-8', errors='strict', **kwargs):
+    def __init__(self, db=0, charset='utf-8', errors='strict',
+                 decode_responses=False, **kwargs):
         if db not in DATABASES:
             DATABASES[db] = _StrKeyDict()
         self._db = DATABASES[db]
@@ -190,6 +225,9 @@ class FakeStrictRedis(object):
         self._encoding = charset
         self._encoding_errors = errors
         self._pubsubs = []
+        self._decode_responses = decode_responses
+        if decode_responses:
+            _patch_responses(self)
 
     def flushdb(self):
         DATABASES[self._db_num].clear()
@@ -231,17 +269,33 @@ class FakeStrictRedis(object):
     __contains__ = exists
 
     def expire(self, name, time):
+        return self._expire(name, time)
+
+    def pexpire(self, name, millis):
+        return self._expire(name, millis, 1000)
+
+    def _expire(self, name, time, multiplier=1):
         if isinstance(time, timedelta):
-            time = int(timedelta_total_seconds(time))
+            time = int(timedelta_total_seconds(time) * multiplier)
+        if not isinstance(time, int):
+            raise redis.ResponseError("value is not an integer or out of "
+                                      "range.")
         if self.exists(name):
-            self._db.expire(name, datetime.now() + timedelta(seconds=time))
+            self._db.expire(name, datetime.now() +
+                            timedelta(seconds=time / float(multiplier)))
             return True
         else:
             return False
 
     def expireat(self, name, when):
+        return self._expireat(name, when)
+
+    def pexpireat(self, name, when):
+        return self._expireat(name, when, 1000)
+
+    def _expireat(self, name, when, multiplier=1):
         if not isinstance(when, datetime):
-            when = datetime.fromtimestamp(when)
+            when = datetime.fromtimestamp(when / float(multiplier))
         if self.exists(name):
             self._db.expire(name, when)
             return True
@@ -262,7 +316,7 @@ class FakeStrictRedis(object):
             return to_bytes(value)
 
     def __getitem__(self, name):
-        return self._db[name]
+        return self.get(name)
 
     def getbit(self, name, offset):
         """Returns a boolean indicating the value of ``offset`` in ``name``"""
@@ -379,11 +433,23 @@ class FakeStrictRedis(object):
     def set(self, name, value, ex=None, px=None, nx=False, xx=False):
         if (not nx and not xx) or (nx and self._db.get(name, None) is None) \
                 or (xx and not self._db.get(name, None) is None):
-            if ex is not None and ex > 0:
-                self._db.expire(name, datetime.now() + timedelta(seconds=ex))
-            elif px is not None and px > 0:
-                self._db.expire(name, datetime.now() +
-                                timedelta(milliseconds=px))
+            if ex is not None:
+                if isinstance(ex, timedelta):
+                    ex = ex.seconds + ex.days * 24 * 3600
+                if ex < 0:
+                    raise ResponseError('invalid expire time in SETEX')
+                if ex > 0:
+                    self._db.expire(name, datetime.now() +
+                                    timedelta(seconds=ex))
+            elif px is not None:
+                if isinstance(px, timedelta):
+                    ms = int(px.microseconds / 1000)
+                    px = (px.seconds + px.days * 24 * 3600) * 1000 + ms
+                if px < 0:
+                    raise ResponseError('invalid expire time in SETEX')
+                if px > 0:
+                    self._db.expire(name, datetime.now() +
+                                    timedelta(milliseconds=px))
             self._db[name] = to_bytes(value)
             return True
         else:
@@ -468,9 +534,9 @@ class FakeStrictRedis(object):
         if now > exp_time:
             return None
         else:
-            return round(((exp_time - now).days * 3600 * 24
-                          + (exp_time - now).seconds
-                          + (exp_time - now).microseconds / 1E6) * multiplier)
+            return long(round(((exp_time - now).days * 3600 * 24 +
+                        (exp_time - now).seconds +
+                        (exp_time - now).microseconds / 1E6) * multiplier))
 
     def type(self, name):
         key = self._db.get(name)
@@ -828,7 +894,7 @@ class FakeStrictRedis(object):
 
     def hvals(self, name):
         "Return the list of values within hash ``name``"
-        return self._db.get(name, {}).values()
+        return list(self._db.get(name, {}).values())
 
     def sadd(self, name, *values):
         "Add ``value`` to set ``name``"
@@ -1419,11 +1485,12 @@ class FakeStrictRedis(object):
                     continue
         raise redis.WatchError('Could not run transaction after 5 tries')
 
-    def pubsub(self):
+    def pubsub(self, ignore_subscribe_messages=False):
         """
         Returns a new FakePubSub instance
         """
-        ps = FakePubSub()
+        ps = FakePubSub(decode_responses=self._decode_responses,
+                        ignore_subscribe_messages=ignore_subscribe_messages)
         self._pubsubs.append(ps)
 
         return ps
@@ -1655,14 +1722,15 @@ class FakePubSub(object):
     UNSUBSCRIBE_MESSAGE_TYPES = ['unsubscribe', 'punsubscribe']
     PATTERN_MESSAGE_TYPES = ['psubscribe', 'punsubscribe']
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, decode_responses=False, *args, **kwargs):
         self.channels = {}
         self.patterns = {}
         self._q = Queue()
         self.subscribed = False
-
-        self.ignore_subscribe_messages = kwargs['ignore_subscribe_messages']\
-            if 'ignore_subscribe_messages' in kwargs else False
+        if decode_responses:
+            _patch_responses(self)
+        self.ignore_subscribe_messages = kwargs.get(
+            'ignore_subscribe_messages', False)
 
     def put(self, channel, message, message_type, pattern=None):
         """
diff --git a/setup.py b/setup.py
index 37c92ab..4759ebc 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ from setuptools import setup, find_packages
 
 setup(
     name='fakeredis',
-    version='0.7.0',
+    version='0.8.1',
     description="Fake implementation of redis API for testing purposes.",
     long_description=open(os.path.join(os.path.dirname(__file__),
                                        'README.rst')).read(),
diff --git a/test_fakeredis.py b/test_fakeredis.py
index 8606c8d..91049af 100644
--- a/test_fakeredis.py
+++ b/test_fakeredis.py
@@ -70,6 +70,7 @@ def key_val_dict(size=100):
 
 
 class TestFakeStrictRedis(unittest.TestCase):
+    decode_responses = False
     def setUp(self):
         self.redis = self.create_redis()
 
@@ -235,17 +236,12 @@ class TestFakeStrictRedis(unittest.TestCase):
     def test_incr_with_float(self):
         with self.assertRaises(redis.ResponseError):
             self.redis.incr('foo', 2.0)
-    
+
     def test_incr_followed_by_mget(self):
         self.redis.set('foo', 15)
         self.assertEqual(self.redis.incr('foo', 5), 20)
         self.assertEqual(self.redis.get('foo'), b'20')
 
-    def test_incr_bad_type(self):
-        self.redis.set('foo', 'bar')
-        with self.assertRaises(redis.ResponseError):
-            self.redis.incr('foo', 15)
-
     def test_incr_followed_by_mget_returns_strings(self):
         self.redis.incr('foo', 1)
         self.assertEqual(self.redis.mget(['foo']), [b'1'])
@@ -361,11 +357,53 @@ class TestFakeStrictRedis(unittest.TestCase):
             self.redis.setex('foo', timedelta(seconds=100), 'bar'), True)
         self.assertEqual(self.redis.get('foo'), b'bar')
 
+    def test_set_ex(self):
+        self.assertEqual(self.redis.set('foo', 'bar', ex=100), True)
+        self.assertEqual(self.redis.get('foo'), b'bar')
+
+    def test_set_ex_using_timedelta(self):
+        self.assertEqual(
+            self.redis.set('foo', 'bar', ex=timedelta(seconds=100)), True)
+        self.assertEqual(self.redis.get('foo'), b'bar')
+
+    def test_set_px(self):
+        self.assertEqual(self.redis.set('foo', 'bar', px=100), True)
+        self.assertEqual(self.redis.get('foo'), b'bar')
+
+    def test_set_px_using_timedelta(self):
+        self.assertEqual(
+            self.redis.set('foo', 'bar', px=timedelta(milliseconds=100)), True)
+        self.assertEqual(self.redis.get('foo'), b'bar')
+
+    def test_set_raises_wrong_ex(self):
+        with self.assertRaises(ResponseError):
+            self.redis.set('foo', 'bar', ex=-100)
+
+    def test_set_using_timedelta_raises_wrong_ex(self):
+        with self.assertRaises(ResponseError):
+            self.redis.set('foo', 'bar', ex=timedelta(seconds=-100))
+
+    def test_set_raises_wrong_px(self):
+        with self.assertRaises(ResponseError):
+            self.redis.set('foo', 'bar', px=-100)
+
+    def test_set_using_timedelta_raises_wrong_px(self):
+        with self.assertRaises(ResponseError):
+            self.redis.set('foo', 'bar', px=timedelta(milliseconds=-100))
+
+    def test_setex_raises_wrong_ex(self):
+        with self.assertRaises(ResponseError):
+            self.redis.setex('foo', -100, 'bar')
+
+    def test_setex_using_timedelta_raises_wrong_ex(self):
+        with self.assertRaises(ResponseError):
+            self.redis.setex('foo', timedelta(seconds=-100), 'bar')
+
     def test_setnx(self):
         self.assertEqual(self.redis.setnx('foo', 'bar'), True)
-        self.assertEqual(self.redis.get('foo'),  b'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
         self.assertEqual(self.redis.setnx('foo', 'baz'), False)
-        self.assertEqual(self.redis.get('foo'),  b'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
 
     def test_delete(self):
         self.redis['foo'] = 'bar'
@@ -1131,7 +1169,7 @@ class TestFakeStrictRedis(unittest.TestCase):
 
     def test_zrem_numeric_member(self):
         self.redis.zadd('foo', **{'128': 13.0, '129': 12.0})
-        self.assertEqual(self.redis.zrem('foo',  128), True)
+        self.assertEqual(self.redis.zrem('foo', 128), True)
         self.assertEqual(self.redis.zrange('foo', 0, -1), [b'129'])
 
     def test_zscore(self):
@@ -1423,7 +1461,6 @@ class TestFakeStrictRedis(unittest.TestCase):
         self.assertEqual(self.redis.zrevrangebylex('foo', b'-', b'[o'),
                          [])
 
-
     def test_zrevrangebylex_with_limit(self):
         self.redis.zadd('foo', one_a=0)
         self.redis.zadd('foo', two_a=0)
@@ -1822,13 +1859,13 @@ class TestFakeStrictRedis(unittest.TestCase):
         res = p.execute()
 
         # Check return values returned as list.
-        self.assertEqual([True, b'bar', 1, 2, [b'quux2', b'quux']], res)
+        self.assertEqual(res, [True, b'bar', 1, 2, [b'quux2', b'quux']])
 
         # Check side effects happened as expected.
-        self.assertEqual([b'quux2', b'quux'], self.redis.lrange('baz', 0, -1))
+        self.assertEqual(self.redis.lrange('baz', 0, -1), [b'quux2', b'quux'])
 
         # Check that the command buffer has been emptied.
-        self.assertEqual([], p.execute())
+        self.assertEqual(p.execute(), [])
 
     def test_pipeline_ignore_errors(self):
         """Test the pipeline ignoring errors when asked."""
@@ -1870,7 +1907,7 @@ class TestFakeStrictRedis(unittest.TestCase):
         p = self.redis.pipeline(transaction=False)
         res = p.set('baz', 'quux').get('baz').execute()
 
-        self.assertEqual([True, b'quux'], res)
+        self.assertEqual(res, [True, b'quux'])
 
     def test_pipeline_raises_when_watched_key_changed(self):
         self.redis.set('foo', 'bar')
@@ -1879,7 +1916,7 @@ class TestFakeStrictRedis(unittest.TestCase):
         self.addCleanup(p.reset)
 
         p.watch('greet', 'foo')
-        nextf = p.get('foo') + b'baz'
+        nextf = fakeredis.to_bytes(p.get('foo')) + b'baz'
         # Simulate change happening on another thread.
         self.redis.rpush('greet', 'world')
         # Begin pipelining.
@@ -1897,7 +1934,7 @@ class TestFakeStrictRedis(unittest.TestCase):
         try:
             # Only watch one of the 2 keys.
             p.watch('foo')
-            nextf = p.get('foo') + b'baz'
+            nextf = fakeredis.to_bytes(p.get('foo')) + b'baz'
             # Simulate change happening on another thread.
             self.redis.rpush('greet', 'world')
             p.multi()
@@ -1905,7 +1942,7 @@ class TestFakeStrictRedis(unittest.TestCase):
             p.execute()
 
             # Check the commands were executed.
-            self.assertEqual(b'barbaz', self.redis.get('foo'))
+            self.assertEqual(self.redis.get('foo'), b'barbaz')
         finally:
             p.reset()
 
@@ -1916,7 +1953,7 @@ class TestFakeStrictRedis(unittest.TestCase):
         try:
             # Also watch a nonexistent key.
             p.watch('foo', 'bam')
-            nextf = p.get('foo') + b'baz'
+            nextf = fakeredis.to_bytes(p.get('foo')) + b'baz'
             # Simulate change happening on another thread.
             self.redis.rpush('greet', 'world')
             p.multi()
@@ -1924,7 +1961,7 @@ class TestFakeStrictRedis(unittest.TestCase):
             p.execute()
 
             # Check the commands were executed.
-            self.assertEqual(b'barbaz', self.redis.get('foo'))
+            self.assertEqual(self.redis.get('foo'), b'barbaz')
         finally:
             p.reset()
 
@@ -2031,8 +2068,12 @@ class TestFakeStrictRedis(unittest.TestCase):
                             'channel': b'channel', 'data': 1}
         message = pubsub.get_message()
         keys = list(pubsub.channels.keys())
-        key = keys[0] if type(keys[0]) == bytes\
-            else bytes(keys[0], encoding='utf-8')
+
+        key = keys[0]
+        if not self.decode_responses:
+            key = (key if type(key) == bytes
+                   else bytes(key, encoding='utf-8'))
+
         self.assertEqual(len(keys), 1)
         self.assertEqual(key, b'channel')
         self.assertEqual(message, expected_message)
@@ -2121,10 +2162,14 @@ class TestFakeStrictRedis(unittest.TestCase):
         pubsub.subscribe(channel)
         pubsub.psubscribe(*patterns)
         sleep(1)
-        pubsub.get_message()
-        pubsub.get_message()
-        pubsub.get_message()
-        pubsub.get_message()
+        msg1 = pubsub.get_message()
+        msg2 = pubsub.get_message()
+        msg3 = pubsub.get_message()
+        msg4 = pubsub.get_message()
+        self.assertEqual(msg1['type'], 'subscribe')
+        self.assertEqual(msg2['type'], 'psubscribe')
+        self.assertEqual(msg3['type'], 'psubscribe')
+        self.assertEqual(msg4['type'], 'psubscribe')
 
         q = Queue()
         t = threading.Thread(target=_listen, args=(pubsub, q))
@@ -2150,6 +2195,50 @@ class TestFakeStrictRedis(unittest.TestCase):
         self.assertEqual(msg4['data'], msg)
         self.assertIn(msg4['channel'], bpatterns)
 
+    @attr('slow')
+    def test_pubsub_ignore_sub_messages_listen(self):
+        def _listen(pubsub, q):
+            count = 0
+            for message in pubsub.listen():
+                q.put(message)
+                count += 1
+                if count == 4:
+                    pubsub.close()
+
+        channel = 'ch1'
+        patterns = ['ch1*', 'ch[1]', 'ch?']
+        pubsub = self.redis.pubsub(ignore_subscribe_messages=True)
+        pubsub.subscribe(channel)
+        pubsub.psubscribe(*patterns)
+        sleep(1)
+
+        q = Queue()
+        t = threading.Thread(target=_listen, args=(pubsub, q))
+        t.start()
+        msg = 'hello world'
+        self.redis.publish(channel, msg)
+        t.join()
+
+        msg1 = q.get()
+        msg2 = q.get()
+        msg3 = q.get()
+        msg4 = q.get()
+
+        if self.decode_responses:
+            bpatterns = patterns + [channel]
+        else:
+            bpatterns = [pattern.encode() for pattern in patterns]
+            bpatterns.append(channel.encode())
+        msg = msg.encode()
+        self.assertEqual(msg1['data'], msg)
+        self.assertIn(msg1['channel'], bpatterns)
+        self.assertEqual(msg2['data'], msg)
+        self.assertIn(msg2['channel'], bpatterns)
+        self.assertEqual(msg3['data'], msg)
+        self.assertIn(msg3['channel'], bpatterns)
+        self.assertEqual(msg4['data'], msg)
+        self.assertIn(msg4['channel'], bpatterns)
+
     def test_pfadd(self):
         key = "hll-pfadd"
         self.assertEqual(
@@ -2295,6 +2384,8 @@ class TestFakeStrictRedis(unittest.TestCase):
 
 
 class TestFakeRedis(unittest.TestCase):
+    decode_responses = False
+
     def setUp(self):
         self.redis = self.create_redis()
 
@@ -2461,6 +2552,43 @@ class TestFakeRedis(unittest.TestCase):
         self.assertEqual(self.redis.expire('bar', 1), False)
 
     @attr('slow')
+    def test_expire_should_expire_immediately_with_millisecond_timedelta(self):
+        self.redis.set('foo', 'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        self.redis.expire('foo', timedelta(milliseconds=750))
+        self.assertEqual(self.redis.get('foo'), None)
+        self.assertEqual(self.redis.expire('bar', 1), False)
+
+    @attr('slow')
+    def test_pexpire_should_expire_key(self):
+        self.redis.set('foo', 'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        self.redis.pexpire('foo', 150)
+        sleep(0.2)
+        self.assertEqual(self.redis.get('foo'), None)
+        self.assertEqual(self.redis.pexpire('bar', 1), False)
+
+    def test_pexpire_should_return_truthy_for_existing_key(self):
+        self.redis.set('foo', 'bar')
+        rv = self.redis.pexpire('foo', 1)
+        self.assertIs(bool(rv), True)
+
+    def test_pexpire_should_return_falsey_for_missing_key(self):
+        rv = self.redis.pexpire('missing', 1)
+        self.assertIs(bool(rv), False)
+
+    @attr('slow')
+    def test_pexpire_should_expire_key_using_timedelta(self):
+        self.redis.set('foo', 'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        self.redis.pexpire('foo', timedelta(milliseconds=750))
+        sleep(0.5)
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        sleep(0.5)
+        self.assertEqual(self.redis.get('foo'), None)
+        self.assertEqual(self.redis.pexpire('bar', 1), False)
+
+    @attr('slow')
     def test_expireat_should_expire_key_by_datetime(self):
         self.redis.set('foo', 'bar')
         self.assertEqual(self.redis.get('foo'), b'bar')
@@ -2487,6 +2615,33 @@ class TestFakeRedis(unittest.TestCase):
         rv = self.redis.expireat('missing', int(time() + 1))
         self.assertIs(rv, False)
 
+    @attr('slow')
+    def test_pexpireat_should_expire_key_by_datetime(self):
+        self.redis.set('foo', 'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        self.redis.pexpireat('foo', datetime.now() + timedelta(milliseconds=150))
+        sleep(0.2)
+        self.assertEqual(self.redis.get('foo'), None)
+        self.assertEqual(self.redis.pexpireat('bar', datetime.now()), False)
+
+    @attr('slow')
+    def test_pexpireat_should_expire_key_by_timestamp(self):
+        self.redis.set('foo', 'bar')
+        self.assertEqual(self.redis.get('foo'), b'bar')
+        self.redis.pexpireat('foo', int(time() * 1000 + 150))
+        sleep(0.2)
+        self.assertEqual(self.redis.get('foo'), None)
+        self.assertEqual(self.redis.expire('bar', 1), False)
+
+    def test_pexpireat_should_return_true_for_existing_key(self):
+        self.redis.set('foo', 'bar')
+        rv = self.redis.pexpireat('foo', int(time() * 1000 + 150))
+        self.assertIs(bool(rv), True)
+
+    def test_pexpireat_should_return_false_for_missing_key(self):
+        rv = self.redis.pexpireat('missing', int(time() * 1000 + 150))
+        self.assertIs(bool(rv), False)
+
     def test_ttl_should_return_none_for_non_expiring_key(self):
         self.redis.set('foo', 'bar')
         self.assertEqual(self.redis.get('foo'), b'bar')
@@ -2522,6 +2677,44 @@ class TestFakeRedis(unittest.TestCase):
                            long_long_c_max * 1000 - d,
                            long_long_c_max * 1000)
 
+    def test_ttls_should_always_be_long(self):
+        self.redis.set('foo', 'bar')
+        self.redis.expire('foo', 1)
+        self.assertTrue(type(self.redis.ttl('foo')) is long)
+        self.assertTrue(type(self.redis.pttl('foo')) is long)
+
+    def test_expire_should_not_handle_floating_point_values(self):
+        self.redis.set('foo', 'bar')
+        with self.assertRaisesRegexp(
+                redis.ResponseError, 'value is not an integer or out of range'):
+            self.redis.expire('something_new', 1.2)
+            self.redis.pexpire('something_new', 1000.2)
+            self.redis.expire('some_unused_key', 1.2)
+            self.redis.pexpire('some_unused_key', 1000.2)
+
+
+class DecodeMixin(object):
+    decode_responses = True
+
+    def assertEqual(self, a, b, msg=None):
+        super(DecodeMixin, self).assertEqual(a, fakeredis._decode(b), msg)
+
+    def assertIn(self, member, container, msg=None):
+        super(DecodeMixin, self).assertIn(fakeredis._decode(member), fakeredis._decode(container))
+
+    def assertItemsEqual(self, a, b):
+        super(DecodeMixin, self).assertItemsEqual(a, fakeredis._decode(b))
+
+
+class TestFakeStrictRedisDecodeResponses(DecodeMixin, TestFakeStrictRedis):
+    def create_redis(self, db=0):
+        return fakeredis.FakeStrictRedis(db=db, decode_responses=True)
+
+
+class TestFakeRedisDecodeResponses(DecodeMixin, TestFakeRedis):
+    def create_redis(self, db=0):
+        return fakeredis.FakeRedis(db=db, decode_responses=True)
+
 
 @redis_must_be_running
 class TestRealRedis(TestFakeRedis):
@@ -2535,6 +2728,18 @@ class TestRealStrictRedis(TestFakeStrictRedis):
         return redis.StrictRedis('localhost', port=6379, db=db)
 
 
+ at redis_must_be_running
+class TestRealRedisDecodeResponses(TestFakeRedisDecodeResponses):
+    def create_redis(self, db=0):
+        return redis.Redis('localhost', port=6379, db=db, decode_responses=True)
+
+
+ at redis_must_be_running
+class TestRealStrictRedisDecodeResponses(TestFakeStrictRedisDecodeResponses):
+    def create_redis(self, db=0):
+        return redis.StrictRedis('localhost', port=6379, db=db, decode_responses=True)
+
+
 class TestInitArgs(unittest.TestCase):
     def test_can_accept_any_kwargs(self):
         fakeredis.FakeRedis(foo='bar', bar='baz')

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-fakeredis.git



More information about the Python-modules-commits mailing list