From 108f15c8638291962aa85d88752d19a7280fef64 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 4 Mar 2014 16:11:17 +0100 Subject: [PATCH] Port to Python 3.3 --- pymemcache/client.py | 246 ++++++++++---------- pymemcache/test/benchmark.py | 12 +- pymemcache/test/integration.py | 152 ++++++------ pymemcache/test/test_client.py | 407 +++++++++++++++++---------------- pymemcache/test/test_utils.py | 46 ++-- pymemcache/test/utils.py | 12 +- setup.py | 3 +- 7 files changed, 452 insertions(+), 426 deletions(-) diff --git a/pymemcache/client.py b/pymemcache/client.py index 56a9a293..0778b5c2 100644 --- a/pymemcache/client.py +++ b/pymemcache/client.py @@ -71,16 +71,17 @@ def json_deserializer(key, value, flags): import socket +import six RECV_SIZE = 4096 VALID_STORE_RESULTS = { - 'set': ('STORED',), - 'add': ('STORED', 'NOT_STORED'), - 'replace': ('STORED', 'NOT_STORED'), - 'append': ('STORED', 'NOT_STORED'), - 'prepend': ('STORED', 'NOT_STORED'), - 'cas': ('STORED', 'EXISTS', 'NOT_FOUND'), + b'set': (b'STORED',), + b'add': (b'STORED', b'NOT_STORED'), + b'replace': (b'STORED', b'NOT_STORED'), + b'append': (b'STORED', b'NOT_STORED'), + b'prepend': (b'STORED', b'NOT_STORED'), + b'cas': (b'STORED', b'EXISTS', b'NOT_FOUND'), } @@ -88,24 +89,24 @@ def json_deserializer(key, value, flags): # need mapping into native Python types STAT_TYPES = { # General stats - 'version': str, - 'rusage_user': lambda value: float(value.replace(':', '.')), - 'rusage_system': lambda value: float(value.replace(':', '.')), - 'hash_is_expanding': lambda value: int(value) != 0, - 'slab_reassign_running': lambda value: int(value) != 0, + b'version': six.binary_type, + b'rusage_user': lambda value: float(value.replace(b':', b'.')), + b'rusage_system': lambda value: float(value.replace(b':', b'.')), + b'hash_is_expanding': lambda value: int(value) != 0, + b'slab_reassign_running': lambda value: int(value) != 0, # Settings stats - 'inter': str, - 'evictions': lambda value: value == 'on', - 'growth_factor': float, - 'stat_key_prefix': str, - 'umask': lambda value: int(value, 8), - 'detail_enabled': lambda value: int(value) != 0, - 'cas_enabled': lambda value: int(value) != 0, - 'auth_enabled_sasl': lambda value: value == 'yes', - 'maxconns_fast': lambda value: int(value) != 0, - 'slab_reassign': lambda value: int(value) != 0, - 'slab_automove': lambda value: int(value) != 0, + b'inter': six.binary_type, + b'evictions': lambda value: value == b'on', + b'growth_factor': float, + b'stat_key_prefix': six.binary_type, + b'umask': lambda value: int(value, 8), + b'detail_enabled': lambda value: int(value) != 0, + b'cas_enabled': lambda value: int(value) != 0, + b'auth_enabled_sasl': lambda value: value == b'yes', + b'maxconns_fast': lambda value: int(value) != 0, + b'slab_reassign': lambda value: int(value) != 0, + b'slab_automove': lambda value: int(value) != 0, } @@ -262,7 +263,7 @@ def __init__(self, self.ignore_exc = ignore_exc self.socket_module = socket_module self.sock = None - self.buf = '' + self.buf = b'' def _connect(self): sock = self.socket_module.socket(self.socket_module.AF_INET, @@ -284,7 +285,7 @@ def close(self): except Exception: pass self.sock = None - self.buf = '' + self.buf = b'' def set(self, key, value, expire=0, noreply=True): """ @@ -302,7 +303,7 @@ def set(self, key, value, expire=0, noreply=True): raised, the set may or may not have occurred. If noreply is True, then a successful return does not guarantee a successful set. """ - return self._store_cmd('set', key, expire, noreply, value) + return self._store_cmd(b'set', key, expire, noreply, value) def set_many(self, values, expire=0, noreply=True): """ @@ -324,7 +325,7 @@ def set_many(self, values, expire=0, noreply=True): # TODO: make this more performant by sending all the values first, then # waiting for all the responses. - for key, value in values.iteritems(): + for key, value in six.iteritems(values): self.set(key, value, expire, noreply) return True @@ -344,7 +345,7 @@ def add(self, key, value, expire=0, noreply=True): return value is True if the value was stgored, and False if it was not (because the key already existed). """ - return self._store_cmd('add', key, expire, noreply, value) + return self._store_cmd(b'add', key, expire, noreply, value) def replace(self, key, value, expire=0, noreply=True): """ @@ -362,7 +363,7 @@ def replace(self, key, value, expire=0, noreply=True): the value was stored and False if it wasn't (because the key didn't already exist). """ - return self._store_cmd('replace', key, expire, noreply, value) + return self._store_cmd(b'replace', key, expire, noreply, value) def append(self, key, value, expire=0, noreply=True): """ @@ -378,7 +379,7 @@ def append(self, key, value, expire=0, noreply=True): Returns: True. """ - return self._store_cmd('append', key, expire, noreply, value) + return self._store_cmd(b'append', key, expire, noreply, value) def prepend(self, key, value, expire=0, noreply=True): """ @@ -394,7 +395,7 @@ def prepend(self, key, value, expire=0, noreply=True): Returns: True. """ - return self._store_cmd('prepend', key, expire, noreply, value) + return self._store_cmd(b'prepend', key, expire, noreply, value) def cas(self, key, value, cas, expire=0, noreply=False): """ @@ -413,7 +414,7 @@ def cas(self, key, value, cas, expire=0, noreply=False): the key didn't exist, False if it existed but had a different cas value and True if it existed and was changed. """ - return self._store_cmd('cas', key, expire, noreply, value, cas) + return self._store_cmd(b'cas', key, expire, noreply, value, cas) def get(self, key): """ @@ -425,7 +426,7 @@ def get(self, key): Returns: The value for the key, or None if the key wasn't found. """ - return self._fetch_cmd('get', [key], False).get(key, None) + return self._fetch_cmd(b'get', [key], False).get(key, None) def get_many(self, keys): """ @@ -442,7 +443,7 @@ def get_many(self, keys): if not keys: return {} - return self._fetch_cmd('get', keys, False) + return self._fetch_cmd(b'get', keys, False) def gets(self, key): """ @@ -454,7 +455,7 @@ def gets(self, key): Returns: A tuple of (key, cas), or (None, None) if the key was not found. """ - return self._fetch_cmd('gets', [key], True).get(key, (None, None)) + return self._fetch_cmd(b'gets', [key], True).get(key, (None, None)) def gets_many(self, keys): """ @@ -471,7 +472,7 @@ def gets_many(self, keys): if not keys: return {} - return self._fetch_cmd('gets', keys, True) + return self._fetch_cmd(b'gets', keys, True) def delete(self, key, noreply=True): """ @@ -484,11 +485,14 @@ def delete(self, key, noreply=True): If noreply is True, always returns True. Otherwise returns True if the key was deleted, and False if it wasn't found. """ - cmd = 'delete {0}{1}\r\n'.format(key, ' noreply' if noreply else '') - result = self._misc_cmd(cmd, 'delete', noreply) + cmd = b'delete ' + key + if noreply: + cmd += b' noreply' + cmd += b'\r\n' + result = self._misc_cmd(cmd, b'delete', noreply) if noreply: return True - return result == 'DELETED' + return result == b'DELETED' def delete_many(self, keys, noreply=True): """ @@ -526,14 +530,14 @@ def incr(self, key, value, noreply=False): If noreply is True, always returns None. Otherwise returns the new value of the key, or None if the key wasn't found. """ - cmd = "incr {0} {1}{2}\r\n".format( - key, - str(value), - ' noreply' if noreply else '') - result = self._misc_cmd(cmd, 'incr', noreply) + cmd = b'incr ' + key + b' ' + six.text_type(value).encode('ascii') + if noreply: + cmd += b' noreply' + cmd += b'\r\n' + result = self._misc_cmd(cmd, b'incr', noreply) if noreply: return None - if result == 'NOT_FOUND': + if result == b'NOT_FOUND': return None return int(result) @@ -550,14 +554,14 @@ def decr(self, key, value, noreply=False): If noreply is True, always returns None. Otherwise returns the new value of the key, or None if the key wasn't found. """ - cmd = "decr {0} {1}{2}\r\n".format( - key, - str(value), - ' noreply' if noreply else '') - result = self._misc_cmd(cmd, 'decr', noreply) + cmd = b'decr ' + key + b' ' + six.text_type(value).encode('ascii') + if noreply: + cmd += b' noreply' + cmd += b'\r\n' + result = self._misc_cmd(cmd, b'decr', noreply) if noreply: return None - if result == 'NOT_FOUND': + if result == b'NOT_FOUND': return None return int(result) @@ -575,14 +579,14 @@ def touch(self, key, expire=0, noreply=True): True if the expiration time was updated, False if the key wasn't found. """ - cmd = "touch {0} {1}{2}\r\n".format( - key, - expire, - ' noreply' if noreply else '') - result = self._misc_cmd(cmd, 'touch', noreply) + cmd = b'touch ' + key + b' ' + six.text_type(expire).encode('ascii') + if noreply: + cmd += b' noreply' + cmd += b'\r\n' + result = self._misc_cmd(cmd, b'touch', noreply) if noreply: return True - return result == 'TOUCHED' + return result == b'TOUCHED' def stats(self, *args): """ @@ -599,9 +603,9 @@ def stats(self, *args): Returns: A dict of the returned stats. """ - result = self._fetch_cmd('stats', args, False) + result = self._fetch_cmd(b'stats', args, False) - for key, value in result.iteritems(): + for key, value in six.iteritems(result): converter = STAT_TYPES.get(key, int) try: result[key] = converter(value) @@ -622,11 +626,14 @@ def flush_all(self, delay=0, noreply=True): Returns: True. """ - cmd = "flush_all {0}{1}\r\n".format(delay, ' noreply' if noreply else '') - result = self._misc_cmd(cmd, 'flush_all', noreply) + cmd = b'flush_all ' + six.text_type(delay).encode('ascii') + if noreply: + cmd += b' noreply' + cmd += b'\r\n' + result = self._misc_cmd(cmd, b'flush_all', noreply) if noreply: return True - return result == 'OK' + return result == b'OK' def quit(self): """ @@ -636,37 +643,38 @@ def quit(self): method on this object will re-open the connection, so this object can be re-used after quit. """ - cmd = "quit\r\n" - self._misc_cmd(cmd, 'quit', True) + cmd = b"quit\r\n" + self._misc_cmd(cmd, b'quit', True) self.close() def _raise_errors(self, line, name): - if line.startswith('ERROR'): + if line.startswith(b'ERROR'): raise MemcacheUnknownCommandError(name) - if line.startswith('CLIENT_ERROR'): - error = line[line.find(' ') + 1:] + if line.startswith(b'CLIENT_ERROR'): + error = line[line.find(b' ') + 1:] raise MemcacheClientError(error) - if line.startswith('SERVER_ERROR'): - error = line[line.find(' ') + 1:] + if line.startswith(b'SERVER_ERROR'): + error = line[line.find(b' ') + 1:] raise MemcacheServerError(error) def _fetch_cmd(self, name, keys, expect_cas): if not self.sock: self._connect() - try: - key_strs = [] - for key in keys: - key = str(key) - if ' ' in key: - raise MemcacheIllegalInputError("Key contains spaces: %s", key) - key_strs.append(key) - except UnicodeEncodeError as e: - raise MemcacheIllegalInputError(str(e)) + key_strs = [] + for key in keys: + if not isinstance(key, six.binary_type): + try: + key = six.text_type(key).encode('ascii') + except UnicodeEncodeError as e: + raise MemcacheIllegalInputError(str(e)) + if b' ' in key: + raise MemcacheIllegalInputError("Key contains spaces: %s", key) + key_strs.append(key) - cmd = '{0} {1}\r\n'.format(name, ' '.join(key_strs)) + cmd = name + b' ' + b' '.join(key_strs) + b'\r\n' try: self.sock.sendall(cmd) @@ -676,13 +684,17 @@ def _fetch_cmd(self, name, keys, expect_cas): self.buf, line = _readline(self.sock, self.buf) self._raise_errors(line, name) - if line == 'END': + if line == b'END': return result - elif line.startswith('VALUE'): + elif line.startswith(b'VALUE'): if expect_cas: _, key, flags, size, cas = line.split() else: - _, key, flags, size = line.split() + try: + _, key, flags, size = line.split() + except Exception as e: + raise ValueError("Unable to parse line %s: %s" + % (line, str(e))) self.buf, value = _readvalue(self.sock, self.buf, @@ -695,7 +707,7 @@ def _fetch_cmd(self, name, keys, expect_cas): result[key] = (value, cas) else: result[key] = value - elif name == 'stats' and line.startswith('STAT'): + elif name == b'stats' and line.startswith(b'STAT'): _, key, value = line.split() result[key] = value else: @@ -707,12 +719,14 @@ def _fetch_cmd(self, name, keys, expect_cas): raise def _store_cmd(self, name, key, expire, noreply, data, cas=None): - try: - key = str(key) - if ' ' in key: - raise MemcacheIllegalInputError("Key contains spaces: %s", key) - except UnicodeEncodeError as e: - raise MemcacheIllegalInputError(str(e)) + if not isinstance(key, six.binary_type): + try: + key = six.text_type(key).encode('ascii') + except UnicodeEncodeError as e: + raise MemcacheIllegalInputError(str(e)) + + if b' ' in key: + raise MemcacheIllegalInputError("Key contains spaces: %s", key) if not self.sock: self._connect() @@ -722,22 +736,22 @@ def _store_cmd(self, name, key, expire, noreply, data, cas=None): else: flags = 0 - try: - data = str(data) - except UnicodeEncodeError as e: - raise MemcacheIllegalInputError(str(e)) - - if cas is not None and noreply: - extra = ' {0} noreply'.format(cas) - elif cas is not None and not noreply: - extra = ' {0}'.format(cas) - elif cas is None and noreply: - extra = ' noreply' - else: - extra = '' + if not isinstance(data, six.binary_type): + try: + data = six.text_type(data).encode('ascii') + except UnicodeEncodeError as e: + raise MemcacheIllegalInputError(str(e)) + + extra = b'' + if cas is not None: + extra += b' ' + cas + if noreply: + extra += b' noreply' - cmd = '{0} {1} {2} {3} {4}{5}\r\n{6}\r\n'.format( - name, key, flags, expire, len(data), extra, data) + cmd = (name + b' ' + key + b' ' + six.text_type(flags).encode('ascii') + + b' ' + six.text_type(expire).encode('ascii') + + b' ' + six.text_type(len(data)).encode('ascii') + extra + + b'\r\n' + data + b'\r\n') try: self.sock.sendall(cmd) @@ -749,13 +763,13 @@ def _store_cmd(self, name, key, expire, noreply, data, cas=None): self._raise_errors(line, name) if line in VALID_STORE_RESULTS[name]: - if line == 'STORED': + if line == b'STORED': return True - if line == 'NOT_STORED': + if line == b'NOT_STORED': return False - if line == 'NOT_FOUND': + if line == b'NOT_FOUND': return None - if line == 'EXISTS': + if line == b'EXISTS': return False else: raise MemcacheUnknownError(line[:32]) @@ -773,7 +787,7 @@ def _misc_cmd(self, cmd, cmd_name, noreply): if noreply: return - _, line = _readline(self.sock, '') + _, line = _readline(self.sock, b'') self._raise_errors(line, cmd_name) return line @@ -815,7 +829,7 @@ def _readline(sock, buf): """ chunks = [] - last_char = '' + last_char = b'' while True: # We're reading in chunks, so "\r\n" could appear in one chunk, @@ -824,18 +838,18 @@ def _readline(sock, buf): # This case must appear first, since the buffer could have # later \r\n characters in it and we want to get the first \r\n. - if last_char == '\r' and buf[0] == '\n': + if last_char == b'\r' and buf[0:1] == b'\n': # Strip the last character from the last chunk. chunks[-1] = chunks[-1][:-1] - return buf[1:], ''.join(chunks) - elif buf.find('\r\n') != -1: - before, sep, after = buf.partition("\r\n") + return buf[1:], b''.join(chunks) + elif buf.find(b'\r\n') != -1: + before, sep, after = buf.partition(b"\r\n") chunks.append(before) - return after, ''.join(chunks) + return after, b''.join(chunks) if buf: chunks.append(buf) - last_char = buf[-1] + last_char = buf[-1:] buf = sock.recv(RECV_SIZE) if not buf: @@ -884,4 +898,4 @@ def _readvalue(sock, buf, size): # Just remove the "\r\n" from the latest chunk chunks.append(buf[:rlen - 2]) - return buf[rlen:], ''.join(chunks) + return buf[rlen:], b''.join(chunks) diff --git a/pymemcache/test/benchmark.py b/pymemcache/test/benchmark.py index 49817f66..2fbda516 100644 --- a/pymemcache/test/benchmark.py +++ b/pymemcache/test/benchmark.py @@ -23,21 +23,21 @@ def test_client(name, client, size, count): start = time.time() - for i in xrange(count): + for i in range(count): client.set(str(i), value) - for i in xrange(count): + for i in range(count): client.get(str(i)) duration = time.time() - start - print "{0}: {1}".format(name, duration) + print("{0}: {1}".format(name, duration)) def test_pylibmc(host, port, size, count): try: import pylibmc except Exception: - print "Could not import pylibmc, skipping test..." + print("Could not import pylibmc, skipping test...") return client = pylibmc.Client(['{0}:{1}'.format(host, port)]) @@ -49,7 +49,7 @@ def test_memcache(host, port, size, count): try: import memcache except Exception: - print "Could not import pymemcache.client, skipping test..." + print("Could not import pymemcache.client, skipping test...") return client = memcache.Client(['{0}:{1}'.format(host, port)]) @@ -60,7 +60,7 @@ def test_pymemcache(host, port, size, count): try: import pymemcache.client except Exception: - print "Could not import pymemcache.client, skipping test..." + print("Could not import pymemcache.client, skipping test...") return client = pymemcache.client.Client((host, port)) diff --git a/pymemcache/test/integration.py b/pymemcache/test/integration.py index 8dba2732..37a60ea6 100644 --- a/pymemcache/test/integration.py +++ b/pymemcache/test/integration.py @@ -16,6 +16,8 @@ import json import socket +import six + from pymemcache.client import (Client, MemcacheClientError, MemcacheUnknownCommandError) from pymemcache.client import MemcacheIllegalInputError @@ -29,16 +31,16 @@ def get_set_test(host, port, socket_module): result = client.get('key') tools.assert_equal(result, None) - client.set('key', 'value', noreply=False) - result = client.get('key') - tools.assert_equal(result, 'value') + client.set(b'key', b'value', noreply=False) + result = client.get(b'key') + tools.assert_equal(result, b'value') - client.set('key2', 'value2', noreply=True) - result = client.get('key2') - tools.assert_equal(result, 'value2') + client.set(b'key2', b'value2', noreply=True) + result = client.get(b'key2') + tools.assert_equal(result, b'value2') - result = client.get_many(['key', 'key2']) - tools.assert_equal(result, {'key': 'value', 'key2': 'value2'}) + result = client.get_many([b'key', b'key2']) + tools.assert_equal(result, {b'key': b'value', b'key2': b'value2'}) result = client.get_many([]) tools.assert_equal(result, {}) @@ -48,74 +50,74 @@ def add_replace_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.add('key', 'value', noreply=False) + result = client.add(b'key', b'value', noreply=False) tools.assert_equal(result, True) - result = client.get('key') - tools.assert_equal(result, 'value') + result = client.get(b'key') + tools.assert_equal(result, b'value') - result = client.add('key', 'value2', noreply=False) + result = client.add(b'key', b'value2', noreply=False) tools.assert_equal(result, False) - result = client.get('key') - tools.assert_equal(result, 'value') + result = client.get(b'key') + tools.assert_equal(result, b'value') - result = client.replace('key1', 'value1', noreply=False) + result = client.replace(b'key1', b'value1', noreply=False) tools.assert_equal(result, False) - result = client.get('key1') + result = client.get(b'key1') tools.assert_equal(result, None) - result = client.replace('key', 'value2', noreply=False) + result = client.replace(b'key', b'value2', noreply=False) tools.assert_equal(result, True) - result = client.get('key') - tools.assert_equal(result, 'value2') + result = client.get(b'key') + tools.assert_equal(result, b'value2') def append_prepend_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.append('key', 'value', noreply=False) + result = client.append(b'key', b'value', noreply=False) tools.assert_equal(result, False) - result = client.get('key') + result = client.get(b'key') tools.assert_equal(result, None) - result = client.set('key', 'value', noreply=False) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) - result = client.append('key', 'after', noreply=False) + result = client.append(b'key', b'after', noreply=False) tools.assert_equal(result, True) - result = client.get('key') - tools.assert_equal(result, 'valueafter') + result = client.get(b'key') + tools.assert_equal(result, b'valueafter') - result = client.prepend('key1', 'value', noreply=False) + result = client.prepend(b'key1', b'value', noreply=False) tools.assert_equal(result, False) - result = client.get('key1') + result = client.get(b'key1') tools.assert_equal(result, None) - result = client.prepend('key', 'before', noreply=False) + result = client.prepend(b'key', b'before', noreply=False) tools.assert_equal(result, True) - result = client.get('key') - tools.assert_equal(result, 'beforevalueafter') + result = client.get(b'key') + tools.assert_equal(result, b'beforevalueafter') def cas_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.cas('key', 'value', '1', noreply=False) + result = client.cas(b'key', b'value', b'1', noreply=False) tools.assert_equal(result, None) - result = client.set('key', 'value', noreply=False) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) - result = client.cas('key', 'value', '1', noreply=False) + result = client.cas(b'key', b'value', b'1', noreply=False) tools.assert_equal(result, False) - result, cas = client.gets('key') - tools.assert_equal(result, 'value') + result, cas = client.gets(b'key') + tools.assert_equal(result, b'value') - result = client.cas('key', 'value1', cas, noreply=False) + result = client.cas(b'key', b'value1', cas, noreply=False) tools.assert_equal(result, True) - result = client.cas('key', 'value2', cas, noreply=False) + result = client.cas(b'key', b'value2', cas, noreply=False) tools.assert_equal(result, False) @@ -123,29 +125,29 @@ def gets_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.gets('key') + result = client.gets(b'key') tools.assert_equal(result, (None, None)) - result = client.set('key', 'value', noreply=False) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) - result = client.gets('key') - tools.assert_equal(result[0], 'value') + result = client.gets(b'key') + tools.assert_equal(result[0], b'value') def delete_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.delete('key', noreply=False) + result = client.delete(b'key', noreply=False) tools.assert_equal(result, False) - result = client.get('key') + result = client.get(b'key') tools.assert_equal(result, None) - result = client.set('key', 'value', noreply=False) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) - result = client.delete('key', noreply=False) + result = client.delete(b'key', noreply=False) tools.assert_equal(result, True) - result = client.get('key') + result = client.get(b'key') tools.assert_equal(result, None) @@ -153,26 +155,26 @@ def incr_decr_test(host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.incr('key', 1, noreply=False) + result = client.incr(b'key', 1, noreply=False) tools.assert_equal(result, None) - result = client.set('key', '0', noreply=False) + result = client.set(b'key', b'0', noreply=False) tools.assert_equal(result, True) - result = client.incr('key', 1, noreply=False) + result = client.incr(b'key', 1, noreply=False) tools.assert_equal(result, 1) def _bad_int(): - client.incr('key', 'foobar') + client.incr(b'key', b'foobar') tools.assert_raises(MemcacheClientError, _bad_int) - result = client.decr('key1', 1, noreply=False) + result = client.decr(b'key1', 1, noreply=False) tools.assert_equal(result, None) - result = client.decr('key', 1, noreply=False) + result = client.decr(b'key', 1, noreply=False) tools.assert_equal(result, 0) - result = client.get('key') - tools.assert_equal(result, '0') + result = client.get(b'key') + tools.assert_equal(result, b'0') def misc_test(host, port, socket_module): @@ -182,11 +184,11 @@ def misc_test(host, port, socket_module): def test_serialization_deserialization(host, port, socket_module): def _ser(key, value): - return json.dumps(value), 1 + return json.dumps(value).encode('ascii'), 1 def _des(key, value, flags): if flags == 1: - return json.loads(value) + return json.loads(value.decode('ascii')) return value client = Client((host, port), serializer=_ser, deserializer=_des, @@ -194,8 +196,8 @@ def _des(key, value, flags): client.flush_all() value = {'a': 'b', 'c': ['d']} - client.set('key', value) - result = client.get('key') + client.set(b'key', value) + result = client.get(b'key') tools.assert_equal(result, value) @@ -204,27 +206,27 @@ def test_errors(host, port, socket_module): client.flush_all() def _key_with_ws(): - client.set('key with spaces', 'value', noreply=False) + client.set(b'key with spaces', b'value', noreply=False) tools.assert_raises(MemcacheIllegalInputError, _key_with_ws) def _key_too_long(): - client.set('x' * 1024, 'value', noreply=False) + client.set(b'x' * 1024, b'value', noreply=False) tools.assert_raises(MemcacheClientError, _key_too_long) def _unicode_key_in_set(): - client.set(u'\u0FFF', 'value', noreply=False) + client.set(six.u('\u0FFF'), b'value', noreply=False) tools.assert_raises(MemcacheClientError, _unicode_key_in_set) def _unicode_key_in_get(): - client.get(u'\u0FFF') + client.get(six.u('\u0FFF')) tools.assert_raises(MemcacheClientError, _unicode_key_in_get) def _unicode_value_in_set(): - client.set('key', u'\u0FFF', noreply=False) + client.set(b'key', six.u('\u0FFF'), noreply=False) tools.assert_raises(MemcacheClientError, _unicode_value_in_set) @@ -245,33 +247,33 @@ def main(): try: from gevent import socket as gevent_socket except ImportError: - print "Skipping gevent (not installed)" + print("Skipping gevent (not installed)") else: socket_modules.append(gevent_socket) for socket_module in socket_modules: - print "Testing with socket module:", socket_module.__name__ + print("Testing with socket module:", socket_module.__name__) - print "Testing get and set..." + print("Testing get and set...") get_set_test(args.server, args.port, socket_module) - print "Testing add and replace..." + print("Testing add and replace...") add_replace_test(args.server, args.port, socket_module) - print "Testing append and prepend..." + print("Testing append and prepend...") append_prepend_test(args.server, args.port, socket_module) - print "Testing cas..." + print("Testing cas...") cas_test(args.server, args.port, socket_module) - print "Testing gets..." + print("Testing gets...") gets_test(args.server, args.port, socket_module) - print "Testing delete..." + print("Testing delete...") delete_test(args.server, args.port, socket_module) - print "Testing incr and decr..." + print("Testing incr and decr...") incr_decr_test(args.server, args.port, socket_module) - print "Testing flush_all..." + print("Testing flush_all...") misc_test(args.server, args.port, socket_module) - print "Testing serialization and deserialization..." + print("Testing serialization and deserialization...") test_serialization_deserialization(args.server, args.port, socket_module) - print "Testing error cases..." + print("Testing error cases...") test_errors(args.server, args.port, socket_module) diff --git a/pymemcache/test/test_client.py b/pymemcache/test/test_client.py index fdd0ae80..4b112752 100644 --- a/pymemcache/test/test_client.py +++ b/pymemcache/test/test_client.py @@ -66,103 +66,103 @@ def __getattr__(self, name): class ClientTestMixin(object): def test_set_success(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) def test_set_unicode_key(self): client = self.Client(None) - client.sock = MockSocket(['']) + client.sock = MockSocket([b'']) def _set(): - client.set(u'\u0FFF', 'value', noreply=False) + client.set(u'\u0FFF', b'value', noreply=False) tools.assert_raises(MemcacheIllegalInputError, _set) def test_set_unicode_value(self): client = self.Client(None) - client.sock = MockSocket(['']) + client.sock = MockSocket([b'']) def _set(): - client.set('key', u'\u0FFF', noreply=False) + client.set(b'key', u'\u0FFF', noreply=False) tools.assert_raises(MemcacheIllegalInputError, _set) def test_set_noreply(self): client = self.Client(None) client.sock = MockSocket([]) - result = client.set('key', 'value', noreply=True) + result = client.set(b'key', b'value', noreply=True) tools.assert_equal(result, True) def test_set_many_success(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set_many({'key' : 'value'}, noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set_many({b'key' : b'value'}, noreply=False) tools.assert_equal(result, True) def test_add_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r', '\n']) - result = client.add('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r', b'\n']) + result = client.add(b'key', b'value', noreply=False) tools.assert_equal(result, True) def test_add_not_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r', '\n']) - result = client.add('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r', b'\n']) + result = client.add(b'key', b'value', noreply=False) - client.sock = MockSocket(['NOT_', 'STOR', 'ED', '\r\n']) - result = client.add('key', 'value', noreply=False) + client.sock = MockSocket([b'NOT_', b'STOR', b'ED', b'\r\n']) + result = client.add(b'key', b'value', noreply=False) tools.assert_equal(result, False) def test_get_not_found(self): client = self.Client(None) - client.sock = MockSocket(['END\r\n']) - result = client.get('key') + client.sock = MockSocket([b'END\r\n']) + result = client.get(b'key') tools.assert_equal(result, None) def test_get_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key', b'value', noreply=False) - client.sock = MockSocket(['VALUE key 0 5\r\nvalue\r\nEND\r\n']) - result = client.get('key') - tools.assert_equal(result, 'value') + client.sock = MockSocket([b'VALUE key 0 5\r\nvalue\r\nEND\r\n']) + result = client.get(b'key') + tools.assert_equal(result, b'value') def test_get_many_none_found(self): client = self.Client(None) - client.sock = MockSocket(['END\r\n']) - result = client.get_many(['key1', 'key2']) + client.sock = MockSocket([b'END\r\n']) + result = client.get_many([b'key1', b'key2']) tools.assert_equal(result, {}) def test_get_many_some_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key1', 'value1', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key1', b'value1', noreply=False) - client.sock = MockSocket(['VALUE key1 0 6\r\nvalue1\r\nEND\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equal(result, {'key1': 'value1'}) + client.sock = MockSocket([b'VALUE key1 0 6\r\nvalue1\r\nEND\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equal(result, {b'key1': b'value1'}) def test_get_many_all_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key1', 'value1', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key1', b'value1', noreply=False) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key2', 'value2', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key2', b'value2', noreply=False) - client.sock = MockSocket(['VALUE key1 0 6\r\nvalue1\r\n' - 'VALUE key2 0 6\r\nvalue2\r\nEND\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equal(result, {'key1': 'value1', 'key2': 'value2'}) + client.sock = MockSocket([b'VALUE key1 0 6\r\nvalue1\r\n' + b'VALUE key2 0 6\r\nvalue2\r\nEND\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equal(result, {b'key1': b'value1', b'key2': b'value2'}) def test_get_unicode_key(self): client = self.Client(None) - client.sock = MockSocket(['']) + client.sock = MockSocket([b'']) def _get(): client.get(u'\u0FFF') @@ -171,65 +171,65 @@ def _get(): def test_delete_not_found(self): client = self.Client(None) - client.sock = MockSocket(['NOT_FOUND\r\n']) - result = client.delete('key', noreply=False) + client.sock = MockSocket([b'NOT_FOUND\r\n']) + result = client.delete(b'key', noreply=False) tools.assert_equal(result, False) def test_delete_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r', '\n']) - result = client.add('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r', b'\n']) + result = client.add(b'key', b'value', noreply=False) - client.sock = MockSocket(['DELETED\r\n']) - result = client.delete('key', noreply=False) + client.sock = MockSocket([b'DELETED\r\n']) + result = client.delete(b'key', noreply=False) tools.assert_equal(result, True) def test_delete_noreply(self): client = self.Client(None) client.sock = MockSocket([]) - result = client.delete('key', noreply=True) + result = client.delete(b'key', noreply=True) tools.assert_equal(result, True) def test_incr_not_found(self): client = self.Client(None) - client.sock = MockSocket(['NOT_FOUND\r\n']) - result = client.incr('key', 1, noreply=False) + client.sock = MockSocket([b'NOT_FOUND\r\n']) + result = client.incr(b'key', 1, noreply=False) tools.assert_equal(result, None) def test_incr_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - client.set('key', 0, noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + client.set(b'key', 0, noreply=False) - client.sock = MockSocket(['1\r\n']) - result = client.incr('key', 1, noreply=False) + client.sock = MockSocket([b'1\r\n']) + result = client.incr(b'key', 1, noreply=False) tools.assert_equal(result, 1) def test_incr_noreply(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - client.set('key', 0, noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + client.set(b'key', 0, noreply=False) client.sock = MockSocket([]) - result = client.incr('key', 1, noreply=True) + result = client.incr(b'key', 1, noreply=True) tools.assert_equal(result, None) def test_decr_not_found(self): client = self.Client(None) - client.sock = MockSocket(['NOT_FOUND\r\n']) - result = client.decr('key', 1, noreply=False) + client.sock = MockSocket([b'NOT_FOUND\r\n']) + result = client.decr(b'key', 1, noreply=False) tools.assert_equal(result, None) def test_decr_found(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - client.set('key', 2, noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + client.set(b'key', 2, noreply=False) - client.sock = MockSocket(['1\r\n']) - result = client.decr('key', 1, noreply=False) + client.sock = MockSocket([b'1\r\n']) + result = client.decr(b'key', 1, noreply=False) tools.assert_equal(result, 1) @@ -239,101 +239,101 @@ class TestClient(ClientTestMixin, unittest.TestCase): def test_append_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.append('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.append(b'key', b'value', noreply=False) tools.assert_equal(result, True) def test_prepend_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.prepend('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.prepend(b'key', b'value', noreply=False) tools.assert_equal(result, True) def test_cas_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.cas('key', 'value', 'cas', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.cas(b'key', b'value', b'cas', noreply=False) tools.assert_equal(result, True) def test_cas_exists(self): client = self.Client(None) - client.sock = MockSocket(['EXISTS\r\n']) - result = client.cas('key', 'value', 'cas', noreply=False) + client.sock = MockSocket([b'EXISTS\r\n']) + result = client.cas(b'key', b'value', b'cas', noreply=False) tools.assert_equal(result, False) def test_cas_not_found(self): client = self.Client(None) - client.sock = MockSocket(['NOT_FOUND\r\n']) - result = client.cas('key', 'value', 'cas', noreply=False) + client.sock = MockSocket([b'NOT_FOUND\r\n']) + result = client.cas(b'key', b'value', b'cas', noreply=False) tools.assert_equal(result, None) def test_cr_nl_boundaries(self): client = self.Client(None) - client.sock = MockSocket(['VALUE key1 0 6\r', - '\nvalue1\r\n' - 'VALUE key2 0 6\r\n', - 'value2\r\n' - 'END\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) - - client.sock = MockSocket(['VALUE key1 0 6\r\n', - 'value1\r', - '\nVALUE key2 0 6\r\n', - 'value2\r\n', - 'END\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) - - client.sock = MockSocket(['VALUE key1 0 6\r\n', - 'value1\r\n', - 'VALUE key2 0 6\r', - '\nvalue2\r\n', - 'END\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) - - - client.sock = MockSocket(['VALUE key1 0 6\r\n', - 'value1\r\n', - 'VALUE key2 0 6\r\n', - 'value2\r', - '\nEND\r\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) - - client.sock = MockSocket(['VALUE key1 0 6\r\n', - 'value1\r\n', - 'VALUE key2 0 6\r\n', - 'value2\r\n', - 'END\r', - '\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) - - client.sock = MockSocket(['VALUE key1 0 6\r', - '\nvalue1\r', - '\nVALUE key2 0 6\r', - '\nvalue2\r', - '\nEND\r', - '\n']) - result = client.get_many(['key1', 'key2']) - tools.assert_equals(result, {'key1': 'value1', 'key2': 'value2'}) + client.sock = MockSocket([b'VALUE key1 0 6\r', + b'\nvalue1\r\n' + b'VALUE key2 0 6\r\n', + b'value2\r\n' + b'END\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) + + client.sock = MockSocket([b'VALUE key1 0 6\r\n', + b'value1\r', + b'\nVALUE key2 0 6\r\n', + b'value2\r\n', + b'END\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) + + client.sock = MockSocket([b'VALUE key1 0 6\r\n', + b'value1\r\n', + b'VALUE key2 0 6\r', + b'\nvalue2\r\n', + b'END\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) + + + client.sock = MockSocket([b'VALUE key1 0 6\r\n', + b'value1\r\n', + b'VALUE key2 0 6\r\n', + b'value2\r', + b'\nEND\r\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) + + client.sock = MockSocket([b'VALUE key1 0 6\r\n', + b'value1\r\n', + b'VALUE key2 0 6\r\n', + b'value2\r\n', + b'END\r', + b'\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) + + client.sock = MockSocket([b'VALUE key1 0 6\r', + b'\nvalue1\r', + b'\nVALUE key2 0 6\r', + b'\nvalue2\r', + b'\nEND\r', + b'\n']) + result = client.get_many([b'key1', b'key2']) + tools.assert_equals(result, {b'key1': b'value1', b'key2': b'value2'}) def test_delete_exception(self): client = self.Client(None) client.sock = MockSocket([Exception('fail')]) def _delete(): - client.delete('key', noreply=False) + client.delete(b'key', noreply=False) tools.assert_raises(Exception, _delete) tools.assert_equal(client.sock, None) - tools.assert_equal(client.buf, '') + tools.assert_equal(client.buf, b'') def test_flush_all(self): client = self.Client(None) - client.sock = MockSocket(['OK\r\n']) + client.sock = MockSocket([b'OK\r\n']) result = client.flush_all(noreply=False) tools.assert_equal(result, True) @@ -342,71 +342,71 @@ def test_incr_exception(self): client.sock = MockSocket([Exception('fail')]) def _incr(): - client.incr('key', 1) + client.incr(b'key', 1) tools.assert_raises(Exception, _incr) tools.assert_equal(client.sock, None) - tools.assert_equal(client.buf, '') + tools.assert_equal(client.buf, b'') def test_get_error(self): client = self.Client(None) - client.sock = MockSocket(['ERROR\r\n']) + client.sock = MockSocket([b'ERROR\r\n']) def _get(): - client.get('key') + client.get(b'key') tools.assert_raises(MemcacheUnknownCommandError, _get) def test_get_recv_chunks(self): client = self.Client(None) - client.sock = MockSocket(['VALUE key', ' 0 5\r', '\nvalue', '\r\n', - 'END', '\r', '\n']) - result = client.get('key') - tools.assert_equal(result, 'value') + client.sock = MockSocket([b'VALUE key', b' 0 5\r', b'\nvalue', b'\r\n', + b'END', b'\r', b'\n']) + result = client.get(b'key') + tools.assert_equal(result, b'value') def test_get_unknown_error(self): client = self.Client(None) - client.sock = MockSocket(['foobarbaz\r\n']) + client.sock = MockSocket([b'foobarbaz\r\n']) def _get(): - client.get('key') + client.get(b'key') tools.assert_raises(MemcacheUnknownError, _get) def test_gets_not_found(self): client = self.Client(None) - client.sock = MockSocket(['END\r\n']) - result = client.gets('key') + client.sock = MockSocket([b'END\r\n']) + result = client.gets(b'key') tools.assert_equal(result, (None, None)) def test_gets_found(self): client = self.Client(None) - client.sock = MockSocket(['VALUE key 0 5 10\r\nvalue\r\nEND\r\n']) - result = client.gets('key') - tools.assert_equal(result, ('value', '10')) + client.sock = MockSocket([b'VALUE key 0 5 10\r\nvalue\r\nEND\r\n']) + result = client.gets(b'key') + tools.assert_equal(result, (b'value', b'10')) def test_gets_many_none_found(self): client = self.Client(None) - client.sock = MockSocket(['END\r\n']) - result = client.gets_many(['key1', 'key2']) + client.sock = MockSocket([b'END\r\n']) + result = client.gets_many([b'key1', b'key2']) tools.assert_equal(result, {}) def test_gets_many_some_found(self): client = self.Client(None) - client.sock = MockSocket(['VALUE key1 0 6 11\r\nvalue1\r\nEND\r\n']) - result = client.gets_many(['key1', 'key2']) - tools.assert_equal(result, {'key1': ('value1', '11')}) + client.sock = MockSocket([b'VALUE key1 0 6 11\r\nvalue1\r\nEND\r\n']) + result = client.gets_many([b'key1', b'key2']) + tools.assert_equal(result, {b'key1': (b'value1', b'11')}) def test_touch_not_found(self): client = self.Client(None) - client.sock = MockSocket(['NOT_FOUND\r\n']) - result = client.touch('key', noreply=False) + client.sock = MockSocket([b'NOT_FOUND\r\n']) + result = client.touch(b'key', noreply=False) tools.assert_equal(result, False) def test_touch_found(self): client = self.Client(None) - client.sock = MockSocket(['TOUCHED\r\n']) - result = client.touch('key', noreply=False) + client.sock = MockSocket([b'TOUCHED\r\n']) + result = client.touch(b'key', noreply=False) tools.assert_equal(result, True) def test_quit(self): @@ -415,18 +415,18 @@ def test_quit(self): result = client.quit() tools.assert_equal(result, None) tools.assert_equal(client.sock, None) - tools.assert_equal(client.buf, '') + tools.assert_equal(client.buf, b'') def test_replace_stored(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.replace('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.replace(b'key', b'value', noreply=False) tools.assert_equal(result, True) def test_replace_not_stored(self): client = self.Client(None) - client.sock = MockSocket(['NOT_STORED\r\n']) - result = client.replace('key', 'value', noreply=False) + client.sock = MockSocket([b'NOT_STORED\r\n']) + result = client.replace(b'key', b'value', noreply=False) tools.assert_equal(result, False) def test_serialization(self): @@ -434,26 +434,26 @@ def _ser(key, value): return json.dumps(value), 0 client = self.Client(None, serializer=_ser) - client.sock = MockSocket(['STORED\r\n']) - client.set('key', {'a': 'b', 'c': 'd'}) + client.sock = MockSocket([b'STORED\r\n']) + client.set('key', {'c': 'd'}) tools.assert_equal(client.sock.send_bufs, [ - 'set key 0 0 20 noreply\r\n{"a": "b", "c": "d"}\r\n' + b'set key 0 0 10 noreply\r\n{"c": "d"}\r\n' ]) def test_set_socket_handling(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set('key', 'value', noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set(b'key', b'value', noreply=False) tools.assert_equal(result, True) tools.assert_equal(client.sock.closed, False) tools.assert_equal(len(client.sock.send_bufs), 1) def test_set_error(self): client = self.Client(None) - client.sock = MockSocket(['ERROR\r\n']) + client.sock = MockSocket([b'ERROR\r\n']) def _set(): - client.set('key', 'value', noreply=False) + client.set(b'key', b'value', noreply=False) tools.assert_raises(MemcacheUnknownCommandError, _set) @@ -462,15 +462,15 @@ def test_set_exception(self): client.sock = MockSocket([Exception('fail')]) def _set(): - client.set('key', 'value', noreply=False) + client.set(b'key', b'value', noreply=False) tools.assert_raises(Exception, _set) tools.assert_equal(client.sock, None) - tools.assert_equal(client.buf, '') + tools.assert_equal(client.buf, b'') def test_set_client_error(self): client = self.Client(None) - client.sock = MockSocket(['CLIENT_ERROR some message\r\n']) + client.sock = MockSocket([b'CLIENT_ERROR some message\r\n']) def _set(): client.set('key', 'value', noreply=False) @@ -479,90 +479,91 @@ def _set(): def test_set_server_error(self): client = self.Client(None) - client.sock = MockSocket(['SERVER_ERROR some message\r\n']) + client.sock = MockSocket([b'SERVER_ERROR some message\r\n']) def _set(): - client.set('key', 'value', noreply=False) + client.set(b'key', b'value', noreply=False) tools.assert_raises(MemcacheServerError, _set) def test_set_unknown_error(self): client = self.Client(None) - client.sock = MockSocket(['foobarbaz\r\n']) + client.sock = MockSocket([b'foobarbaz\r\n']) def _set(): - client.set('key', 'value', noreply=False) + client.set(b'key', b'value', noreply=False) tools.assert_raises(MemcacheUnknownError, _set) def test_set_many_socket_handling(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - result = client.set_many({'key' : 'value'}, noreply=False) + client.sock = MockSocket([b'STORED\r\n']) + result = client.set_many({b'key': b'value'}, noreply=False) tools.assert_equal(result, True) tools.assert_equal(client.sock.closed, False) tools.assert_equal(len(client.sock.send_bufs), 1) def test_set_many_exception(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n', Exception('fail')]) + client.sock = MockSocket([b'STORED\r\n', Exception('fail')]) def _set(): - client.set_many({'key' : 'value', 'other' : 'value'}, noreply=False) + client.set_many({b'key': b'value', b'other': b'value'}, + noreply=False) tools.assert_raises(Exception, _set) tools.assert_equal(client.sock, None) - tools.assert_equal(client.buf, '') + tools.assert_equal(client.buf, b'') def test_stats(self): client = self.Client(None) - client.sock = MockSocket(['STAT fake_stats 1\r\n', 'END\r\n']) + client.sock = MockSocket([b'STAT fake_stats 1\r\n', b'END\r\n']) result = client.stats() tools.assert_equal(client.sock.send_bufs, [ - 'stats \r\n' + b'stats \r\n' ]) - tools.assert_equal(result, {'fake_stats': 1}) + tools.assert_equal(result, {b'fake_stats': 1}) def test_stats_with_args(self): client = self.Client(None) - client.sock = MockSocket(['STAT fake_stats 1\r\n', 'END\r\n']) + client.sock = MockSocket([b'STAT fake_stats 1\r\n', b'END\r\n']) result = client.stats('some_arg') tools.assert_equal(client.sock.send_bufs, [ - 'stats some_arg\r\n' + b'stats some_arg\r\n' ]) - tools.assert_equal(result, {'fake_stats': 1}) + tools.assert_equal(result, {b'fake_stats': 1}) def test_stats_conversions(self): client = self.Client(None) client.sock = MockSocket([ # Most stats are converted to int - 'STAT cmd_get 2519\r\n', - 'STAT cmd_set 3099\r\n', + b'STAT cmd_get 2519\r\n', + b'STAT cmd_set 3099\r\n', # Unless they can't be, they remain str - 'STAT libevent 2.0.19-stable\r\n', + b'STAT libevent 2.0.19-stable\r\n', # Some named stats are explicitly converted - 'STAT hash_is_expanding 0\r\n', - 'STAT rusage_user 0.609165\r\n', - 'STAT rusage_system 0.852791\r\n', - 'STAT slab_reassign_running 1\r\n', - 'STAT version 1.4.14\r\n', - 'END\r\n', + b'STAT hash_is_expanding 0\r\n', + b'STAT rusage_user 0.609165\r\n', + b'STAT rusage_system 0.852791\r\n', + b'STAT slab_reassign_running 1\r\n', + b'STAT version 1.4.14\r\n', + b'END\r\n', ]) result = client.stats() tools.assert_equal(client.sock.send_bufs, [ - 'stats \r\n' + b'stats \r\n' ]) expected = { - 'cmd_get': 2519, - 'cmd_set': 3099, - 'libevent': '2.0.19-stable', - 'hash_is_expanding': False, - 'rusage_user': 0.609165, - 'rusage_system': 0.852791, - 'slab_reassign_running': True, - 'version': '1.4.14', + b'cmd_get': 2519, + b'cmd_set': 3099, + b'libevent': b'2.0.19-stable', + b'hash_is_expanding': False, + b'rusage_user': 0.609165, + b'rusage_system': 0.852791, + b'slab_reassign_running': True, + b'version': b'1.4.14', } tools.assert_equal(result, expected) @@ -591,27 +592,27 @@ def test_socket_connect(self): def test_python_dict_set_is_supported(self): client = self.Client(None) - client.sock = MockSocket(['STORED\r\n']) - client['key'] = 'value' + client.sock = MockSocket([b'STORED\r\n']) + client[b'key'] = b'value' def test_python_dict_get_is_supported(self): client = self.Client(None) - client.sock = MockSocket(['VALUE key 0 5\r\nvalue\r\nEND\r\n']) - tools.assert_equal(client['key'], 'value') + client.sock = MockSocket([b'VALUE key 0 5\r\nvalue\r\nEND\r\n']) + tools.assert_equal(client[b'key'], b'value') def test_python_dict_get_not_found_is_supported(self): client = self.Client(None) - client.sock = MockSocket(['END\r\n']) + client.sock = MockSocket([b'END\r\n']) def _get(): - _ = client['key'] + _ = client[b'key'] tools.assert_raises(KeyError, _get) def test_python_dict_del_is_supported(self): client = self.Client(None) - client.sock = MockSocket(['DELETED\r\n']) - del client['key'] + client.sock = MockSocket([b'DELETED\r\n']) + del client[b'key'] class TestMockClient(ClientTestMixin, unittest.TestCase): Client = MockMemcacheClient diff --git a/pymemcache/test/test_utils.py b/pymemcache/test/test_utils.py index a96217d7..40bafecb 100644 --- a/pymemcache/test/test_utils.py +++ b/pymemcache/test/test_utils.py @@ -1,53 +1,59 @@ from nose import tools +import six from pymemcache.test.utils import MockMemcacheClient def test_get_set(): client = MockMemcacheClient() - tools.assert_equal(client.get("hello"), None) + tools.assert_equal(client.get(b"hello"), None) - client.set("hello", 12) - tools.assert_equal(client.get("hello"), 12) + client.set(b"hello", 12) + tools.assert_equal(client.get(b"hello"), 12) def test_get_many_set_many(): client = MockMemcacheClient() - client.set("h", 1) + client.set(b"h", 1) - tools.assert_equal(client.get_many("hello"), {"h" : 1}) + tools.assert_equal(client.get_many([b"h", b"e", b"l", b"o"]), + {b"h": 1}) - client.set_many(dict(h=1, e=2, l=3)) - tools.assert_equal(client.get_many("hello"), dict(h=1, e=2, l=3)) + # Convert keys into bytes + d = dict((k.encode('ascii'), v) + for k, v in six.iteritems(dict(h=1, e=2, l=3))) + client.set_many(d) + tools.assert_equal(client.get_many([b"h", b"e", b"l", b"o"]), + d) def test_add(): client = MockMemcacheClient() - client.add("k", 2) - tools.assert_equal(client.get("k"), 2) + client.add(b"k", 2) + tools.assert_equal(client.get(b"k"), 2) - client.add("k", 25) - tools.assert_equal(client.get("k"), 2) + client.add(b"k", 25) + tools.assert_equal(client.get(b"k"), 2) def test_delete(): client = MockMemcacheClient() - client.add("k", 2) - tools.assert_equal(client.get("k"), 2) + client.add(b"k", 2) + tools.assert_equal(client.get(b"k"), 2) - client.delete("k") - tools.assert_equal(client.get("k"), None) + client.delete(b"k") + tools.assert_equal(client.get(b"k"), None) def test_incr_decr(): client = MockMemcacheClient() - client.add("k", 2) + client.add(b"k", 2) - client.incr("k", 4) - tools.assert_equal(client.get("k"), 6) + client.incr(b"k", 4) + tools.assert_equal(client.get(b"k"), 6) - client.decr("k", 2) - tools.assert_equal(client.get("k"), 4) + client.decr(b"k", 2) + tools.assert_equal(client.get(b"k"), 4) diff --git a/pymemcache/test/utils.py b/pymemcache/test/utils.py index 381fe1d1..77b7c22e 100644 --- a/pymemcache/test/utils.py +++ b/pymemcache/test/utils.py @@ -7,6 +7,8 @@ import time +import six + from pymemcache.client import MemcacheIllegalInputError @@ -38,7 +40,7 @@ def __init__(self, self.ignore_exc = ignore_exc def get(self, key): - if isinstance(key, unicode): + if isinstance(key, six.text_type): raise MemcacheIllegalInputError(key) if key not in self._contents: @@ -62,9 +64,9 @@ def get_many(self, keys): return out def set(self, key, value, expire=0, noreply=True): - if isinstance(key, unicode): + if isinstance(key, six.text_type): raise MemcacheIllegalInputError(key) - if isinstance(value, unicode): + if isinstance(value, six.text_type): raise MemcacheIllegalInputError(value) was_serialized = False @@ -78,7 +80,7 @@ def set(self, key, value, expire=0, noreply=True): return True def set_many(self, values, expire=None, noreply=True): - for key, value in values.iteritems(): + for key, value in six.iteritems(values): self.set(key, value, expire, noreply) return True @@ -122,7 +124,7 @@ def stats(self): "evictions": False, "growth_factor": 1.0, "stat_key_prefix": "", - "umask": 0644, + "umask": 0o644, "detail_enabled": False, "cas_enabled": False, "auth_enabled_sasl": False, diff --git a/setup.py b/setup.py index f79596b3..1e458b16 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ author = 'Charles Gordon', author_email = 'charles@pinterest.com', packages = find_packages(), - setup_requires = ['nose>=1.0'], + setup_requires = ['nose>=1.0', 'six'], description = 'A comprehensive, fast, pure Python memcached client', long_description = open('README.md').read(), license = 'Apache License 2.0', @@ -19,6 +19,7 @@ 'Programming Language :: Python', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.3', 'License :: OSI Approved :: Apache Software License', 'Topic :: Database', ],