Skip to content

Commit

Permalink
Use repr to encode floats in to_bytes
Browse files Browse the repository at this point in the history
This ensures that no precision is lost when encoding 64-bit floats. This
matches the encoding logic in redis-py. Tests are added for `set`,
`incrbyfloat` and `hincrbyfloat`.
  • Loading branch information
bmerry committed Nov 10, 2017
1 parent 0e0cf4c commit 865f5d4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
4 changes: 4 additions & 0 deletions fakeredis.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
def to_bytes(x, charset=DEFAULT_ENCODING, errors='strict'):
if isinstance(x, unicode):
return x.encode(charset, errors)
if isinstance(x, float):
return repr(x)
if isinstance(x, (bytes, bytearray, buffer)) or hasattr(x, '__str__'):
return bytes(x)
if hasattr(x, '__unicode__'):
Expand Down Expand Up @@ -76,6 +78,8 @@ def to_bytes(x, charset=sys.getdefaultencoding(), errors='strict'):
return bytes(x)
if isinstance(x, str):
return x.encode(charset, errors)
if isinstance(x, float):
return repr(x).encode(charset, errors)
if hasattr(x, '__str__'):
return str(x).encode(charset, errors)
raise TypeError('expected bytes or str, not ' + type(x).__name__)
Expand Down
15 changes: 15 additions & 0 deletions test_fakeredis.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ def test_set_None_value(self):
self.assertEqual(self.redis.set('foo', None), True)
self.assertEqual(self.redis.get('foo'), b'None')

def test_set_float_value(self):
x = 1.23456789123456789
self.redis.set('foo', x)
self.assertEqual(float(self.redis.get('foo')), x)

def test_saving_non_ascii_chars_as_value(self):
self.assertEqual(self.redis.set('foo', 'Ñandu'), True)
self.assertEqual(self.redis.get('foo'),
Expand Down Expand Up @@ -287,6 +292,11 @@ def test_incrbyfloat_bad_type(self):
with self.assertRaisesRegexp(redis.ResponseError, 'not a valid float'):
self.redis.incrbyfloat('foo', 1.0)

def test_incrbyfloat_precision(self):
x = 1.23456789123456789
self.assertEqual(self.redis.incrbyfloat('foo', x), x)
self.assertEqual(float(self.redis.get('foo')), x)

def test_decr(self):
self.redis.set('foo', 10)
self.assertEqual(self.redis.decr('foo'), 9)
Expand Down Expand Up @@ -884,6 +894,11 @@ def test_hincrbyfloat_with_non_float_amount_raises_error(self):
with self.assertRaises(redis.ResponseError):
self.redis.hincrbyfloat('foo', 'counter', 'cat')

def test_hincrbyfloat_precision(self):
x = 1.23456789123456789
self.assertEqual(self.redis.hincrbyfloat('foo', 'bar', x), x)
self.assertEqual(float(self.redis.hget('foo', 'bar')), x)

def test_hsetnx(self):
self.assertEqual(self.redis.hsetnx('foo', 'newkey', 'v1'), True)
self.assertEqual(self.redis.hsetnx('foo', 'newkey', 'v1'), False)
Expand Down

0 comments on commit 865f5d4

Please sign in to comment.