summaryrefslogtreecommitdiff
path: root/redis/connection.py
diff options
context:
space:
mode:
authorandy <andy@andymccurdy.com>2012-06-10 23:29:41 -0700
committerandy <andy@andymccurdy.com>2012-06-10 23:29:41 -0700
commit17ade97a064248f309b771c8ccf3a9ea96e79356 (patch)
treeaed1cccf4784ca9f944a5c77d09dcdf392bb68cb /redis/connection.py
parentd2a7156f7fd108a24d8aa321e2ecd67b3f1f34c6 (diff)
parenta99b650071ff83368d1b3b1d75d8870a682a2390 (diff)
downloadredis-py-17ade97a064248f309b771c8ccf3a9ea96e79356.tar.gz
Merge remote-tracking branch 'encoding/2.4.11-fix' into encoding
Conflicts: redis/connection.py
Diffstat (limited to 'redis/connection.py')
-rw-r--r--redis/connection.py35
1 files changed, 25 insertions, 10 deletions
diff --git a/redis/connection.py b/redis/connection.py
index 6df60d8..8036784 100644
--- a/redis/connection.py
+++ b/redis/connection.py
@@ -23,6 +23,7 @@ except ImportError:
class PythonParser(object):
"Plain Python parsing class"
MAX_READ_LENGTH = 1000000
+ encoding = None
def __init__(self):
self._fp = None
@@ -36,6 +37,8 @@ class PythonParser(object):
def on_connect(self, connection):
"Called when the socket connects"
self._fp = connection._sock.makefile('rb')
+ if connection.decode_responses:
+ self.encoding = connection.encoding
def on_disconnect(self):
"Called when the socket disconnects"
@@ -81,6 +84,9 @@ class PythonParser(object):
byte, response = response[0], response[1:]
+ if byte not in ('-', '+', ':', '$', '*'):
+ raise InvalidResponse("Protocol Error")
+
# server returned an error
if byte == '-':
if response.startswith('ERR '):
@@ -92,24 +98,25 @@ class PythonParser(object):
raise ConnectionError("Redis is loading data into memory")
# single value
elif byte == '+':
- return response
+ pass
# int value
elif byte == ':':
- return long(response)
+ response = long(response)
# bulk response
elif byte == '$':
length = int(response)
if length == -1:
return None
response = self.read(length)
- return response
# multi-bulk response
elif byte == '*':
length = int(response)
if length == -1:
return None
- return [self.read_response() for i in xrange(length)]
- raise InvalidResponse("Protocol Error")
+ response = [self.read_response() for i in xrange(length)]
+ if isinstance(response, str) and self.encoding:
+ response = response.decode(self.encoding)
+ return response
class HiredisParser(object):
"Parser class for connections using Hiredis"
@@ -125,9 +132,13 @@ class HiredisParser(object):
def on_connect(self, connection):
self._sock = connection._sock
- self._reader = hiredis.Reader(
- protocolError=InvalidResponse,
- replyError=ResponseError)
+ kwargs = {
+ 'protocolError': InvalidResponse,
+ 'replyError': ResponseError,
+ }
+ if connection.decode_responses:
+ kwargs['encoding'] = connection.encoding
+ self._reader = hiredis.Reader(**kwargs)
def on_disconnect(self):
self._sock = None
@@ -163,7 +174,8 @@ class Connection(object):
"Manages TCP communication to and from a Redis server"
def __init__(self, host='localhost', port=6379, db=0, password=None,
socket_timeout=None, encoding='utf-8',
- encoding_errors='strict', parser_class=DefaultParser):
+ encoding_errors='strict', decode_responses=False,
+ parser_class=DefaultParser):
self.pid = os.getpid()
self.host = host
self.port = port
@@ -172,6 +184,7 @@ class Connection(object):
self.socket_timeout = socket_timeout
self.encoding = encoding
self.encoding_errors = encoding_errors
+ self.decode_responses = decode_responses
self._sock = None
self._parser = parser_class()
@@ -285,7 +298,8 @@ class Connection(object):
class UnixDomainSocketConnection(Connection):
def __init__(self, path='', db=0, password=None,
socket_timeout=None, encoding='utf-8',
- encoding_errors='strict', parser_class=DefaultParser):
+ encoding_errors='strict', decode_responses=False,
+ parser_class=DefaultParser):
self.pid = os.getpid()
self.path = path
self.db = db
@@ -293,6 +307,7 @@ class UnixDomainSocketConnection(Connection):
self.socket_timeout = socket_timeout
self.encoding = encoding
self.encoding_errors = encoding_errors
+ self.decode_responses = decode_responses
self._sock = None
self._parser = parser_class()