diff options
author | Joe Gordon <jogo@pinterest.com> | 2021-12-02 16:17:01 -0800 |
---|---|---|
committer | Joe Gordon <jogo@pinterest.com> | 2021-12-03 09:27:52 -0800 |
commit | 73c78212c0eea3970570cee48b55c3295b9f4c94 (patch) | |
tree | 563715d0eae29d06d642f266b5e1cd66d99b6b39 | |
parent | d43b10cbe4d35abf79fea816bdaafbd6c41f6c32 (diff) | |
download | pymemcache-73c78212c0eea3970570cee48b55c3295b9f4c94.tar.gz |
Apply black formatting
https://black.readthedocs.io/en/stable/index.html
-rw-r--r-- | docs/conf.py | 101 | ||||
-rw-r--r-- | pymemcache/__init__.py | 2 | ||||
-rw-r--r-- | pymemcache/client/base.py | 454 | ||||
-rw-r--r-- | pymemcache/client/hash.py | 146 | ||||
-rw-r--r-- | pymemcache/client/murmur3.py | 44 | ||||
-rw-r--r-- | pymemcache/client/rendezvous.py | 9 | ||||
-rw-r--r-- | pymemcache/client/retrying.py | 33 | ||||
-rw-r--r-- | pymemcache/exceptions.py | 5 | ||||
-rw-r--r-- | pymemcache/pool.py | 18 | ||||
-rw-r--r-- | pymemcache/serde.py | 8 | ||||
-rw-r--r-- | pymemcache/test/conftest.py | 73 | ||||
-rw-r--r-- | pymemcache/test/test_benchmark.py | 19 | ||||
-rw-r--r-- | pymemcache/test/test_client.py | 1188 | ||||
-rw-r--r-- | pymemcache/test/test_client_hash.py | 405 | ||||
-rw-r--r-- | pymemcache/test/test_client_retry.py | 120 | ||||
-rw-r--r-- | pymemcache/test/test_integration.py | 209 | ||||
-rw-r--r-- | pymemcache/test/test_rendezvous.py | 78 | ||||
-rw-r--r-- | pymemcache/test/test_serde.py | 33 | ||||
-rw-r--r-- | pymemcache/test/test_utils.py | 24 | ||||
-rw-r--r-- | pymemcache/test/utils.py | 43 |
20 files changed, 1518 insertions, 1494 deletions
diff --git a/docs/conf.py b/docs/conf.py index 5008ed2..b781a5a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -20,54 +20,54 @@ import os import sys import subprocess -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath(".")) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # -needs_sphinx = '3.0.0' +needs_sphinx = "3.0.0" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.intersphinx', - 'sphinx.ext.napoleon', - 'sphinx.ext.ifconfig', - 'sphinxcontrib.apidoc', + "sphinx.ext.autodoc", + "sphinx.ext.intersphinx", + "sphinx.ext.napoleon", + "sphinx.ext.ifconfig", + "sphinxcontrib.apidoc", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = u'pymemcache' -copyright = u'Pinterest' -author = u'Charles Gordon, Jon Parise, Joe Gordon' +project = "pymemcache" +copyright = "Pinterest" +author = "Charles Gordon, Jon Parise, Joe Gordon" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = u'3.2' +version = "3.2" # The full version, including alpha/beta/rc tags. -release = u'3.2.0' +release = "3.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -88,7 +88,7 @@ language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -110,7 +110,7 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -127,7 +127,7 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -161,7 +161,7 @@ html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied @@ -241,34 +241,36 @@ html_static_path = ['_static'] # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'pymemcachedoc' +htmlhelp_basename = "pymemcachedoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'pymemcache.tex', u'pymemcache Documentation', - u'Charles Gordon, Jon Parise, Joe Gordon', 'manual'), + ( + master_doc, + "pymemcache.tex", + "pymemcache Documentation", + "Charles Gordon, Jon Parise, Joe Gordon", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -308,10 +310,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'pymemcache', u'pymemcache Documentation', - [author], 1) -] +man_pages = [(master_doc, "pymemcache", "pymemcache Documentation", [author], 1)] # If true, show URL addresses after external links. # @@ -324,9 +323,15 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'pymemcache', u'pymemcache Documentation', - author, 'pymemcache', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "pymemcache", + "pymemcache Documentation", + author, + "pymemcache", + "One line description of project.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. @@ -347,11 +352,11 @@ texinfo_documents = [ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = {"https://docs.python.org/": None} # Automate building apidoc when building with readthedocs -apidoc_module_dir = os.path.join('..', 'pymemcache') -apidoc_output_dir = 'apidoc' +apidoc_module_dir = os.path.join("..", "pymemcache") +apidoc_output_dir = "apidoc" apidoc_separate_modules = True -apidoc_extra_args = ['--force'] +apidoc_extra_args = ["--force"] diff --git a/pymemcache/__init__.py b/pymemcache/__init__.py index 53637cd..436fe26 100644 --- a/pymemcache/__init__.py +++ b/pymemcache/__init__.py @@ -1,4 +1,4 @@ -__version__ = '4.0.0-dev' +__version__ = "4.0.0-dev" from pymemcache.client.base import Client # noqa from pymemcache.client.base import PooledClient # noqa diff --git a/pymemcache/client/base.py b/pymemcache/client/base.py index 7499758..d1392d4 100644 --- a/pymemcache/client/base.py +++ b/pymemcache/client/base.py @@ -24,29 +24,29 @@ from pymemcache.exceptions import ( MemcacheIllegalInputError, MemcacheServerError, MemcacheUnknownError, - MemcacheUnexpectedCloseError + MemcacheUnexpectedCloseError, ) RECV_SIZE = 4096 VALID_STORE_RESULTS = { - b'set': (b'STORED', b'NOT_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'), + b"set": (b"STORED", b"NOT_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"), } SOCKET_KEEPALIVE_SUPPORTED_SYSTEM = { - 'Linux', + "Linux", } STORE_RESULTS_VALUE = { - b'STORED': True, - b'NOT_STORED': False, - b'NOT_FOUND': None, - b'EXISTS': False + b"STORED": True, + b"NOT_STORED": False, + b"NOT_FOUND": None, + b"EXISTS": False, } @@ -57,11 +57,11 @@ def _parse_bool_int(value): def _parse_bool_string_is_yes(value): - return value == b'yes' + return value == b"yes" def _parse_float(value): - return float(value.replace(b':', b'.')) + return float(value.replace(b":", b".")) def _parse_hex(value): @@ -70,36 +70,35 @@ def _parse_hex(value): STAT_TYPES = { # General stats - b'version': bytes, - b'rusage_user': _parse_float, - b'rusage_system': _parse_float, - b'hash_is_expanding': _parse_bool_int, - b'slab_reassign_running': _parse_bool_int, - + b"version": bytes, + b"rusage_user": _parse_float, + b"rusage_system": _parse_float, + b"hash_is_expanding": _parse_bool_int, + b"slab_reassign_running": _parse_bool_int, # Settings stats - b'inter': bytes, - b'growth_factor': float, - b'stat_key_prefix': bytes, - b'umask': _parse_hex, - b'detail_enabled': _parse_bool_int, - b'cas_enabled': _parse_bool_int, - b'auth_enabled_sasl': _parse_bool_string_is_yes, - b'maxconns_fast': _parse_bool_int, - b'slab_reassign': _parse_bool_int, - b'slab_automove': _parse_bool_int, + b"inter": bytes, + b"growth_factor": float, + b"stat_key_prefix": bytes, + b"umask": _parse_hex, + b"detail_enabled": _parse_bool_int, + b"cas_enabled": _parse_bool_int, + b"auth_enabled_sasl": _parse_bool_string_is_yes, + b"maxconns_fast": _parse_bool_int, + b"slab_reassign": _parse_bool_int, + b"slab_automove": _parse_bool_int, } # Common helper functions. -def check_key_helper(key, allow_unicode_keys, key_prefix=b''): +def check_key_helper(key, allow_unicode_keys, key_prefix=b""): """Checks key and add key_prefix.""" if allow_unicode_keys: if isinstance(key, str): - key = key.encode('utf8') + key = key.encode("utf8") elif isinstance(key, str): try: - key = key.encode('ascii') + key = key.encode("ascii") except (UnicodeEncodeError, UnicodeDecodeError): raise MemcacheIllegalInputError("Non-ASCII key: %r" % key) @@ -111,7 +110,7 @@ def check_key_helper(key, allow_unicode_keys, key_prefix=b''): # second statement catches leading or trailing whitespace elif len(parts) > 1 or (parts and parts[0] != key): raise MemcacheIllegalInputError("Key contains whitespace: %r" % key) - elif b'\00' in key: + elif b"\00" in key: raise MemcacheIllegalInputError("Key contains null: %r" % key) return key @@ -123,18 +122,18 @@ def normalize_server_spec(server): if isinstance(server, list): return tuple(server) # Assume [host, port] provided. if not isinstance(server, str): - raise ValueError('Unknown server provided: %r' % server) - if server.startswith('unix:'): + raise ValueError("Unknown server provided: %r" % server) + if server.startswith("unix:"): return server[5:] - if server.startswith('/'): + if server.startswith("/"): return server - if ':' not in server or server.endswith(']'): + if ":" not in server or server.endswith("]"): host, port = server, 11211 else: - host, port = server.rsplit(':', 1) + host, port = server.rsplit(":", 1) port = int(port) - if host.startswith('['): - host = host.strip('[]') + if host.startswith("["): + host = host.strip("[]") return (host, port) @@ -155,20 +154,18 @@ class KeepaliveOpts: dropping the connection. Should be a positive integer most greater than zero. """ - __slots__ = ('idle', 'intvl', 'cnt') + + __slots__ = ("idle", "intvl", "cnt") def __init__(self, idle=1, intvl=1, cnt=5): if idle < 1: - raise ValueError( - "The idle parameter must be greater or equal to 1.") + raise ValueError("The idle parameter must be greater or equal to 1.") self.idle = idle if intvl < 1: - raise ValueError( - "The intvl parameter must be greater or equal to 1.") + raise ValueError("The intvl parameter must be greater or equal to 1.") self.intvl = intvl if cnt < 1: - raise ValueError( - "The cnt parameter must be greater or equal to 1.") + raise ValueError("The cnt parameter must be greater or equal to 1.") self.cnt = cnt @@ -268,22 +265,24 @@ class Client: to memcached. """ - def __init__(self, - server, - serde=None, - serializer=None, - deserializer=None, - connect_timeout=None, - timeout=None, - no_delay=False, - ignore_exc=False, - socket_module=socket, - socket_keepalive=None, - key_prefix=b'', - default_noreply=True, - allow_unicode_keys=False, - encoding='ascii', - tls_context=None): + def __init__( + self, + server, + serde=None, + serializer=None, + deserializer=None, + connect_timeout=None, + timeout=None, + no_delay=False, + ignore_exc=False, + socket_module=socket, + socket_keepalive=None, + key_prefix=b"", + default_noreply=True, + allow_unicode_keys=False, + encoding="ascii", + tls_context=None, + ): """ Constructor. @@ -340,8 +339,7 @@ class Client: "keepalive=False` or use a supported system. " "Supported systems are: {systems}".format( user_system=user_system, - systems=", ".join(sorted( - SOCKET_KEEPALIVE_SUPPORTED_SYSTEM)) + systems=", ".join(sorted(SOCKET_KEEPALIVE_SUPPORTED_SYSTEM)), ) ) if not isinstance(self.socket_keepalive, KeepaliveOpts): @@ -355,7 +353,7 @@ class Client: ) self.sock = None if isinstance(key_prefix, str): - key_prefix = key_prefix.encode('ascii') + key_prefix = key_prefix.encode("ascii") if not isinstance(key_prefix, bytes): raise TypeError("key_prefix should be bytes.") self.key_prefix = key_prefix @@ -366,8 +364,9 @@ class Client: def check_key(self, key): """Checks key and add key_prefix.""" - return check_key_helper(key, allow_unicode_keys=self.allow_unicode_keys, - key_prefix=self.key_prefix) + return check_key_helper( + key, allow_unicode_keys=self.allow_unicode_keys, key_prefix=self.key_prefix + ) def _connect(self): self.close() @@ -382,8 +381,7 @@ class Client: sock = None error = None host, port = self.server - info = s.getaddrinfo(host, port, s.AF_UNSPEC, s.SOCK_STREAM, - s.IPPROTO_TCP) + info = s.getaddrinfo(host, port, s.AF_UNSPEC, s.SOCK_STREAM, s.IPPROTO_TCP) for family, socktype, proto, _, sockaddr in info: try: sock = s.socket(family, socktype, proto) @@ -407,12 +405,17 @@ class Client: sock.settimeout(self.connect_timeout) if self.socket_keepalive is not None: sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, - self.socket_keepalive.idle) - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, - self.socket_keepalive.intvl) - sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, - self.socket_keepalive.cnt) + sock.setsockopt( + socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, self.socket_keepalive.idle + ) + sock.setsockopt( + socket.IPPROTO_TCP, + socket.TCP_KEEPINTVL, + self.socket_keepalive.intvl, + ) + sock.setsockopt( + socket.IPPROTO_TCP, socket.TCP_KEEPCNT, self.socket_keepalive.cnt + ) sock.connect(sockaddr) sock.settimeout(self.timeout) except Exception: @@ -455,8 +458,7 @@ class Client: """ if noreply is None: noreply = self.default_noreply - return self._store_cmd(b'set', {key: value}, expire, noreply, - flags=flags)[key] + return self._store_cmd(b"set", {key: value}, expire, noreply, flags=flags)[key] def set_many(self, values, expire=0, noreply=None, flags=None): """ @@ -478,7 +480,7 @@ class Client: """ if noreply is None: noreply = self.default_noreply - result = self._store_cmd(b'set', values, expire, noreply, flags=flags) + result = self._store_cmd(b"set", values, expire, noreply, flags=flags) return [k for k, v in result.items() if not v] set_multi = set_many @@ -505,8 +507,7 @@ class Client: """ if noreply is None: noreply = self.default_noreply - return self._store_cmd(b'add', {key: value}, expire, noreply, - flags=flags)[key] + return self._store_cmd(b"add", {key: value}, expire, noreply, flags=flags)[key] def replace(self, key, value, expire=0, noreply=None, flags=None): """ @@ -530,8 +531,9 @@ class Client: """ if noreply is None: noreply = self.default_noreply - return self._store_cmd(b'replace', {key: value}, expire, noreply, - flags=flags)[key] + return self._store_cmd(b"replace", {key: value}, expire, noreply, flags=flags)[ + key + ] def append(self, key, value, expire=0, noreply=None, flags=None): """ @@ -552,8 +554,9 @@ class Client: """ if noreply is None: noreply = self.default_noreply - return self._store_cmd(b'append', {key: value}, expire, noreply, - flags=flags)[key] + return self._store_cmd(b"append", {key: value}, expire, noreply, flags=flags)[ + key + ] def prepend(self, key, value, expire=0, noreply=None, flags=None): """ @@ -574,8 +577,9 @@ class Client: """ if noreply is None: noreply = self.default_noreply - return self._store_cmd(b'prepend', {key: value}, expire, noreply, - flags=flags)[key] + return self._store_cmd(b"prepend", {key: value}, expire, noreply, flags=flags)[ + key + ] def cas(self, key, value, cas, expire=0, noreply=False, flags=None): """ @@ -598,8 +602,9 @@ class Client: value and True if it existed and was changed. """ cas = self._check_cas(cas) - return self._store_cmd(b'cas', {key: value}, expire, noreply, - flags=flags, cas=cas)[key] + return self._store_cmd( + b"cas", {key: value}, expire, noreply, flags=flags, cas=cas + )[key] def get(self, key, default=None): """ @@ -612,7 +617,7 @@ class Client: Returns: The value for the key, or default if the key wasn't found. """ - return self._fetch_cmd(b'get', [key], False).get(key, default) + return self._fetch_cmd(b"get", [key], False).get(key, default) def get_many(self, keys): """ @@ -629,7 +634,7 @@ class Client: if not keys: return {} - return self._fetch_cmd(b'get', keys, False) + return self._fetch_cmd(b"get", keys, False) get_multi = get_many @@ -647,7 +652,7 @@ class Client: or (default, cas_defaults) if the key was not found. """ defaults = (default, cas_default) - return self._fetch_cmd(b'gets', [key], True).get(key, defaults) + return self._fetch_cmd(b"gets", [key], True).get(key, defaults) def gets_many(self, keys): """ @@ -664,7 +669,7 @@ class Client: if not keys: return {} - return self._fetch_cmd(b'gets', keys, True) + return self._fetch_cmd(b"gets", keys, True) def delete(self, key, noreply=None): """ @@ -682,14 +687,14 @@ class Client: """ if noreply is None: noreply = self.default_noreply - cmd = b'delete ' + self.check_key(key) + cmd = b"delete " + self.check_key(key) if noreply: - cmd += b' noreply' - cmd += b'\r\n' - results = self._misc_cmd([cmd], b'delete', noreply) + cmd += b" noreply" + cmd += b"\r\n" + results = self._misc_cmd([cmd], b"delete", noreply) if noreply: return True - return results[0] == b'DELETED' + return results[0] == b"DELETED" def delete_many(self, keys, noreply=None): """ @@ -715,10 +720,12 @@ class Client: cmds = [] for key in keys: cmds.append( - b'delete ' + self.check_key(key) + - (b' noreply' if noreply else b'') + - b'\r\n') - self._misc_cmd(cmds, b'delete', noreply) + b"delete " + + self.check_key(key) + + (b" noreply" if noreply else b"") + + b"\r\n" + ) + self._misc_cmd(cmds, b"delete", noreply) return True delete_multi = delete_many @@ -738,14 +745,14 @@ class Client: """ key = self.check_key(key) value = self._check_integer(value, "value") - cmd = b'incr ' + key + b' ' + value + cmd = b"incr " + key + b" " + value if noreply: - cmd += b' noreply' - cmd += b'\r\n' - results = self._misc_cmd([cmd], b'incr', noreply) + cmd += b" noreply" + cmd += b"\r\n" + results = self._misc_cmd([cmd], b"incr", noreply) if noreply: return None - if results[0] == b'NOT_FOUND': + if results[0] == b"NOT_FOUND": return None return int(results[0]) @@ -764,14 +771,14 @@ class Client: """ key = self.check_key(key) value = self._check_integer(value, "value") - cmd = b'decr ' + key + b' ' + value + cmd = b"decr " + key + b" " + value if noreply: - cmd += b' noreply' - cmd += b'\r\n' - results = self._misc_cmd([cmd], b'decr', noreply) + cmd += b" noreply" + cmd += b"\r\n" + results = self._misc_cmd([cmd], b"decr", noreply) if noreply: return None - if results[0] == b'NOT_FOUND': + if results[0] == b"NOT_FOUND": return None return int(results[0]) @@ -794,14 +801,14 @@ class Client: noreply = self.default_noreply key = self.check_key(key) expire = self._check_integer(expire, "expire") - cmd = b'touch ' + key + b' ' + expire + cmd = b"touch " + key + b" " + expire if noreply: - cmd += b' noreply' - cmd += b'\r\n' - results = self._misc_cmd([cmd], b'touch', noreply) + cmd += b" noreply" + cmd += b"\r\n" + results = self._misc_cmd([cmd], b"touch", noreply) if noreply: return True - return results[0] == b'TOUCHED' + return results[0] == b"TOUCHED" def stats(self, *args): """ @@ -818,7 +825,7 @@ class Client: Returns: A dict of the returned stats. """ - result = self._fetch_cmd(b'stats', args, False) + result = self._fetch_cmd(b"stats", args, False) for key, value in result.items(): converter = STAT_TYPES.get(key, int) @@ -841,7 +848,7 @@ class Client: If no exception is raised, always returns True. """ memlimit = self._check_integer(memlimit, "memlimit") - self._fetch_cmd(b'cache_memlimit', [memlimit], False) + self._fetch_cmd(b"cache_memlimit", [memlimit], False) return True def version(self): @@ -852,12 +859,11 @@ class Client: A string of the memcached version. """ cmd = b"version\r\n" - results = self._misc_cmd([cmd], b'version', False) - before, _, after = results[0].partition(b' ') + results = self._misc_cmd([cmd], b"version", False) + before, _, after = results[0].partition(b" ") - if before != b'VERSION': - raise MemcacheUnknownError( - "Received unexpected response: %s" % results[0]) + if before != b"VERSION": + raise MemcacheUnknownError("Received unexpected response: %s" % results[0]) return after def flush_all(self, delay=0, noreply=None): @@ -876,14 +882,14 @@ class Client: if noreply is None: noreply = self.default_noreply delay = self._check_integer(delay, "delay") - cmd = b'flush_all ' + delay + cmd = b"flush_all " + delay if noreply: - cmd += b' noreply' - cmd += b'\r\n' - results = self._misc_cmd([cmd], b'flush_all', noreply) + cmd += b" noreply" + cmd += b"\r\n" + results = self._misc_cmd([cmd], b"flush_all", noreply) if noreply: return True - return results[0] == b'OK' + return results[0] == b"OK" def quit(self): """ @@ -894,7 +900,7 @@ class Client: be re-used after quit. """ cmd = b"quit\r\n" - self._misc_cmd([cmd], b'quit', True) + self._misc_cmd([cmd], b"quit", True) self.close() def shutdown(self, graceful=False): @@ -910,36 +916,36 @@ class Client: graceful: optional bool, True to request a graceful shutdown with SIGUSR1 (defaults to False, i.e. SIGINT shutdown). """ - cmd = b'shutdown' + cmd = b"shutdown" if graceful: - cmd += b' graceful' - cmd += b'\r\n' + cmd += b" graceful" + cmd += b"\r\n" # The shutdown command raises a server-side error if the shutdown # protocol command is not enabled. Otherwise, a successful shutdown # is expected to close the remote end of the transport. try: - self._misc_cmd([cmd], b'shutdown', False) + self._misc_cmd([cmd], b"shutdown", False) except MemcacheUnexpectedCloseError: pass def _raise_errors(self, line, name): - if line.startswith(b'ERROR'): + if line.startswith(b"ERROR"): raise MemcacheUnknownCommandError(name) - if line.startswith(b'CLIENT_ERROR'): - error = line[line.find(b' ') + 1:] + if line.startswith(b"CLIENT_ERROR"): + error = line[line.find(b" ") + 1 :] raise MemcacheClientError(error) - if line.startswith(b'SERVER_ERROR'): - error = line[line.find(b' ') + 1:] + if line.startswith(b"SERVER_ERROR"): + error = line[line.find(b" ") + 1 :] raise MemcacheServerError(error) def _check_integer(self, value, name): """Check that a value is an integer and encode it as a binary string""" if not isinstance(value, int): raise MemcacheIllegalInputError( - f'{name} must be integer, got bad value: {value!r}' + f"{name} must be integer, got bad value: {value!r}" ) return str(value).encode(self.encoding) @@ -955,23 +961,20 @@ class Client: try: cas = str(cas).encode(self.encoding) except UnicodeEncodeError: - raise MemcacheIllegalInputError( - 'non-ASCII cas value: %r' % cas) + raise MemcacheIllegalInputError("non-ASCII cas value: %r" % cas) elif not isinstance(cas, bytes): raise MemcacheIllegalInputError( - 'cas must be integer, string, or bytes, got bad value: %r' % cas + "cas must be integer, string, or bytes, got bad value: %r" % cas ) if not cas.isdigit(): raise MemcacheIllegalInputError( - 'cas must only contain values in 0-9, got bad value: %r' - % cas + "cas must only contain values in 0-9, got bad value: %r" % cas ) return cas - def _extract_value(self, expect_cas, line, buf, remapped_keys, - prefixed_keys): + def _extract_value(self, expect_cas, line, buf, remapped_keys, prefixed_keys): """ This function is abstracted from _fetch_cmd to support different ways of value extraction. In order to use this feature, _extract_value needs @@ -1006,8 +1009,8 @@ class Client: # It is important for all keys to be listed in their original order. cmd = name if prefixed_keys: - cmd += b' ' + b' '.join(prefixed_keys) - cmd += b'\r\n' + cmd += b" " + b" ".join(prefixed_keys) + cmd += b"\r\n" try: if self.sock is None: @@ -1015,7 +1018,7 @@ class Client: self.sock.sendall(cmd) - buf = b'' + buf = b"" line = None result = {} while True: @@ -1025,20 +1028,20 @@ class Client: self.close() raise self._raise_errors(line, name) - if line == b'END' or line == b'OK': + if line == b"END" or line == b"OK": return result - elif line.startswith(b'VALUE'): - key, value, buf = self._extract_value(expect_cas, line, buf, - remapped_keys, - prefixed_keys) + elif line.startswith(b"VALUE"): + key, value, buf = self._extract_value( + expect_cas, line, buf, remapped_keys, prefixed_keys + ) result[key] = value - elif name == b'stats' and line.startswith(b'STAT'): + elif name == b"stats" and line.startswith(b"STAT"): key_value = line.split() result[key_value[1]] = key_value[2] - elif name == b'stats' and line.startswith(b'ITEM'): + elif name == b"stats" and line.startswith(b"ITEM"): # For 'stats cachedump' commands key_value = line.split() - result[key_value[1]] = b' '.join(key_value[2:]) + result[key_value[1]] = b" ".join(key_value[2:]) else: raise MemcacheUnknownError(line[:32]) except Exception: @@ -1051,11 +1054,11 @@ class Client: cmds = [] keys = [] - extra = b'' + extra = b"" if cas is not None: - extra += b' ' + cas + extra += b" " + cas if noreply: - extra += b' noreply' + extra += b" noreply" expire = self._check_integer(expire, "expire") for key, data in values.items(): @@ -1075,24 +1078,35 @@ class Client: data = str(data).encode(self.encoding) except UnicodeEncodeError as e: raise MemcacheIllegalInputError( - "Data values must be binary-safe: %s" % e) + "Data values must be binary-safe: %s" % e + ) - cmds.append(name + b' ' + key + b' ' + - str(data_flags).encode(self.encoding) + - b' ' + expire + - b' ' + str(len(data)).encode(self.encoding) + - extra + b'\r\n' + data + b'\r\n') + cmds.append( + name + + b" " + + key + + b" " + + str(data_flags).encode(self.encoding) + + b" " + + expire + + b" " + + str(len(data)).encode(self.encoding) + + extra + + b"\r\n" + + data + + b"\r\n" + ) if self.sock is None: self._connect() try: - self.sock.sendall(b''.join(cmds)) + self.sock.sendall(b"".join(cmds)) if noreply: return {k: True for k in keys} results = {} - buf = b'' + buf = b"" line = None for key in keys: try: @@ -1116,13 +1130,13 @@ class Client: self._connect() try: - self.sock.sendall(b''.join(cmds)) + self.sock.sendall(b"".join(cmds)) if noreply: return [] results = [] - buf = b'' + buf = b"" line = None for cmd in cmds: try: @@ -1175,25 +1189,27 @@ class PooledClient: #: :class:`Client` class used to create new clients client_class = Client - def __init__(self, - server, - serde=None, - serializer=None, - deserializer=None, - connect_timeout=None, - timeout=None, - no_delay=False, - ignore_exc=False, - socket_module=socket, - socket_keepalive=None, - key_prefix=b'', - max_pool_size=None, - pool_idle_timeout=0, - lock_generator=None, - default_noreply=True, - allow_unicode_keys=False, - encoding='ascii', - tls_context=None): + def __init__( + self, + server, + serde=None, + serializer=None, + deserializer=None, + connect_timeout=None, + timeout=None, + no_delay=False, + ignore_exc=False, + socket_module=socket, + socket_keepalive=None, + key_prefix=b"", + max_pool_size=None, + pool_idle_timeout=0, + lock_generator=None, + default_noreply=True, + allow_unicode_keys=False, + encoding="ascii", + tls_context=None, + ): self.server = normalize_server_spec(server) self.serde = serde or LegacyWrappingSerde(serializer, deserializer) self.connect_timeout = connect_timeout @@ -1205,7 +1221,7 @@ class PooledClient: self.default_noreply = default_noreply self.allow_unicode_keys = allow_unicode_keys if isinstance(key_prefix, str): - key_prefix = key_prefix.encode('ascii') + key_prefix = key_prefix.encode("ascii") if not isinstance(key_prefix, bytes): raise TypeError("key_prefix should be bytes.") self.key_prefix = key_prefix @@ -1214,14 +1230,16 @@ class PooledClient: after_remove=lambda client: client.close(), max_size=max_pool_size, idle_timeout=pool_idle_timeout, - lock_generator=lock_generator) + lock_generator=lock_generator, + ) self.encoding = encoding self.tls_context = tls_context def check_key(self, key): """Checks key and add key_prefix.""" - return check_key_helper(key, allow_unicode_keys=self.allow_unicode_keys, - key_prefix=self.key_prefix) + return check_key_helper( + key, allow_unicode_keys=self.allow_unicode_keys, key_prefix=self.key_prefix + ) def _create_client(self): return self.client_class( @@ -1238,7 +1256,8 @@ class PooledClient: key_prefix=self.key_prefix, default_noreply=self.default_noreply, allow_unicode_keys=self.allow_unicode_keys, - tls_context=self.tls_context) + tls_context=self.tls_context, + ) def close(self): self.client_pool.clear() @@ -1247,35 +1266,37 @@ class PooledClient: def set(self, key, value, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.set(key, value, expire=expire, noreply=noreply, - flags=flags) + return client.set(key, value, expire=expire, noreply=noreply, flags=flags) def set_many(self, values, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.set_many(values, expire=expire, noreply=noreply, - flags=flags) + return client.set_many(values, expire=expire, noreply=noreply, flags=flags) set_multi = set_many def replace(self, key, value, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.replace(key, value, expire=expire, noreply=noreply, - flags=flags) + return client.replace( + key, value, expire=expire, noreply=noreply, flags=flags + ) def append(self, key, value, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.append(key, value, expire=expire, noreply=noreply, - flags=flags) + return client.append( + key, value, expire=expire, noreply=noreply, flags=flags + ) def prepend(self, key, value, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.prepend(key, value, expire=expire, noreply=noreply, - flags=flags) + return client.prepend( + key, value, expire=expire, noreply=noreply, flags=flags + ) def cas(self, key, value, cas, expire=0, noreply=False, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.cas(key, value, cas, - expire=expire, noreply=noreply, flags=flags) + return client.cas( + key, value, cas, expire=expire, noreply=noreply, flags=flags + ) def get(self, key, default=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: @@ -1331,8 +1352,7 @@ class PooledClient: def add(self, key, value, expire=0, noreply=None, flags=None): with self.client_pool.get_and_release(destroy_on_fail=True) as client: - return client.add(key, value, expire=expire, noreply=noreply, - flags=flags) + return client.add(key, value, expire=expire, noreply=noreply, flags=flags) def incr(self, key, value, noreply=False): with self.client_pool.get_and_release(destroy_on_fail=True) as client: @@ -1409,7 +1429,7 @@ def _readline(sock, buf): """ chunks = [] - last_char = b'' + last_char = b"" while True: # We're reading in chunks, so "\r\n" could appear in one chunk, @@ -1418,14 +1438,14 @@ 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 == b'\r' and buf[0:1] == b'\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:], b''.join(chunks) - elif buf.find(b'\r\n') != -1: + 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, b''.join(chunks) + return after, b"".join(chunks) if buf: chunks.append(buf) @@ -1476,9 +1496,9 @@ def _readvalue(sock, buf, size): chunks[-1] = chunks[-1][:-1] else: # Just remove the "\r\n" from the latest chunk - chunks.append(buf[:rlen - 2]) + chunks.append(buf[: rlen - 2]) - return buf[rlen:], b''.join(chunks) + return buf[rlen:], b"".join(chunks) def _recv(sock, size): diff --git a/pymemcache/client/hash.py b/pymemcache/client/hash.py index e5d89fe..07052fe 100644 --- a/pymemcache/client/hash.py +++ b/pymemcache/client/hash.py @@ -19,6 +19,7 @@ class HashClient: """ A client for communicating with a cluster of memcached servers """ + #: :class:`Client` class used to create new clients client_class = Client @@ -34,7 +35,7 @@ class HashClient: no_delay=False, socket_module=socket, socket_keepalive=None, - key_prefix=b'', + key_prefix=b"", max_pool_size=None, pool_idle_timeout=0, lock_generator=None, @@ -45,8 +46,8 @@ class HashClient: ignore_exc=False, allow_unicode_keys=False, default_noreply=True, - encoding='ascii', - tls_context=None + encoding="ascii", + tls_context=None, ): """ Constructor. @@ -88,27 +89,29 @@ class HashClient: self.hasher = hasher() self.default_kwargs = { - 'connect_timeout': connect_timeout, - 'timeout': timeout, - 'no_delay': no_delay, - 'socket_module': socket_module, - 'socket_keepalive': socket_keepalive, - 'key_prefix': key_prefix, - 'serde': serde, - 'serializer': serializer, - 'deserializer': deserializer, - 'allow_unicode_keys': allow_unicode_keys, - 'default_noreply': default_noreply, - 'encoding': encoding, - 'tls_context': tls_context, + "connect_timeout": connect_timeout, + "timeout": timeout, + "no_delay": no_delay, + "socket_module": socket_module, + "socket_keepalive": socket_keepalive, + "key_prefix": key_prefix, + "serde": serde, + "serializer": serializer, + "deserializer": deserializer, + "allow_unicode_keys": allow_unicode_keys, + "default_noreply": default_noreply, + "encoding": encoding, + "tls_context": tls_context, } if use_pooling is True: - self.default_kwargs.update({ - 'max_pool_size': max_pool_size, - 'pool_idle_timeout': pool_idle_timeout, - 'lock_generator': lock_generator - }) + self.default_kwargs.update( + { + "max_pool_size": max_pool_size, + "pool_idle_timeout": pool_idle_timeout, + "lock_generator": lock_generator, + } + ) for server in servers: self.add_server(normalize_server_spec(server)) @@ -117,7 +120,7 @@ class HashClient: def _make_client_key(self, server): if isinstance(server, (list, tuple)) and len(server) == 2: - return '%s:%s' % server + return "%s:%s" % server return server def add_server(self, server, port=None): @@ -125,7 +128,7 @@ class HashClient: # that server wasn't provided as a (host, port) tuple. if port is not None: if not isinstance(server, str): - raise TypeError('Server must be a string when passing port.') + raise TypeError("Server must be a string when passing port.") server = (server, port) _class = PooledClient if self.use_pooling else self.client_class @@ -142,7 +145,7 @@ class HashClient: # that server wasn't provided as a (host, port) tuple. if port is not None: if not isinstance(server, str): - raise TypeError('Server must be a string when passing port.') + raise TypeError("Server must be a string when passing port.") server = (server, port) key = self._make_client_key(server) @@ -161,10 +164,7 @@ class HashClient: if current_time - dead_time > self.dead_timeout: candidates.append(server) for server in candidates: - logger.debug( - 'bringing server back into rotation %s', - server - ) + logger.debug("bringing server back into rotation %s", server) self.add_server(server) del self._dead_clients[server] self._last_dead_check_time = current_time @@ -179,7 +179,7 @@ class HashClient: if server is None: if self.ignore_exc is True: return - raise MemcacheError('All servers seem to be down right now') + raise MemcacheError("All servers seem to be down right now") return self.clients[server] @@ -192,12 +192,10 @@ class HashClient: # we haven't tried our max amount yet, if it has been enough # time lets just retry using it - if failed_metadata['attempts'] < self.retry_attempts: - failed_time = failed_metadata['failed_time'] + if failed_metadata["attempts"] < self.retry_attempts: + failed_time = failed_metadata["failed_time"] if time.time() - failed_time > self.retry_timeout: - logger.debug( - 'retrying failed server: %s', client.server - ) + logger.debug("retrying failed server: %s", client.server) result = func(*args, **kwargs) # we were successful, lets remove it from the failed # clients @@ -207,7 +205,7 @@ class HashClient: else: # We've reached our max retry attempts, we need to mark # the sever as dead - logger.debug('marking server as dead: %s', client.server) + logger.debug("marking server as dead: %s", client.server) self.remove_server(client.server) result = func(*args, **kwargs) @@ -243,14 +241,13 @@ class HashClient: # we haven't tried our max amount yet, if it has been enough # time lets just retry using it - if failed_metadata['attempts'] < self.retry_attempts: - failed_time = failed_metadata['failed_time'] + if failed_metadata["attempts"] < self.retry_attempts: + failed_time = failed_metadata["failed_time"] if time.time() - failed_time > self.retry_timeout: - logger.debug( - 'retrying failed server: %s', client.server - ) + logger.debug("retrying failed server: %s", client.server) succeeded, failed, err = self._set_many( - client, values, *args, **kwargs) + client, values, *args, **kwargs + ) if err is not None: raise err # we were successful, lets remove it from the failed @@ -261,12 +258,10 @@ class HashClient: else: # We've reached our max retry attempts, we need to mark # the sever as dead - logger.debug('marking server as dead: %s', client.server) + logger.debug("marking server as dead: %s", client.server) self.remove_server(client.server) - succeeded, failed, err = self._set_many( - client, values, *args, **kwargs - ) + succeeded, failed, err = self._set_many(client, values, *args, **kwargs) if err is not None: raise err @@ -293,23 +288,17 @@ class HashClient: def _mark_failed_server(self, server): # This client has never failed, lets mark it for failure - if ( - server not in self._failed_clients and - self.retry_attempts > 0 - ): + if server not in self._failed_clients and self.retry_attempts > 0: self._failed_clients[server] = { - 'failed_time': time.time(), - 'attempts': 0, + "failed_time": time.time(), + "attempts": 0, } # We aren't allowing any retries, we should mark the server as # dead immediately - elif ( - server not in self._failed_clients and - self.retry_attempts <= 0 - ): + elif server not in self._failed_clients and self.retry_attempts <= 0: self._failed_clients[server] = { - 'failed_time': time.time(), - 'attempts': 0, + "failed_time": time.time(), + "attempts": 0, } logger.debug("marking server as dead %s", server) self.remove_server(server) @@ -317,8 +306,8 @@ class HashClient: # to reflect that we have attempted it again else: failed_metadata = self._failed_clients[server] - failed_metadata['attempts'] += 1 - failed_metadata['failed_time'] = time.time() + failed_metadata["attempts"] += 1 + failed_metadata["failed_time"] = time.time() self._failed_clients[server] = failed_metadata def _run_cmd(self, cmd, key, default_val, *args, **kwargs): @@ -330,9 +319,7 @@ class HashClient: func = getattr(client, cmd) args = list(args) args.insert(0, key) - return self._safely_run_func( - client, func, default_val, *args, **kwargs - ) + return self._safely_run_func(client, func, default_val, *args, **kwargs) def _set_many(self, client, values, *args, **kwargs): failed = [] @@ -354,16 +341,16 @@ class HashClient: disconnect_all = close def set(self, key, *args, **kwargs): - return self._run_cmd('set', key, False, *args, **kwargs) + return self._run_cmd("set", key, False, *args, **kwargs) def get(self, key, default=None, **kwargs): - return self._run_cmd('get', key, default, default=default, **kwargs) + return self._run_cmd("get", key, default, default=default, **kwargs) def incr(self, key, *args, **kwargs): - return self._run_cmd('incr', key, False, *args, **kwargs) + return self._run_cmd("incr", key, False, *args, **kwargs) def decr(self, key, *args, **kwargs): - return self._run_cmd('decr', key, False, *args, **kwargs) + return self._run_cmd("decr", key, False, *args, **kwargs) def set_many(self, values, *args, **kwargs): client_batches = collections.defaultdict(dict) @@ -380,9 +367,7 @@ class HashClient: for server, values in client_batches.items(): client = self.clients[self._make_client_key(server)] - failed += self._safely_run_set_many( - client, values, *args, **kwargs - ) + failed += self._safely_run_set_many(client, values, *args, **kwargs) return failed @@ -410,10 +395,7 @@ class HashClient: else: get_func = client.get_many - result = self._safely_run_func( - client, - get_func, {}, *new_args, **kwargs - ) + result = self._safely_run_func(client, get_func, {}, *new_args, **kwargs) end.update(result) return end @@ -421,7 +403,7 @@ class HashClient: get_multi = get_many def gets(self, key, *args, **kwargs): - return self._run_cmd('gets', key, None, *args, **kwargs) + return self._run_cmd("gets", key, None, *args, **kwargs) def gets_many(self, keys, *args, **kwargs): return self.get_many(keys, gets=True, *args, **kwargs) @@ -429,32 +411,32 @@ class HashClient: gets_multi = gets_many def add(self, key, *args, **kwargs): - return self._run_cmd('add', key, False, *args, **kwargs) + return self._run_cmd("add", key, False, *args, **kwargs) def prepend(self, key, *args, **kwargs): - return self._run_cmd('prepend', key, False, *args, **kwargs) + return self._run_cmd("prepend", key, False, *args, **kwargs) def append(self, key, *args, **kwargs): - return self._run_cmd('append', key, False, *args, **kwargs) + return self._run_cmd("append", key, False, *args, **kwargs) def delete(self, key, *args, **kwargs): - return self._run_cmd('delete', key, False, *args, **kwargs) + return self._run_cmd("delete", key, False, *args, **kwargs) def delete_many(self, keys, *args, **kwargs): for key in keys: - self._run_cmd('delete', key, False, *args, **kwargs) + self._run_cmd("delete", key, False, *args, **kwargs) return True delete_multi = delete_many def cas(self, key, *args, **kwargs): - return self._run_cmd('cas', key, False, *args, **kwargs) + return self._run_cmd("cas", key, False, *args, **kwargs) def replace(self, key, *args, **kwargs): - return self._run_cmd('replace', key, False, *args, **kwargs) + return self._run_cmd("replace", key, False, *args, **kwargs) def touch(self, key, *args, **kwargs): - return self._run_cmd('touch', key, False, *args, **kwargs) + return self._run_cmd("touch", key, False, *args, **kwargs) def flush_all(self): for client in self.clients.values(): diff --git a/pymemcache/client/murmur3.py b/pymemcache/client/murmur3.py index 787eeaf..b42cc09 100644 --- a/pymemcache/client/murmur3.py +++ b/pymemcache/client/murmur3.py @@ -1,40 +1,44 @@ def murmur3_32(data, seed=0): """MurmurHash3 was written by Austin Appleby, and is placed in the - public domain. The author hereby disclaims copyright to this source - code.""" + public domain. The author hereby disclaims copyright to this source + code.""" - c1 = 0xcc9e2d51 - c2 = 0x1b873593 + c1 = 0xCC9E2D51 + c2 = 0x1B873593 length = len(data) h1 = seed - roundedEnd = (length & 0xfffffffc) # round down to 4 byte block + roundedEnd = length & 0xFFFFFFFC # round down to 4 byte block for i in range(0, roundedEnd, 4): # little endian load order - k1 = (ord(data[i]) & 0xff) | ((ord(data[i + 1]) & 0xff) << 8) | \ - ((ord(data[i + 2]) & 0xff) << 16) | (ord(data[i + 3]) << 24) + k1 = ( + (ord(data[i]) & 0xFF) + | ((ord(data[i + 1]) & 0xFF) << 8) + | ((ord(data[i + 2]) & 0xFF) << 16) + | (ord(data[i + 3]) << 24) + ) k1 *= c1 - k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15) + k1 = (k1 << 15) | ((k1 & 0xFFFFFFFF) >> 17) # ROTL32(k1,15) k1 *= c2 h1 ^= k1 - h1 = (h1 << 13) | ((h1 & 0xffffffff) >> 19) # ROTL32(h1,13) - h1 = h1 * 5 + 0xe6546b64 + h1 = (h1 << 13) | ((h1 & 0xFFFFFFFF) >> 19) # ROTL32(h1,13) + h1 = h1 * 5 + 0xE6546B64 # tail k1 = 0 val = length & 0x03 if val == 3: - k1 = (ord(data[roundedEnd + 2]) & 0xff) << 16 + k1 = (ord(data[roundedEnd + 2]) & 0xFF) << 16 # fallthrough if val in [2, 3]: - k1 |= (ord(data[roundedEnd + 1]) & 0xff) << 8 + k1 |= (ord(data[roundedEnd + 1]) & 0xFF) << 8 # fallthrough if val in [1, 2, 3]: - k1 |= ord(data[roundedEnd]) & 0xff + k1 |= ord(data[roundedEnd]) & 0xFF k1 *= c1 - k1 = (k1 << 15) | ((k1 & 0xffffffff) >> 17) # ROTL32(k1,15) + k1 = (k1 << 15) | ((k1 & 0xFFFFFFFF) >> 17) # ROTL32(k1,15) k1 *= c2 h1 ^= k1 @@ -42,10 +46,10 @@ def murmur3_32(data, seed=0): h1 ^= length # fmix(h1) - h1 ^= ((h1 & 0xffffffff) >> 16) - h1 *= 0x85ebca6b - h1 ^= ((h1 & 0xffffffff) >> 13) - h1 *= 0xc2b2ae35 - h1 ^= ((h1 & 0xffffffff) >> 16) + h1 ^= (h1 & 0xFFFFFFFF) >> 16 + h1 *= 0x85EBCA6B + h1 ^= (h1 & 0xFFFFFFFF) >> 13 + h1 *= 0xC2B2AE35 + h1 ^= (h1 & 0xFFFFFFFF) >> 16 - return h1 & 0xffffffff + return h1 & 0xFFFFFFFF diff --git a/pymemcache/client/rendezvous.py b/pymemcache/client/rendezvous.py index 00583fc..eb4d9ec 100644 --- a/pymemcache/client/rendezvous.py +++ b/pymemcache/client/rendezvous.py @@ -3,13 +3,14 @@ from pymemcache.client.murmur3 import murmur3_32 class RendezvousHash: """ - Implements the Highest Random Weight (HRW) hashing algorithm most - commonly referred to as rendezvous hashing. + Implements the Highest Random Weight (HRW) hashing algorithm most + commonly referred to as rendezvous hashing. - Originally developed as part of python-clandestined. + Originally developed as part of python-clandestined. - Copyright (c) 2014 Ernest W. Durbin III + Copyright (c) 2014 Ernest W. Durbin III """ + def __init__(self, nodes=None, seed=0, hash_function=murmur3_32): """ Constructor. diff --git a/pymemcache/client/retrying.py b/pymemcache/client/retrying.py index 8c8f3a9..22d7898 100644 --- a/pymemcache/client/retrying.py +++ b/pymemcache/client/retrying.py @@ -27,9 +27,7 @@ def _ensure_tuple_argument(argument_name, argument_value): if argument_value is None: return tuple() elif not isinstance(argument_value, (tuple, set, list)): - raise ValueError( - "%s must be either a tuple, a set or a list." % argument_name - ) + raise ValueError("%s must be either a tuple, a set or a list." % argument_name) # Convert the argument before checking contents. argument_tuple = tuple(argument_value) @@ -51,12 +49,7 @@ class RetryingClient(object): """ def __init__( - self, - client, - attempts=2, - retry_delay=0, - retry_for=None, - do_not_retry_for=None + self, client, attempts=2, retry_delay=0, retry_for=None, do_not_retry_for=None ): """ Constructor for RetryingClient. @@ -113,7 +106,7 @@ class RetryingClient(object): for exc_class in self._retry_for: if exc_class in self._do_not_retry_for: raise ValueError( - "Exception class \"%s\" was present in both `retry_for` " + 'Exception class "%s" was present in both `retry_for` ' "and `do_not_retry_for`. Any exception class is only " "allowed in a single argument." % repr(exc_class) ) @@ -142,12 +135,15 @@ class RetryingClient(object): # - self._retry_for is set, and we do not match. # - self._do_not_retry_for is set, and we do match. # - name is not actually a member of the client class. - if attempt >= self._attempts - 1 \ - or (self._retry_for - and not isinstance(exc, self._retry_for)) \ - or (self._do_not_retry_for - and isinstance(exc, self._do_not_retry_for)) \ - or name not in self._client_dir: + if ( + attempt >= self._attempts - 1 + or (self._retry_for and not isinstance(exc, self._retry_for)) + or ( + self._do_not_retry_for + and isinstance(exc, self._do_not_retry_for) + ) + or name not in self._client_dir + ): raise exc # Sleep and try again. @@ -159,10 +155,7 @@ class RetryingClient(object): def __getattr__(self, name): return lambda *args, **kwargs: self._retry( - name, - self._client.__getattribute__(name), - *args, - **kwargs + name, self._client.__getattribute__(name), *args, **kwargs ) # We implement these explicitly because they're "magic" functions and won't diff --git a/pymemcache/exceptions.py b/pymemcache/exceptions.py index 416fa0a..138a0db 100644 --- a/pymemcache/exceptions.py +++ b/pymemcache/exceptions.py @@ -7,24 +7,28 @@ class MemcacheClientError(MemcacheError): """Raised when memcached fails to parse the arguments to a request, likely due to a malformed key and/or value, a bug in this library, or a version mismatch with memcached.""" + pass class MemcacheUnknownCommandError(MemcacheClientError): """Raised when memcached fails to parse a request, likely due to a bug in this library or a version mismatch with memcached.""" + pass class MemcacheIllegalInputError(MemcacheClientError): """Raised when a key or value is not legal for Memcache (see the class docs for Client for more details).""" + pass class MemcacheServerError(MemcacheError): """Raised when memcached reports a failure while processing a request, likely due to a bug or transient issue in memcached.""" + pass @@ -32,6 +36,7 @@ class MemcacheUnknownError(MemcacheError): """Raised when this library receives a response from memcached that it cannot parse, likely due to a bug in this library or a version mismatch with memcached.""" + pass diff --git a/pymemcache/pool.py b/pymemcache/pool.py index 1422835..10277b6 100644 --- a/pymemcache/pool.py +++ b/pymemcache/pool.py @@ -22,10 +22,14 @@ import time class ObjectPool: """A pool of objects that release/creates/destroys as needed.""" - def __init__(self, obj_creator, - after_remove=None, max_size=None, - idle_timeout=0, - lock_generator=None): + def __init__( + self, + obj_creator, + after_remove=None, + max_size=None, + idle_timeout=0, + lock_generator=None, + ): self._used_objs = collections.deque() self._free_objs = collections.deque() self._obj_creator = obj_creator @@ -78,9 +82,9 @@ class ObjectPool: # No free objects, create a new one. curr_count = len(self._used_objs) if curr_count >= self.max_size: - raise RuntimeError("Too many objects," - " %s >= %s" % (curr_count, - self.max_size)) + raise RuntimeError( + "Too many objects," " %s >= %s" % (curr_count, self.max_size) + ) obj = self._obj_creator() self._used_objs.append(obj) diff --git a/pymemcache/serde.py b/pymemcache/serde.py index daa24c0..f92aeb7 100644 --- a/pymemcache/serde.py +++ b/pymemcache/serde.py @@ -44,7 +44,7 @@ def _python_memcache_serializer(key, value, pickle_version=None): elif value_type is str: flags |= FLAG_TEXT - value = value.encode('utf8') + value = value.encode("utf8") elif value_type is int: flags |= FLAG_INTEGER @@ -73,7 +73,7 @@ def python_memcache_deserializer(key, value, flags): return value elif flags & FLAG_TEXT: - return value.decode('utf8') + return value.decode("utf8") elif flags & FLAG_INTEGER: return int(value) @@ -87,7 +87,7 @@ def python_memcache_deserializer(key, value, flags): unpickler = pickle.Unpickler(buf) return unpickler.load() except Exception: - logging.info('Pickle error', exc_info=True) + logging.info("Pickle error", exc_info=True) return None return value @@ -110,6 +110,7 @@ class PickleSerde: For more details on the serialization protocol, see the class documentation for :py:class:`pymemcache.client.base.Client` """ + def __init__(self, pickle_version=DEFAULT_PICKLE_VERSION): self._serialize_func = get_python_memcache_serializer(pickle_version) @@ -130,6 +131,7 @@ class LegacyWrappingSerde: The serializer_func and deserializer_func are expected to be None in the case that they are missing. """ + def __init__(self, serializer_func, deserializer_func): self.serialize = serializer_func or self._default_serialize self.deserialize = deserializer_func or self._default_deserialize diff --git a/pymemcache/test/conftest.py b/pymemcache/test/conftest.py index 79dc45d..befd70d 100644 --- a/pymemcache/test/conftest.py +++ b/pymemcache/test/conftest.py @@ -5,69 +5,82 @@ import ssl def pytest_addoption(parser): - parser.addoption('--server', action='store', default='localhost', - help='memcached server') + parser.addoption( + "--server", action="store", default="localhost", help="memcached server" + ) - parser.addoption('--port', action='store', default='11211', - help='memcached server port') + parser.addoption( + "--port", action="store", default="11211", help="memcached server port" + ) - parser.addoption('--tls-server', action='store', default='localhost', - help='TLS memcached server') + parser.addoption( + "--tls-server", action="store", default="localhost", help="TLS memcached server" + ) - parser.addoption('--tls-port', action='store', default='11212', - help='TLS memcached server port') + parser.addoption( + "--tls-port", action="store", default="11212", help="TLS memcached server port" + ) - parser.addoption('--size', action='store', default=1024, - help='size of data in benchmarks') + parser.addoption( + "--size", action="store", default=1024, help="size of data in benchmarks" + ) - parser.addoption('--count', action='store', default=10000, - help='number of iterations to run each benchmark') + parser.addoption( + "--count", + action="store", + default=10000, + help="number of iterations to run each benchmark", + ) - parser.addoption('--keys', action='store', default=20, - help='number of keys to use for multi benchmarks') + parser.addoption( + "--keys", + action="store", + default=20, + help="number of keys to use for multi benchmarks", + ) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def host(request): return request.config.option.server -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def port(request): return int(request.config.option.port) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tls_host(request): return request.config.option.tls_server -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tls_port(request): return int(request.config.option.tls_port) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def size(request): return int(request.config.option.size) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def count(request): return int(request.config.option.count) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def keys(request): return int(request.config.option.keys) -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def pairs(size, keys): - return {'pymemcache_test:%d' % i: 'X' * size for i in range(keys)} + return {"pymemcache_test:%d" % i: "X" * size for i in range(keys)} -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def tls_context(): return ssl.create_default_context( cafile=os.path.join(os.path.dirname(__file__), "certs/ca-root.crt") @@ -75,7 +88,7 @@ def tls_context(): def pytest_generate_tests(metafunc): - if 'socket_module' in metafunc.fixturenames: + if "socket_module" in metafunc.fixturenames: socket_modules = [socket] try: from gevent import socket as gevent_socket @@ -86,16 +99,12 @@ def pytest_generate_tests(metafunc): metafunc.parametrize("socket_module", socket_modules) - if 'client_class' in metafunc.fixturenames: + if "client_class" in metafunc.fixturenames: from pymemcache.client.base import PooledClient, Client from pymemcache.client.hash import HashClient class HashClientSingle(HashClient): def __init__(self, server, *args, **kwargs): - super().__init__( - [server], *args, **kwargs - ) + super().__init__([server], *args, **kwargs) - metafunc.parametrize( - "client_class", [Client, PooledClient, HashClientSingle] - ) + metafunc.parametrize("client_class", [Client, PooledClient, HashClientSingle]) diff --git a/pymemcache/test/test_benchmark.py b/pymemcache/test/test_benchmark.py index 408ea7b..61cd96a 100644 --- a/pymemcache/test/test_benchmark.py +++ b/pymemcache/test/test_benchmark.py @@ -17,12 +17,14 @@ import pytest try: import pylibmc + HAS_PYLIBMC = True except Exception: HAS_PYLIBMC = False try: import memcache + HAS_MEMCACHE = True except Exception: HAS_MEMCACHE = False @@ -30,27 +32,30 @@ except Exception: try: import pymemcache.client + HAS_PYMEMCACHE = True except Exception: HAS_PYMEMCACHE = False -@pytest.fixture(params=[ - "pylibmc", - "memcache", - "pymemcache", -]) +@pytest.fixture( + params=[ + "pylibmc", + "memcache", + "pymemcache", + ] +) def client(request, host, port): if request.param == "pylibmc": if not HAS_PYLIBMC: pytest.skip("requires pylibmc") - client = pylibmc.Client([f'{host}:{port}']) + client = pylibmc.Client([f"{host}:{port}"]) client.behaviors = {"tcp_nodelay": True} elif request.param == "memcache": if not HAS_MEMCACHE: pytest.skip("requires python-memcached") - client = memcache.Client([f'{host}:{port}']) + client = memcache.Client([f"{host}:{port}"]) elif request.param == "pymemcache": if not HAS_PYMEMCACHE: diff --git a/pymemcache/test/test_client.py b/pymemcache/test/test_client.py index d286e71..56f3895 100644 --- a/pymemcache/test/test_client.py +++ b/pymemcache/test/test_client.py @@ -30,7 +30,7 @@ from pymemcache.client.base import ( Client, normalize_server_spec, KeepaliveOpts, - check_key_helper + check_key_helper, ) from pymemcache.exceptions import ( MemcacheClientError, @@ -38,7 +38,7 @@ from pymemcache.exceptions import ( MemcacheUnexpectedCloseError, MemcacheUnknownCommandError, MemcacheUnknownError, - MemcacheIllegalInputError + MemcacheIllegalInputError, ) from pymemcache import pool @@ -54,20 +54,18 @@ def is_ipv6(address): @pytest.mark.parametrize( - 'key,allow_unicode_keys,key_prefix,ex_exception,ex_excinfo', + "key,allow_unicode_keys,key_prefix,ex_exception,ex_excinfo", [ - ('b'*251, True, b'', - MemcacheIllegalInputError, 'Key is too long'), - ('foo bar', True, b'', - MemcacheIllegalInputError, 'Key contains whitespace'), - ('\00', True, b'', - MemcacheIllegalInputError, 'Key contains null'), - (None, True, b'', TypeError, None), - ]) + ("b" * 251, True, b"", MemcacheIllegalInputError, "Key is too long"), + ("foo bar", True, b"", MemcacheIllegalInputError, "Key contains whitespace"), + ("\00", True, b"", MemcacheIllegalInputError, "Key contains null"), + (None, True, b"", TypeError, None), + ], +) @pytest.mark.unit() -def test_check_key_helper_failing_conditions(key, allow_unicode_keys, - key_prefix, ex_exception, - ex_excinfo): +def test_check_key_helper_failing_conditions( + key, allow_unicode_keys, key_prefix, ex_exception, ex_excinfo +): with pytest.raises(ex_exception) as excinfo: check_key_helper(key, allow_unicode_keys, key_prefix) @@ -81,7 +79,7 @@ def test_check_key_helper_failing_conditions(key, allow_unicode_keys, @pytest.mark.unit() def test_check_key_helper(): - assert check_key_helper(b"key", True, b'') == b"key" + assert check_key_helper(b"key", True, b"") == b"key" assert check_key_helper("key", True) == b"key" assert isinstance(check_key_helper(b"key", True), bytes) assert check_key_helper("", True) == b"" @@ -154,34 +152,27 @@ class MockSocketModule: def socket(self, family, type, proto=0, fileno=None): socket = MockSocket( - [], - connect_failure=self.connect_failure, - close_failure=self.close_failure) + [], connect_failure=self.connect_failure, close_failure=self.close_failure + ) self.sockets.append(socket) return socket def getaddrinfo(self, host, port, family=0, type=0, proto=0, flags=0): - family = family or ( - socket.AF_INET6 if is_ipv6(host) else socket.AF_INET - ) + family = family or (socket.AF_INET6 if is_ipv6(host) else socket.AF_INET) type = type or socket.SOCK_STREAM proto = proto or socket.IPPROTO_TCP sockaddr = ( - ('::1', 11211, 0, 0) - if family == socket.AF_INET6 - else ('127.0.0.1', 11211) + ("::1", 11211, 0, 0) if family == socket.AF_INET6 else ("127.0.0.1", 11211) ) - return [(family, type, proto, '', sockaddr)] + return [(family, type, proto, "", sockaddr)] def __getattr__(self, name): return getattr(socket, name) class CustomizedClient(Client): - - def _extract_value(self, expect_cas, line, buf, remapped_keys, - prefixed_keys): - return b'key', b'value', b'END\r\n' + def _extract_value(self, expect_cas, line, buf, remapped_keys, prefixed_keys): + return b"key", b"value", b"END\r\n" @pytest.mark.unit() @@ -192,8 +183,9 @@ class ClientTestMixin: # ensure methods are checking whether self.sock is None before # attempting to use it sock = MockSocket(list(mock_socket_values)) - client._connect = mock.Mock(side_effect=functools.partial( - setattr, client, "sock", sock)) + client._connect = mock.Mock( + side_effect=functools.partial(setattr, client, "sock", sock) + ) return client def make_customized_client(self, mock_socket_values, **kwargs): @@ -202,246 +194,255 @@ class ClientTestMixin: # ensure methods are checking whether self.sock is None before # attempting to use it sock = MockSocket(list(mock_socket_values)) - client._connect = mock.Mock(side_effect=functools.partial( - setattr, client, "sock", sock)) + client._connect = mock.Mock( + side_effect=functools.partial(setattr, client, "sock", sock) + ) return client def test_set_success(self): - client = self.make_client([b'STORED\r\n']) - result = client.set(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.set(b"key", b"value", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.set(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.set(b"key", b"value", noreply=False) assert result is True # unit test for set operation with parameter flags - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.set(b'key', b'value', noreply=False, flags=0x00000030) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.set(b"key", b"value", noreply=False, flags=0x00000030) assert result is True def test_set_unicode_key(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set('\u0FFF', b'value', noreply=False) + client.set("\u0FFF", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_unicode_key_ok(self): - client = self.make_client([b'STORED\r\n'], allow_unicode_keys=True) + client = self.make_client([b"STORED\r\n"], allow_unicode_keys=True) - result = client.set('\u0FFF', b'value', noreply=False) + result = client.set("\u0FFF", b"value", noreply=False) assert result is True def test_set_unicode_key_ok_snowman(self): - client = self.make_client([b'STORED\r\n'], allow_unicode_keys=True) + client = self.make_client([b"STORED\r\n"], allow_unicode_keys=True) - result = client.set('my☃', b'value', noreply=False) + result = client.set("my☃", b"value", noreply=False) assert result is True def test_set_unicode_char_in_middle_of_key(self): - client = self.make_client([b'STORED\r\n']) + client = self.make_client([b"STORED\r\n"]) def _set(): - client.set('helloworld_\xb1901520_%c3', b'value', noreply=False) + client.set("helloworld_\xb1901520_%c3", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_unicode_char_in_middle_of_key_snowman(self): - client = self.make_client([b'STORED\r\n']) + client = self.make_client([b"STORED\r\n"]) def _set(): - client.set('my☃', b'value', noreply=False) + client.set("my☃", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_unicode_value(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set(b'key', '\u0FFF', noreply=False) + client.set(b"key", "\u0FFF", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_unicode_char_in_middle_of_key_ok(self): - client = self.make_client([b'STORED\r\n'], allow_unicode_keys=True) + client = self.make_client([b"STORED\r\n"], allow_unicode_keys=True) - result = client.set('helloworld_\xb1901520_%c3', b'value', - noreply=False) + result = client.set("helloworld_\xb1901520_%c3", b"value", noreply=False) assert result is True def test_set_noreply(self): client = self.make_client([]) - result = client.set(b'key', b'value', noreply=True) + result = client.set(b"key", b"value", noreply=True) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([], encoding='utf-8') - result = client.set(b'key', b'value', noreply=True) + client = self.make_client([], encoding="utf-8") + result = client.set(b"key", b"value", noreply=True) assert result is True def test_set_many_success(self): - client = self.make_client([b'STORED\r\n']) - result = client.set_many({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.set_many({b"key": b"value"}, noreply=False) assert result == [] # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.set_many({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.set_many({b"key": b"value"}, noreply=False) assert result == [] def test_set_multi_success(self): # Should just map to set_many - client = self.make_client([b'STORED\r\n']) - result = client.set_multi({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.set_multi({b"key": b"value"}, noreply=False) assert result == [] # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.set_multi({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.set_multi({b"key": b"value"}, noreply=False) assert result == [] def test_add_stored(self): - client = self.make_client([b'STORED\r', b'\n']) - result = client.add(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r", b"\n"]) + result = client.add(b"key", b"value", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r', b'\n'], encoding='utf-8') - result = client.add(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r", b"\n"], encoding="utf-8") + result = client.add(b"key", b"value", noreply=False) assert result is True def test_add_not_stored(self): - client = self.make_client([b'STORED\r', b'\n', - b'NOT_', b'STOR', b'ED', b'\r\n']) - client.add(b'key', b'value', noreply=False) - result = client.add(b'key', b'value', noreply=False) + client = self.make_client( + [b"STORED\r", b"\n", b"NOT_", b"STOR", b"ED", b"\r\n"] + ) + client.add(b"key", b"value", noreply=False) + result = client.add(b"key", b"value", noreply=False) assert result is False # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r', b'\n', - b'NOT_', b'STOR', b'ED', b'\r\n'], - encoding='utf-8') - client.add(b'key', b'value', noreply=False) - result = client.add(b'key', b'value', noreply=False) + client = self.make_client( + [b"STORED\r", b"\n", b"NOT_", b"STOR", b"ED", b"\r\n"], encoding="utf-8" + ) + client.add(b"key", b"value", noreply=False) + result = client.add(b"key", b"value", noreply=False) assert result is False def test_get_not_found(self): - client = self.make_client([b'END\r\n']) - result = client.get(b'key') + client = self.make_client([b"END\r\n"]) + result = client.get(b"key") assert result is None # Unit test for customized client (override _extract_value) - client = self.make_customized_client([b'END\r\n']) - result = client.get(b'key') + client = self.make_customized_client([b"END\r\n"]) + result = client.get(b"key") assert result is None def test_space_key(self): - client = self.make_client([b'']) + client = self.make_client([b""]) with pytest.raises(MemcacheIllegalInputError): - client.get(b'space key') + client.get(b"space key") with pytest.raises(MemcacheIllegalInputError): - client.set(b'space key', b'value') + client.set(b"space key", b"value") def test_get_not_found_default(self): - client = self.make_client([b'END\r\n']) - result = client.get(b'key', default='foobar') - assert result == 'foobar' + client = self.make_client([b"END\r\n"]) + result = client.get(b"key", default="foobar") + assert result == "foobar" # Unit test for customized client (override _extract_value) - client = self.make_customized_client([b'END\r\n']) - result = client.get(b'key', default='foobar') - assert result == 'foobar' + client = self.make_customized_client([b"END\r\n"]) + result = client.get(b"key", default="foobar") + assert result == "foobar" def test_get_ignore_exc_default(self): - client = self.make_client([b'INVALID DATA\r\n'], ignore_exc=True) - result = client.get(b'key', default='foobar') - assert result == 'foobar' + client = self.make_client([b"INVALID DATA\r\n"], ignore_exc=True) + result = client.get(b"key", default="foobar") + assert result == "foobar" # Unit test for customized client (override _extract_value) - client = self.make_client([b'INVALID DATA\r\n'], ignore_exc=True) - result = client.get(b'key', default='foobar') - assert result == 'foobar' + client = self.make_client([b"INVALID DATA\r\n"], ignore_exc=True) + result = client.get(b"key", default="foobar") + assert result == "foobar" def test_get_found(self): - client = self.make_client([ - b'STORED\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n', - ]) - client.set(b'key', b'value', noreply=False) - result = client.get(b'key') - assert result == b'value' + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE key 0 5\r\nvalue\r\nEND\r\n", + ] + ) + client.set(b"key", b"value", noreply=False) + result = client.get(b"key") + assert result == b"value" # Unit test for customized client (override _extract_value) - client = self.make_customized_client([ - b'STORED\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n', - ]) - client.set(b'key', b'value', noreply=False) - result = client.get(b'key') - assert result == b'value' + client = self.make_customized_client( + [ + b"STORED\r\n", + b"VALUE key 0 5\r\nvalue\r\nEND\r\n", + ] + ) + client.set(b"key", b"value", noreply=False) + result = client.get(b"key") + assert result == b"value" def test_get_many_none_found(self): - client = self.make_client([b'END\r\n']) - result = client.get_many([b'key1', b'key2']) + client = self.make_client([b"END\r\n"]) + result = client.get_many([b"key1", b"key2"]) assert result == {} def test_get_multi_none_found(self): - client = self.make_client([b'END\r\n']) - result = client.get_multi([b'key1', b'key2']) + client = self.make_client([b"END\r\n"]) + result = client.get_multi([b"key1", b"key2"]) assert result == {} def test_get_many_some_found(self): - client = self.make_client([ - b'STORED\r\n', - b'VALUE key1 0 6\r\nvalue1\r\nEND\r\n', - ]) - client.set(b'key1', b'value1', noreply=False) - result = client.get_many([b'key1', b'key2']) - assert result == {b'key1': b'value1'} + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE key1 0 6\r\nvalue1\r\nEND\r\n", + ] + ) + client.set(b"key1", b"value1", noreply=False) + result = client.get_many([b"key1", b"key2"]) + assert result == {b"key1": b"value1"} def test_get_many_all_found(self): - client = self.make_client([ - b'STORED\r\n', - b'STORED\r\n', - b'VALUE key1 0 6\r\nvalue1\r\n', - b'VALUE key2 0 6\r\nvalue2\r\nEND\r\n', - ]) - client.set(b'key1', b'value1', noreply=False) - client.set(b'key2', b'value2', noreply=False) - result = client.get_many([b'key1', b'key2']) - assert result == {b'key1': b'value1', b'key2': b'value2'} + client = self.make_client( + [ + b"STORED\r\n", + b"STORED\r\n", + b"VALUE key1 0 6\r\nvalue1\r\n", + b"VALUE key2 0 6\r\nvalue2\r\nEND\r\n", + ] + ) + client.set(b"key1", b"value1", noreply=False) + client.set(b"key2", b"value2", noreply=False) + result = client.get_many([b"key1", b"key2"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} def test_get_unicode_key(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _get(): - client.get('\u0FFF') + client.get("\u0FFF") with pytest.raises(MemcacheIllegalInputError): _get() def test_delete_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.delete(b'key', noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.delete(b"key", noreply=False) assert result is False def test_delete_found(self): - client = self.make_client([b'STORED\r', b'\n', b'DELETED\r\n']) - client.add(b'key', b'value', noreply=False) - result = client.delete(b'key', noreply=False) + client = self.make_client([b"STORED\r", b"\n", b"DELETED\r\n"]) + client.add(b"key", b"value", noreply=False) + result = client.delete(b"key", noreply=False) assert result is True def test_delete_noreply(self): client = self.make_client([]) - result = client.delete(b'key', noreply=True) + result = client.delete(b"key", noreply=True) assert result is True def test_delete_many_no_keys(self): @@ -450,64 +451,56 @@ class ClientTestMixin: assert result is True def test_delete_many_none_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.delete_many([b'key'], noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.delete_many([b"key"], noreply=False) assert result is True def test_delete_many_found(self): - client = self.make_client([b'STORED\r', b'\n', b'DELETED\r\n']) - client.add(b'key', b'value', noreply=False) - result = client.delete_many([b'key'], noreply=False) + client = self.make_client([b"STORED\r", b"\n", b"DELETED\r\n"]) + client.add(b"key", b"value", noreply=False) + result = client.delete_many([b"key"], noreply=False) assert result is True def test_delete_many_some_found(self): - client = self.make_client([ - b'STORED\r\n', - b'DELETED\r\n', - b'NOT_FOUND\r\n' - ]) - client.add(b'key', b'value', noreply=False) - result = client.delete_many([b'key', b'key2'], noreply=False) + client = self.make_client([b"STORED\r\n", b"DELETED\r\n", b"NOT_FOUND\r\n"]) + client.add(b"key", b"value", noreply=False) + result = client.delete_many([b"key", b"key2"], noreply=False) assert result is True def test_delete_multi_some_found(self): - client = self.make_client([ - b'STORED\r\n', - b'DELETED\r\n', - b'NOT_FOUND\r\n' - ]) - client.add(b'key', b'value', noreply=False) - result = client.delete_multi([b'key', b'key2'], noreply=False) + client = self.make_client([b"STORED\r\n", b"DELETED\r\n", b"NOT_FOUND\r\n"]) + client.add(b"key", b"value", noreply=False) + result = client.delete_multi([b"key", b"key2"], noreply=False) assert result is True def test_incr_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.incr(b'key', 1, noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.incr(b"key", 1, noreply=False) assert result is None def test_incr_found(self): - client = self.make_client([b'STORED\r\n', b'1\r\n']) - client.set(b'key', 0, noreply=False) - result = client.incr(b'key', 1, noreply=False) + client = self.make_client([b"STORED\r\n", b"1\r\n"]) + client.set(b"key", 0, noreply=False) + result = client.incr(b"key", 1, noreply=False) assert result == 1 def test_incr_noreply(self): - client = self.make_client([b'STORED\r\n']) - client.set(b'key', 0, noreply=False) + client = self.make_client([b"STORED\r\n"]) + client.set(b"key", 0, noreply=False) client = self.make_client([]) - result = client.incr(b'key', 1, noreply=True) + result = client.incr(b"key", 1, noreply=True) assert result is None def test_decr_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.decr(b'key', 1, noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.decr(b"key", 1, noreply=False) assert result is None def test_decr_found(self): - client = self.make_client([b'STORED\r\n', b'1\r\n']) - client.set(b'key', 2, noreply=False) - result = client.decr(b'key', 1, noreply=False) + client = self.make_client([b"STORED\r\n", b"1\r\n"]) + client.set(b"key", 2, noreply=False) + result = client.decr(b"key", 1, noreply=False) assert result == 1 @@ -516,127 +509,149 @@ class TestClient(ClientTestMixin, unittest.TestCase): Client = Client def test_append_stored(self): - client = self.make_client([b'STORED\r\n']) - result = client.append(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.append(b"key", b"value", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.append(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.append(b"key", b"value", noreply=False) assert result is True def test_prepend_stored(self): - client = self.make_client([b'STORED\r\n']) - result = client.prepend(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.prepend(b"key", b"value", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.prepend(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.prepend(b"key", b"value", noreply=False) assert result is True def test_cas_malformed(self): - client = self.make_client([b'STORED\r\n']) + client = self.make_client([b"STORED\r\n"]) with pytest.raises(MemcacheIllegalInputError): - client.cas(b'key', b'value', None, noreply=False) + client.cas(b"key", b"value", None, noreply=False) with pytest.raises(MemcacheIllegalInputError): - client.cas(b'key', b'value', 'nonintegerstring', noreply=False) + client.cas(b"key", b"value", "nonintegerstring", noreply=False) with pytest.raises(MemcacheIllegalInputError): # even a space makes it a noninteger string - client.cas(b'key', b'value', '123 ', noreply=False) + client.cas(b"key", b"value", "123 ", noreply=False) with pytest.raises(MemcacheIllegalInputError): # non-ASCII digit - client.cas(b'key', b'value', '⁰', noreply=False) + client.cas(b"key", b"value", "⁰", noreply=False) def test_cas_stored(self): - client = self.make_client([b'STORED\r\n']) - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is True def test_cas_exists(self): - client = self.make_client([b'EXISTS\r\n']) - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"EXISTS\r\n"]) + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is False # unit test for encoding passed in __init__() - client = self.make_client([b'EXISTS\r\n'], encoding='utf-8') - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"EXISTS\r\n"], encoding="utf-8") + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is False def test_cas_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is None # unit test for encoding passed in __init__() - client = self.make_client([b'NOT_FOUND\r\n'], encoding='utf-8') - result = client.cas(b'key', b'value', b'123', noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"], encoding="utf-8") + result = client.cas(b"key", b"value", b"123", noreply=False) assert result is None def test_cr_nl_boundaries(self): - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} - - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} - - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} - - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} - - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} - - client = self.make_client([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']) - assert result == {b'key1': b'value1', b'key2': b'value2'} + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} + + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} + + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} + + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} + + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} + + client = self.make_client( + [ + 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"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} def test_delete_exception(self): - client = self.make_client([Exception('fail')]) + client = self.make_client([Exception("fail")]) def _delete(): - client.delete(b'key', noreply=False) + client.delete(b"key", noreply=False) with pytest.raises(Exception): _delete() @@ -644,15 +659,15 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None def test_flush_all(self): - client = self.make_client([b'OK\r\n']) + client = self.make_client([b"OK\r\n"]) result = client.flush_all(noreply=False) assert result is True def test_incr_exception(self): - client = self.make_client([Exception('fail')]) + client = self.make_client([Exception("fail")]) def _incr(): - client.incr(b'key', 1) + client.incr(b"key", 1) with pytest.raises(Exception): _incr() @@ -660,62 +675,63 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None def test_get_error(self): - client = self.make_client([b'ERROR\r\n']) + client = self.make_client([b"ERROR\r\n"]) def _get(): - client.get(b'key') + client.get(b"key") with pytest.raises(MemcacheUnknownCommandError): _get() def test_get_recv_chunks(self): - client = self.make_client([b'VALUE key', b' 0 5\r', b'\nvalue', - b'\r\n', b'END', b'\r', b'\n']) - result = client.get(b'key') - assert result == b'value' + client = self.make_client( + [b"VALUE key", b" 0 5\r", b"\nvalue", b"\r\n", b"END", b"\r", b"\n"] + ) + result = client.get(b"key") + assert result == b"value" def test_get_unknown_error(self): - client = self.make_client([b'foobarbaz\r\n']) + client = self.make_client([b"foobarbaz\r\n"]) def _get(): - client.get(b'key') + client.get(b"key") with pytest.raises(MemcacheUnknownError): _get() def test_gets_not_found(self): - client = self.make_client([b'END\r\n']) - result = client.gets(b'key') + client = self.make_client([b"END\r\n"]) + result = client.gets(b"key") assert result == (None, None) def test_gets_not_found_defaults(self): - client = self.make_client([b'END\r\n']) - result = client.gets(b'key', default='foo', cas_default='bar') - assert result == ('foo', 'bar') + client = self.make_client([b"END\r\n"]) + result = client.gets(b"key", default="foo", cas_default="bar") + assert result == ("foo", "bar") def test_gets_found(self): - client = self.make_client([b'VALUE key 0 5 10\r\nvalue\r\nEND\r\n']) - result = client.gets(b'key') - assert result == (b'value', b'10') + client = self.make_client([b"VALUE key 0 5 10\r\nvalue\r\nEND\r\n"]) + result = client.gets(b"key") + assert result == (b"value", b"10") def test_gets_many_none_found(self): - client = self.make_client([b'END\r\n']) - result = client.gets_many([b'key1', b'key2']) + client = self.make_client([b"END\r\n"]) + result = client.gets_many([b"key1", b"key2"]) assert result == {} def test_gets_many_some_found(self): - client = self.make_client([b'VALUE key1 0 6 11\r\nvalue1\r\nEND\r\n']) - result = client.gets_many([b'key1', b'key2']) - assert result == {b'key1': (b'value1', b'11')} + client = self.make_client([b"VALUE key1 0 6 11\r\nvalue1\r\nEND\r\n"]) + result = client.gets_many([b"key1", b"key2"]) + assert result == {b"key1": (b"value1", b"11")} def test_touch_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.touch(b'key', noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.touch(b"key", noreply=False) assert result is False def test_touch_found(self): - client = self.make_client([b'TOUCHED\r\n']) - result = client.touch(b'key', noreply=False) + client = self.make_client([b"TOUCHED\r\n"]) + result = client.touch(b"key", noreply=False) assert result is True def test_quit(self): @@ -725,138 +741,132 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None def test_shutdown(self): - client = self.make_client([MemcacheUnexpectedCloseError('shutdown')]) + client = self.make_client([MemcacheUnexpectedCloseError("shutdown")]) result = client.shutdown() assert result is None def test_shutdown_disabled(self): def _shutdown(): - client = self.make_client([b'ERROR: shutdown not enabled\r\n']) + client = self.make_client([b"ERROR: shutdown not enabled\r\n"]) client.shutdown() with pytest.raises(MemcacheUnknownCommandError): _shutdown() def test_replace_stored(self): - client = self.make_client([b'STORED\r\n']) - result = client.replace(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.replace(b"key", b"value", noreply=False) assert result is True # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.replace(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.replace(b"key", b"value", noreply=False) assert result is True def test_replace_not_stored(self): - client = self.make_client([b'NOT_STORED\r\n']) - result = client.replace(b'key', b'value', noreply=False) + client = self.make_client([b"NOT_STORED\r\n"]) + result = client.replace(b"key", b"value", noreply=False) assert result is False # unit test for encoding passed in __init__ - client = self.make_client([b'NOT_STORED\r\n'], encoding='utf-8') - result = client.replace(b'key', b'value', noreply=False) + client = self.make_client([b"NOT_STORED\r\n"], encoding="utf-8") + result = client.replace(b"key", b"value", noreply=False) assert result is False def test_serialization(self): class JsonSerde: def serialize(self, key, value): - return json.dumps(value).encode('ascii'), 0 + return json.dumps(value).encode("ascii"), 0 def deserialize(self, key, value, flags): - return json.loads(value.decode('ascii')) + return json.loads(value.decode("ascii")) - client = self.make_client([b'STORED\r\n'], serde=JsonSerde()) - client.set('key', {'c': 'd'}) - assert client.sock.send_bufs == [ - b'set key 0 0 10 noreply\r\n{"c": "d"}\r\n' - ] + client = self.make_client([b"STORED\r\n"], serde=JsonSerde()) + client.set("key", {"c": "d"}) + assert client.sock.send_bufs == [b'set key 0 0 10 noreply\r\n{"c": "d"}\r\n'] def test_serialization_flags(self): def _ser(key, value): return value, 1 if isinstance(value, int) else 0 - client = self.make_client( - [b'STORED\r\n', b'STORED\r\n'], serializer=_ser) + client = self.make_client([b"STORED\r\n", b"STORED\r\n"], serializer=_ser) client.set_many( - collections.OrderedDict([(b'a', b's'), (b'b', 0)]), noreply=False) - assert client.sock.send_bufs == [ - b'set a 0 0 1\r\ns\r\nset b 1 0 1\r\n0\r\n' - ] + collections.OrderedDict([(b"a", b"s"), (b"b", 0)]), noreply=False + ) + assert client.sock.send_bufs == [b"set a 0 0 1\r\ns\r\nset b 1 0 1\r\n0\r\n"] def test_serialization_overridden_flags(self): def _ser(key, value): return value, 1 if isinstance(value, int) else 0 - client = self.make_client( - [b'STORED\r\n', b'STORED\r\n'], serializer=_ser) + client = self.make_client([b"STORED\r\n", b"STORED\r\n"], serializer=_ser) client.set_many( - collections.OrderedDict([(b'a', b's'), (b'b', 0)]), - noreply=False, flags=5) - assert client.sock.send_bufs == [ - b'set a 5 0 1\r\ns\r\nset b 5 0 1\r\n0\r\n' - ] + collections.OrderedDict([(b"a", b"s"), (b"b", 0)]), noreply=False, flags=5 + ) + assert client.sock.send_bufs == [b"set a 5 0 1\r\ns\r\nset b 5 0 1\r\n0\r\n"] def test_explicit_flags(self): - client = self.make_client([b'STORED\r\n', b'STORED\r\n']) + client = self.make_client([b"STORED\r\n", b"STORED\r\n"]) client.set_many( - collections.OrderedDict([(b'a', b's'), (b'b', 0)]), - noreply=False, flags=5) - assert client.sock.send_bufs == [ - b'set a 5 0 1\r\ns\r\nset b 5 0 1\r\n0\r\n' - ] + collections.OrderedDict([(b"a", b"s"), (b"b", 0)]), noreply=False, flags=5 + ) + assert client.sock.send_bufs == [b"set a 5 0 1\r\ns\r\nset b 5 0 1\r\n0\r\n"] def test_set_socket_handling(self): - client = self.make_client([b'STORED\r\n']) - result = client.set(b'key', b'value', noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.set(b"key", b"value", noreply=False) assert result is True assert client.sock.closed is False assert len(client.sock.send_bufs) == 1 def test_set_error(self): - client = self.make_client([b'ERROR\r\n']) + client = self.make_client([b"ERROR\r\n"]) def _set(): - client.set(b'key', b'value', noreply=False) + client.set(b"key", b"value", noreply=False) with pytest.raises(MemcacheUnknownCommandError): _set() def test_set_exception(self): - client = self.make_client([Exception('fail')]) + client = self.make_client([Exception("fail")]) def _set(): - client.set(b'key', b'value', noreply=False) + client.set(b"key", b"value", noreply=False) + with pytest.raises(Exception): _set() assert client.sock is None def test_set_client_error(self): - client = self.make_client([b'CLIENT_ERROR some message\r\n']) + client = self.make_client([b"CLIENT_ERROR some message\r\n"]) def _set(): - client.set('key', 'value', noreply=False) + client.set("key", "value", noreply=False) with pytest.raises(MemcacheClientError): _set() def test_set_server_error(self): - client = self.make_client([b'SERVER_ERROR some message\r\n']) + client = self.make_client([b"SERVER_ERROR some message\r\n"]) def _set(): - client.set(b'key', b'value', noreply=False) + client.set(b"key", b"value", noreply=False) with pytest.raises(MemcacheServerError): _set() def test_closing_socket_on_unexpected_closed_error(self): - client = self.make_client([ - b'VALUE ', - MemcacheUnexpectedCloseError("foo bar"), - ]) + client = self.make_client( + [ + b"VALUE ", + MemcacheUnexpectedCloseError("foo bar"), + ] + ) def _set(): - client.set(b'key', b'value', noreply=False) + client.set(b"key", b"value", noreply=False) with pytest.raises(MemcacheUnexpectedCloseError): _set() @@ -864,87 +874,87 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None def test_set_unknown_error(self): - client = self.make_client([b'foobarbaz\r\n']) + client = self.make_client([b"foobarbaz\r\n"]) def _set(): - client.set(b'key', b'value', noreply=False) + client.set(b"key", b"value", noreply=False) with pytest.raises(MemcacheUnknownError): _set() def test_set_key_with_space(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set(b'key has space', b'value', noreply=False) + client.set(b"key has space", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_key_with_newline(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set(b'key\n', b'value', noreply=False) + client.set(b"key\n", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_key_with_carriage_return(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set(b'key\r', b'value', noreply=False) + client.set(b"key\r", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_key_with_null_character(self): - client = self.make_client([b'']) + client = self.make_client([b""]) def _set(): - client.set(b'key\00', b'value', noreply=False) + client.set(b"key\00", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_key_with_noninteger_expire(self): - client = self.make_client([b'']) + client = self.make_client([b""]) class _OneLike: """object that looks similar to the int 1""" + def __str__(self): return "1" for noreply in (True, False): for expire in (1.5, _OneLike(), "1"): + def _set(): - client.set(b'finekey', b'finevalue', - noreply=noreply, expire=expire) + client.set(b"finekey", b"finevalue", noreply=noreply, expire=expire) with pytest.raises(MemcacheIllegalInputError): _set() def test_set_many_socket_handling(self): - client = self.make_client([b'STORED\r\n']) - result = client.set_many({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"]) + result = client.set_many({b"key": b"value"}, noreply=False) assert result == [] assert client.sock.closed is False assert len(client.sock.send_bufs) == 1 # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n'], encoding='utf-8') - result = client.set_many({b'key': b'value'}, noreply=False) + client = self.make_client([b"STORED\r\n"], encoding="utf-8") + result = client.set_many({b"key": b"value"}, noreply=False) assert result == [] assert client.sock.closed is False assert len(client.sock.send_bufs) == 1 def test_set_many_exception(self): - client = self.make_client([b'STORED\r\n', Exception('fail')]) + client = self.make_client([b"STORED\r\n", Exception("fail")]) def _set(): - client.set_many({b'key': b'value', b'other': b'value'}, - noreply=False) + client.set_many({b"key": b"value", b"other": b"value"}, noreply=False) with pytest.raises(Exception): _set() @@ -952,12 +962,10 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None # unit test for encoding passed in __init__() - client = self.make_client([b'STORED\r\n', Exception('fail')], - encoding='utf-8') + client = self.make_client([b"STORED\r\n", Exception("fail")], encoding="utf-8") def _set(): - client.set_many({b'key': b'value', b'other': b'value'}, - noreply=False) + client.set_many({b"key": b"value", b"other": b"value"}, noreply=False) with pytest.raises(Exception): _set() @@ -965,122 +973,112 @@ class TestClient(ClientTestMixin, unittest.TestCase): assert client.sock is None def test_stats(self): - client = self.make_client([b'STAT fake_stats 1\r\n', b'END\r\n']) + client = self.make_client([b"STAT fake_stats 1\r\n", b"END\r\n"]) result = client.stats() - assert client.sock.send_bufs == [ - b'stats\r\n' - ] - assert result == {b'fake_stats': 1} + assert client.sock.send_bufs == [b"stats\r\n"] + assert result == {b"fake_stats": 1} def test_stats_with_args(self): - client = self.make_client([b'STAT fake_stats 1\r\n', b'END\r\n']) - result = client.stats('some_arg') - assert client.sock.send_bufs == [ - b'stats some_arg\r\n' - ] - assert result == {b'fake_stats': 1} + client = self.make_client([b"STAT fake_stats 1\r\n", b"END\r\n"]) + result = client.stats("some_arg") + assert client.sock.send_bufs == [b"stats some_arg\r\n"] + assert result == {b"fake_stats": 1} def test_stats_conversions(self): - client = self.make_client([ - # Most stats are converted to int - b'STAT cmd_get 2519\r\n', - b'STAT cmd_set 3099\r\n', - b'STAT evictions 939\r\n', - - # Unless they can't be, they remain str - b'STAT libevent 2.0.19-stable\r\n', - - # Some named stats are explicitly converted - 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'STAT umask 777\r\n', - b'STAT auth_enabled_sasl yes\r\n', - b'END\r\n', - ]) + client = self.make_client( + [ + # Most stats are converted to int + b"STAT cmd_get 2519\r\n", + b"STAT cmd_set 3099\r\n", + b"STAT evictions 939\r\n", + # Unless they can't be, they remain str + b"STAT libevent 2.0.19-stable\r\n", + # Some named stats are explicitly converted + 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"STAT umask 777\r\n", + b"STAT auth_enabled_sasl yes\r\n", + b"END\r\n", + ] + ) result = client.stats() - assert client.sock.send_bufs == [ - b'stats\r\n' - ] + assert client.sock.send_bufs == [b"stats\r\n"] expected = { - b'cmd_get': 2519, - b'cmd_set': 3099, - b'evictions': 939, - 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', - b'umask': 0o777, - b'auth_enabled_sasl': True, + b"cmd_get": 2519, + b"cmd_set": 3099, + b"evictions": 939, + 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", + b"umask": 0o777, + b"auth_enabled_sasl": True, } assert result == expected def test_stats_cachedump(self): - client = self.make_client([b'ITEM bob [7 b; 0 s]\r\n', b'END\r\n']) - result = client.stats('cachedump', '1', '1') - assert client.sock.send_bufs == [ - b'stats cachedump 1 1\r\n' - ] - assert result == {b'bob': b'[7 b; 0 s]'} + client = self.make_client([b"ITEM bob [7 b; 0 s]\r\n", b"END\r\n"]) + result = client.stats("cachedump", "1", "1") + assert client.sock.send_bufs == [b"stats cachedump 1 1\r\n"] + assert result == {b"bob": b"[7 b; 0 s]"} def test_cache_memlimit(self): - client = self.make_client([b'OK\r\n']) + client = self.make_client([b"OK\r\n"]) result = client.cache_memlimit(8) - assert client.sock.send_bufs == [ - b'cache_memlimit 8\r\n' - ] + assert client.sock.send_bufs == [b"cache_memlimit 8\r\n"] assert result is True def test_python_dict_set_is_supported(self): - client = self.make_client([b'STORED\r\n']) - client[b'key'] = b'value' + client = self.make_client([b"STORED\r\n"]) + client[b"key"] = b"value" def test_python_dict_get_is_supported(self): - client = self.make_client([b'VALUE key 0 5\r\nvalue\r\nEND\r\n']) - assert client[b'key'] == b'value' + client = self.make_client([b"VALUE key 0 5\r\nvalue\r\nEND\r\n"]) + assert client[b"key"] == b"value" def test_python_dict_get_not_found_is_supported(self): - client = self.make_client([b'END\r\n']) + client = self.make_client([b"END\r\n"]) def _get(): - client[b'key'] + client[b"key"] with pytest.raises(KeyError): _get() def test_python_dict_del_is_supported(self): - client = self.make_client([b'DELETED\r\n']) - del client[b'key'] + client = self.make_client([b"DELETED\r\n"]) + del client[b"key"] def test_too_long_key(self): - client = self.make_client([b'END\r\n']) + client = self.make_client([b"END\r\n"]) with pytest.raises(MemcacheClientError): - client.get(b'x' * 251) + client.get(b"x" * 251) def test_too_long_unicode_key(self): - client = self.make_client([b'STORED\r\n'], allow_unicode_keys=True) + client = self.make_client([b"STORED\r\n"], allow_unicode_keys=True) with pytest.raises(MemcacheClientError): - client.get('my☃'*150) + client.get("my☃" * 150) with pytest.raises(MemcacheClientError): - client.get('\u0FFF'*150) + client.get("\u0FFF" * 150) def test_key_contains_space(self): - client = self.make_client([b'END\r\n']) + client = self.make_client([b"END\r\n"]) with pytest.raises(MemcacheClientError): - client.get(b'abc xyz') + client.get(b"abc xyz") def test_key_contains_nonascii(self): - client = self.make_client([b'END\r\n']) + client = self.make_client([b"END\r\n"]) with pytest.raises(MemcacheClientError): - client.get('\u3053\u3093\u306b\u3061\u306f') + client.get("\u3053\u3093\u306b\u3061\u306f") def _default_noreply_false(self, cmd, args, response): client = self.make_client(response, default_noreply=False) @@ -1099,62 +1097,50 @@ class TestClient(ClientTestMixin, unittest.TestCase): def test_default_noreply_set(self): with pytest.raises(MemcacheUnknownError): - self._default_noreply_false( - 'set', (b'key', b'value'), [b'UNKNOWN\r\n']) - self._default_noreply_false( - 'set', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'set', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("set", (b"key", b"value"), [b"UNKNOWN\r\n"]) + self._default_noreply_false("set", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("set", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_set_many(self): with pytest.raises(MemcacheUnknownError): - client = self.make_client([b'UNKNOWN\r\n'], default_noreply=False) - result = client.set_many({b'key': b'value'}) - assert result == [b'key'] + client = self.make_client([b"UNKNOWN\r\n"], default_noreply=False) + result = client.set_many({b"key": b"value"}) + assert result == [b"key"] self._default_noreply_true_and_empty_list( - 'set_many', ({b'key': b'value'},), [b'NOT_STORED\r\n']) + "set_many", ({b"key": b"value"},), [b"NOT_STORED\r\n"] + ) def test_default_noreply_add(self): - self._default_noreply_false( - 'add', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'add', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("add", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("add", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_replace(self): - self._default_noreply_false( - 'replace', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'replace', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("replace", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("replace", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_append(self): - self._default_noreply_false( - 'append', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'append', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("append", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("append", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_prepend(self): - self._default_noreply_false( - 'prepend', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'prepend', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("prepend", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("prepend", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_touch(self): - self._default_noreply_false('touch', (b'key',), [b'NOT_FOUND\r\n']) - self._default_noreply_true('touch', (b'key',), [b'NOT_FOUND\r\n']) + self._default_noreply_false("touch", (b"key",), [b"NOT_FOUND\r\n"]) + self._default_noreply_true("touch", (b"key",), [b"NOT_FOUND\r\n"]) def test_default_noreply_flush_all(self): - self._default_noreply_false('flush_all', (), - [b'__FAKE_RESPONSE__\r\n']) - self._default_noreply_true('flush_all', (), [b'__FAKE_RESPONSE__\r\n']) + self._default_noreply_false("flush_all", (), [b"__FAKE_RESPONSE__\r\n"]) + self._default_noreply_true("flush_all", (), [b"__FAKE_RESPONSE__\r\n"]) def test_version_success(self): - client = self.make_client([b'VERSION 1.2.3\r\n'], - default_noreply=False) + client = self.make_client([b"VERSION 1.2.3\r\n"], default_noreply=False) result = client.version() - assert result == b'1.2.3' + assert result == b"1.2.3" def test_version_exception(self): - client = self.make_client([b'INVALID DATA\r\n'], default_noreply=False) + client = self.make_client([b"INVALID DATA\r\n"], default_noreply=False) with pytest.raises(MemcacheUnknownError): client.version() @@ -1162,7 +1148,7 @@ class TestClient(ClientTestMixin, unittest.TestCase): @pytest.mark.unit() class TestClientSocketConnect(unittest.TestCase): def test_socket_connect_ipv4(self): - server = ('127.0.0.1', 11211) + server = ("127.0.0.1", 11211) client = Client(server, socket_module=MockSocketModule()) client._connect() @@ -1172,8 +1158,11 @@ class TestClientSocketConnect(unittest.TestCase): timeout = 2 connect_timeout = 3 client = Client( - server, connect_timeout=connect_timeout, timeout=timeout, - socket_module=MockSocketModule()) + server, + connect_timeout=connect_timeout, + timeout=timeout, + socket_module=MockSocketModule(), + ) client._connect() assert client.sock.timeouts == [connect_timeout, timeout] @@ -1181,14 +1170,14 @@ class TestClientSocketConnect(unittest.TestCase): client._connect() assert client.sock.socket_options == [] - client = Client( - server, socket_module=MockSocketModule(), no_delay=True) + client = Client(server, socket_module=MockSocketModule(), no_delay=True) client._connect() - assert client.sock.socket_options == [(socket.IPPROTO_TCP, - socket.TCP_NODELAY, 1)] + assert client.sock.socket_options == [ + (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + ] def test_socket_connect_ipv6(self): - server = ('::1', 11211) + server = ("::1", 11211) client = Client(server, socket_module=MockSocketModule()) client._connect() @@ -1198,8 +1187,11 @@ class TestClientSocketConnect(unittest.TestCase): timeout = 2 connect_timeout = 3 client = Client( - server, connect_timeout=connect_timeout, timeout=timeout, - socket_module=MockSocketModule()) + server, + connect_timeout=connect_timeout, + timeout=timeout, + socket_module=MockSocketModule(), + ) client._connect() assert client.sock.timeouts == [connect_timeout, timeout] @@ -1207,60 +1199,61 @@ class TestClientSocketConnect(unittest.TestCase): client._connect() assert client.sock.socket_options == [] - client = Client( - server, socket_module=MockSocketModule(), no_delay=True) + client = Client(server, socket_module=MockSocketModule(), no_delay=True) client._connect() - assert client.sock.socket_options == [(socket.IPPROTO_TCP, - socket.TCP_NODELAY, 1)] + assert client.sock.socket_options == [ + (socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + ] def test_socket_connect_unix(self): - server = f'/tmp/pymemcache.{os.getpid()}' + server = f"/tmp/pymemcache.{os.getpid()}" with MockUnixSocketServer(server): client = Client(server) client._connect() assert client.sock.family == socket.AF_UNIX - @unittest.skipIf('Linux' != platform.system(), - 'Socket keepalive only support Linux platforms.') + @unittest.skipIf( + "Linux" != platform.system(), "Socket keepalive only support Linux platforms." + ) def test_linux_socket_keepalive(self): - server = ('::1', 11211) + server = ("::1", 11211) try: client = Client( server, socket_module=MockSocketModule(), - socket_keepalive=KeepaliveOpts()) + socket_keepalive=KeepaliveOpts(), + ) client._connect() except SystemError: self.fail("SystemError unexpectedly raised") with self.assertRaises(ValueError): # A KeepaliveOpts object is expected, a ValueError will be raised - Client( - server, - socket_module=MockSocketModule(), - socket_keepalive=True) + Client(server, socket_module=MockSocketModule(), socket_keepalive=True) - @mock.patch('platform.system') + @mock.patch("platform.system") def test_osx_socket_keepalive(self, platform_mock): - platform_mock.return_value = 'Darwin' - server = ('::1', 11211) + platform_mock.return_value = "Darwin" + server = ("::1", 11211) # For the moment the socket keepalive is only implemented for Linux with self.assertRaises(SystemError): Client( server, socket_module=MockSocketModule(), - socket_keepalive=KeepaliveOpts()) + socket_keepalive=KeepaliveOpts(), + ) - @mock.patch('platform.system') + @mock.patch("platform.system") def test_windows_socket_keepalive(self, platform_mock): - platform_mock.return_value = 'Windows' - server = ('::1', 11211) + platform_mock.return_value = "Windows" + server = ("::1", 11211) # For the moment the socket keepalive is only implemented for Linux with self.assertRaises(SystemError): Client( server, socket_module=MockSocketModule(), - socket_keepalive=KeepaliveOpts()) + socket_keepalive=KeepaliveOpts(), + ) def test_socket_connect_closes_on_failure(self): server = ("example.com", 11211) @@ -1320,57 +1313,47 @@ class TestPooledClient(ClientTestMixin, unittest.TestCase): def test_default_noreply_set(self): with pytest.raises(MemcacheUnknownError): - self._default_noreply_false( - 'set', (b'key', b'value'), [b'UNKNOWN\r\n']) - self._default_noreply_false( - 'set', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'set', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("set", (b"key", b"value"), [b"UNKNOWN\r\n"]) + self._default_noreply_false("set", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("set", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_set_many(self): with pytest.raises(MemcacheUnknownError): - client = self.make_client([b'UNKNOWN\r\n'], default_noreply=False) - client.set_many({b'key': b'value'}) + client = self.make_client([b"UNKNOWN\r\n"], default_noreply=False) + client.set_many({b"key": b"value"}) self._default_noreply_true_and_empty_list( - 'set_many', ({b'key': b'value'},), [b'NOT_STORED\r\n']) + "set_many", ({b"key": b"value"},), [b"NOT_STORED\r\n"] + ) def test_default_noreply_add(self): - self._default_noreply_false( - 'add', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'add', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("add", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("add", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_replace(self): - self._default_noreply_false( - 'replace', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'replace', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("replace", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("replace", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_append(self): - self._default_noreply_false( - 'append', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'append', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("append", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("append", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_prepend(self): - self._default_noreply_false( - 'prepend', (b'key', b'value'), [b'NOT_STORED\r\n']) - self._default_noreply_true( - 'prepend', (b'key', b'value'), [b'NOT_STORED\r\n']) + self._default_noreply_false("prepend", (b"key", b"value"), [b"NOT_STORED\r\n"]) + self._default_noreply_true("prepend", (b"key", b"value"), [b"NOT_STORED\r\n"]) def test_default_noreply_touch(self): - self._default_noreply_false('touch', (b'key',), [b'NOT_FOUND\r\n']) - self._default_noreply_true('touch', (b'key',), [b'NOT_FOUND\r\n']) + self._default_noreply_false("touch", (b"key",), [b"NOT_FOUND\r\n"]) + self._default_noreply_true("touch", (b"key",), [b"NOT_FOUND\r\n"]) def test_default_noreply_flush_all(self): - self._default_noreply_false('flush_all', (), - [b'__FAKE_RESPONSE__\r\n']) - self._default_noreply_true('flush_all', (), [b'__FAKE_RESPONSE__\r\n']) + self._default_noreply_false("flush_all", (), [b"__FAKE_RESPONSE__\r\n"]) + self._default_noreply_true("flush_all", (), [b"__FAKE_RESPONSE__\r\n"]) def test_custom_client(self): class MyClient(Client): pass - client = PooledClient(('host', 11211)) + + client = PooledClient(("host", 11211)) client.client_class = MyClient assert isinstance(client.client_pool.get(), MyClient) @@ -1392,18 +1375,18 @@ class TestPooledClientIdleTimeout(ClientTestMixin, unittest.TestCase): removed = Counter() - client = self.make_client([b'VALUE key 0 5\r\nvalue\r\nEND\r\n']*2) + client = self.make_client([b"VALUE key 0 5\r\nvalue\r\nEND\r\n"] * 2) client.client_pool._after_remove = removed.increment client.client_pool._idle_clock = lambda: 0 - client.set(b'key', b'value') + client.set(b"key", b"value") assert removed.count == 0 - client.get(b'key') + client.get(b"key") assert removed.count == 0 # Advance clock to beyond the idle timeout. client.client_pool._idle_clock = lambda: 61 - client.get(b'key') + client.get(b"key") assert removed.count == 1 @@ -1414,88 +1397,99 @@ class TestMockClient(ClientTestMixin, unittest.TestCase): return client def test_get_found(self): - client = self.make_client([ - b'STORED\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n', - ]) - result = client.set(b'key', b'value', noreply=False) - result = client.get(b'key') - assert result == b'value' + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE key 0 5\r\nvalue\r\nEND\r\n", + ] + ) + result = client.set(b"key", b"value", noreply=False) + result = client.get(b"key") + assert result == b"value" def test_deserialization(self): class JsonSerde: def serialize(self, key, value): if isinstance(value, dict): - return json.dumps(value).encode('UTF-8'), 1 + return json.dumps(value).encode("UTF-8"), 1 return value, 0 def deserialize(self, key, value, flags): if flags == 1: - return json.loads(value.decode('UTF-8')) + return json.loads(value.decode("UTF-8")) return value - client = self.make_client([ - b'STORED\r\n', - b'VALUE key1 0 5\r\nhello\r\nEND\r\n', - b'STORED\r\n', - b'VALUE key2 0 18\r\n{"hello": "world"}\r\nEND\r\n', - ], serde=JsonSerde()) + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE key1 0 5\r\nhello\r\nEND\r\n", + b"STORED\r\n", + b'VALUE key2 0 18\r\n{"hello": "world"}\r\nEND\r\n', + ], + serde=JsonSerde(), + ) - result = client.set(b'key1', b'hello', noreply=False) - result = client.get(b'key1') - assert result == b'hello' + result = client.set(b"key1", b"hello", noreply=False) + result = client.get(b"key1") + assert result == b"hello" - result = client.set(b'key2', dict(hello='world'), noreply=False) - result = client.get(b'key2') - assert result == dict(hello='world') + result = client.set(b"key2", dict(hello="world"), noreply=False) + result = client.get(b"key2") + assert result == dict(hello="world") class TestPrefixedClient(ClientTestMixin, unittest.TestCase): def make_client(self, mock_socket_values, **kwargs): - client = Client(None, key_prefix=b'xyz:', **kwargs) + client = Client(None, key_prefix=b"xyz:", **kwargs) client.sock = MockSocket(list(mock_socket_values)) return client def test_get_found(self): - client = self.make_client([ - b'STORED\r\n', - b'VALUE xyz:key 0 5\r\nvalue\r\nEND\r\n', - ]) - result = client.set(b'key', b'value', noreply=False) - result = client.get(b'key') - assert result == b'value' + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE xyz:key 0 5\r\nvalue\r\nEND\r\n", + ] + ) + result = client.set(b"key", b"value", noreply=False) + result = client.get(b"key") + assert result == b"value" def test_get_many_some_found(self): - client = self.make_client([ - b'STORED\r\n', - b'VALUE xyz:key1 0 6\r\nvalue1\r\nEND\r\n', - ]) - result = client.set(b'key1', b'value1', noreply=False) - result = client.get_many([b'key1', b'key2']) - assert result == {b'key1': b'value1'} + client = self.make_client( + [ + b"STORED\r\n", + b"VALUE xyz:key1 0 6\r\nvalue1\r\nEND\r\n", + ] + ) + result = client.set(b"key1", b"value1", noreply=False) + result = client.get_many([b"key1", b"key2"]) + assert result == {b"key1": b"value1"} def test_get_many_all_found(self): - client = self.make_client([ - b'STORED\r\n', - b'STORED\r\n', - b'VALUE xyz:key1 0 6\r\nvalue1\r\n', - b'VALUE xyz:key2 0 6\r\nvalue2\r\nEND\r\n', - ]) - result = client.set(b'key1', b'value1', noreply=False) - result = client.set(b'key2', b'value2', noreply=False) - result = client.get_many([b'key1', b'key2']) - assert result == {b'key1': b'value1', b'key2': b'value2'} + client = self.make_client( + [ + b"STORED\r\n", + b"STORED\r\n", + b"VALUE xyz:key1 0 6\r\nvalue1\r\n", + b"VALUE xyz:key2 0 6\r\nvalue2\r\nEND\r\n", + ] + ) + result = client.set(b"key1", b"value1", noreply=False) + result = client.set(b"key2", b"value2", noreply=False) + result = client.get_many([b"key1", b"key2"]) + assert result == {b"key1": b"value1", b"key2": b"value2"} def test_python_dict_get_is_supported(self): - client = self.make_client([b'VALUE xyz:key 0 5\r\nvalue\r\nEND\r\n']) - assert client[b'key'] == b'value' + client = self.make_client([b"VALUE xyz:key 0 5\r\nvalue\r\nEND\r\n"]) + assert client[b"key"] == b"value" class TestPrefixedPooledClient(TestPrefixedClient): def make_client(self, mock_socket_values, **kwargs): - mock_client = Client(None, key_prefix=b'xyz:', **kwargs) + mock_client = Client(None, key_prefix=b"xyz:", **kwargs) mock_client.sock = MockSocket(list(mock_socket_values)) - client = PooledClient(None, key_prefix=b'xyz:', **kwargs) + client = PooledClient(None, key_prefix=b"xyz:", **kwargs) client.client_pool = pool.ObjectPool(lambda: mock_client) return client @@ -1508,14 +1502,16 @@ class TestRetryOnEINTR(unittest.TestCase): return client def test_recv(self): - client = self.make_client([ - b'VALUE ', - socket.error(errno.EINTR, "Interrupted system call"), - b'key1 0 6\r\nval', - socket.error(errno.EINTR, "Interrupted system call"), - b'ue1\r\nEND\r\n', - ]) - assert client[b'key1'] == b'value1' + client = self.make_client( + [ + b"VALUE ", + socket.error(errno.EINTR, "Interrupted system call"), + b"key1 0 6\r\nval", + socket.error(errno.EINTR, "Interrupted system call"), + b"ue1\r\nEND\r\n", + ] + ) + assert client[b"key1"] == b"value1" @pytest.mark.unit() @@ -1523,19 +1519,19 @@ class TestNormalizeServerSpec(unittest.TestCase): def test_normalize_server_spec(self): f = normalize_server_spec assert f(None) is None - assert f(('127.0.0.1', 12345)) == ('127.0.0.1', 12345) - assert f(['127.0.0.1', 12345]) == ('127.0.0.1', 12345) - assert f('unix:/run/memcached/socket') == '/run/memcached/socket' - assert f('/run/memcached/socket') == '/run/memcached/socket' - assert f('localhost') == ('localhost', 11211) - assert f('localhost:12345') == ('localhost', 12345) - assert f('[::1]') == ('::1', 11211) - assert f('[::1]:12345') == ('::1', 12345) - assert f('127.0.0.1') == ('127.0.0.1', 11211) - assert f('127.0.0.1:12345') == ('127.0.0.1', 12345) + assert f(("127.0.0.1", 12345)) == ("127.0.0.1", 12345) + assert f(["127.0.0.1", 12345]) == ("127.0.0.1", 12345) + assert f("unix:/run/memcached/socket") == "/run/memcached/socket" + assert f("/run/memcached/socket") == "/run/memcached/socket" + assert f("localhost") == ("localhost", 11211) + assert f("localhost:12345") == ("localhost", 12345) + assert f("[::1]") == ("::1", 11211) + assert f("[::1]:12345") == ("::1", 12345) + assert f("127.0.0.1") == ("127.0.0.1", 11211) + assert f("127.0.0.1:12345") == ("127.0.0.1", 12345) with pytest.raises(ValueError) as excinfo: - f({'host': 12345}) + f({"host": 12345}) assert str(excinfo.value) == "Unknown server provided: {'host': 12345}" with pytest.raises(ValueError) as excinfo: @@ -1547,13 +1543,13 @@ class TestNormalizeServerSpec(unittest.TestCase): class TestKeepaliveopts(unittest.TestCase): def test_keepalive_opts(self): kao = KeepaliveOpts() - assert (kao.idle == 1 and kao.intvl == 1 and kao.cnt == 5) + assert kao.idle == 1 and kao.intvl == 1 and kao.cnt == 5 kao = KeepaliveOpts(idle=1, intvl=4, cnt=2) - assert (kao.idle == 1 and kao.intvl == 4 and kao.cnt == 2) + assert kao.idle == 1 and kao.intvl == 4 and kao.cnt == 2 kao = KeepaliveOpts(idle=8) - assert (kao.idle == 8 and kao.intvl == 1 and kao.cnt == 5) + assert kao.idle == 8 and kao.intvl == 1 and kao.cnt == 5 kao = KeepaliveOpts(cnt=8) - assert (kao.idle == 1 and kao.intvl == 1 and kao.cnt == 8) + assert kao.idle == 1 and kao.intvl == 1 and kao.cnt == 8 with self.assertRaises(ValueError): KeepaliveOpts(cnt=0) diff --git a/pymemcache/test/test_client_hash.py b/pymemcache/test/test_client_hash.py index f747845..e5f9d45 100644 --- a/pymemcache/test/test_client_hash.py +++ b/pymemcache/test/test_client_hash.py @@ -12,9 +12,7 @@ import socket class TestHashClient(ClientTestMixin, unittest.TestCase): - - def make_client_pool(self, hostname, mock_socket_values, - serializer=None, **kwargs): + def make_client_pool(self, hostname, mock_socket_values, serializer=None, **kwargs): mock_client = Client(hostname, serializer=serializer, **kwargs) mock_client.sock = MockSocket(mock_socket_values) client = PooledClient(hostname, serializer=serializer) @@ -24,15 +22,11 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): def make_client(self, *mock_socket_values, **kwargs): current_port = 11012 client = HashClient([], **kwargs) - ip = '127.0.0.1' + ip = "127.0.0.1" for vals in mock_socket_values: - s = f'{ip}:{current_port}' - c = self.make_client_pool( - (ip, current_port), - vals, - **kwargs - ) + s = f"{ip}:{current_port}" + c = self.make_client_pool((ip, current_port), vals, **kwargs) client.clients[s] = c client.hasher.add_node(s) current_port += 1 @@ -43,159 +37,203 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): client = HashClient([], **kwargs) for socket_, vals in zip(sockets, mock_socket_values): - c = self.make_client_pool( - socket_, - vals, - **kwargs - ) + c = self.make_client_pool(socket_, vals, **kwargs) client.clients[socket_] = c client.hasher.add_node(socket_) return client def test_setup_client_without_pooling(self): - client_class = 'pymemcache.client.hash.HashClient.client_class' + client_class = "pymemcache.client.hash.HashClient.client_class" with mock.patch(client_class) as internal_client: - client = HashClient([], timeout=999, key_prefix='foo_bar_baz') - client.add_server(('127.0.0.1', '11211')) + client = HashClient([], timeout=999, key_prefix="foo_bar_baz") + client.add_server(("127.0.0.1", "11211")) - assert internal_client.call_args[0][0] == ('127.0.0.1', '11211') + assert internal_client.call_args[0][0] == ("127.0.0.1", "11211") kwargs = internal_client.call_args[1] - assert kwargs['timeout'] == 999 - assert kwargs['key_prefix'] == 'foo_bar_baz' + assert kwargs["timeout"] == 999 + assert kwargs["key_prefix"] == "foo_bar_baz" def test_get_many_unix(self): pid = os.getpid() sockets = [ - '/tmp/pymemcache.1.%d' % pid, - '/tmp/pymemcache.2.%d' % pid, + "/tmp/pymemcache.1.%d" % pid, + "/tmp/pymemcache.2.%d" % pid, ] - client = self.make_unix_client(sockets, *[ - [b'STORED\r\n', b'VALUE key3 0 6\r\nvalue2\r\nEND\r\n', ], - [b'STORED\r\n', b'VALUE key1 0 6\r\nvalue1\r\nEND\r\n', ], - ]) + client = self.make_unix_client( + sockets, + *[ + [ + b"STORED\r\n", + b"VALUE key3 0 6\r\nvalue2\r\nEND\r\n", + ], + [ + b"STORED\r\n", + b"VALUE key1 0 6\r\nvalue1\r\nEND\r\n", + ], + ], + ) def get_clients(key): - if key == b'key3': - return client.clients['/tmp/pymemcache.1.%d' % pid] + if key == b"key3": + return client.clients["/tmp/pymemcache.1.%d" % pid] else: - return client.clients['/tmp/pymemcache.2.%d' % pid] + return client.clients["/tmp/pymemcache.2.%d" % pid] client._get_client = get_clients - result = client.set(b'key1', b'value1', noreply=False) - result = client.set(b'key3', b'value2', noreply=False) - result = client.get_many([b'key1', b'key3']) - assert result == {b'key1': b'value1', b'key3': b'value2'} + result = client.set(b"key1", b"value1", noreply=False) + result = client.set(b"key3", b"value2", noreply=False) + result = client.get_many([b"key1", b"key3"]) + assert result == {b"key1": b"value1", b"key3": b"value2"} def test_get_many_all_found(self): - client = self.make_client(*[ - [b'STORED\r\n', b'VALUE key3 0 6\r\nvalue2\r\nEND\r\n', ], - [b'STORED\r\n', b'VALUE key1 0 6\r\nvalue1\r\nEND\r\n', ], - ]) + client = self.make_client( + *[ + [ + b"STORED\r\n", + b"VALUE key3 0 6\r\nvalue2\r\nEND\r\n", + ], + [ + b"STORED\r\n", + b"VALUE key1 0 6\r\nvalue1\r\nEND\r\n", + ], + ] + ) def get_clients(key): - if key == b'key3': - return client.clients['127.0.0.1:11012'] + if key == b"key3": + return client.clients["127.0.0.1:11012"] else: - return client.clients['127.0.0.1:11013'] + return client.clients["127.0.0.1:11013"] client._get_client = get_clients - result = client.set(b'key1', b'value1', noreply=False) - result = client.set(b'key3', b'value2', noreply=False) - result = client.get_many([b'key1', b'key3']) - assert result == {b'key1': b'value1', b'key3': b'value2'} + result = client.set(b"key1", b"value1", noreply=False) + result = client.set(b"key3", b"value2", noreply=False) + result = client.get_many([b"key1", b"key3"]) + assert result == {b"key1": b"value1", b"key3": b"value2"} def test_get_many_some_found(self): - client = self.make_client(*[ - [b'END\r\n', ], - [b'STORED\r\n', b'VALUE key1 0 6\r\nvalue1\r\nEND\r\n', ], - ]) + client = self.make_client( + *[ + [ + b"END\r\n", + ], + [ + b"STORED\r\n", + b"VALUE key1 0 6\r\nvalue1\r\nEND\r\n", + ], + ] + ) def get_clients(key): - if key == b'key3': - return client.clients['127.0.0.1:11012'] + if key == b"key3": + return client.clients["127.0.0.1:11012"] else: - return client.clients['127.0.0.1:11013'] + return client.clients["127.0.0.1:11013"] client._get_client = get_clients - result = client.set(b'key1', b'value1', noreply=False) - result = client.get_many([b'key1', b'key3']) + result = client.set(b"key1", b"value1", noreply=False) + result = client.get_many([b"key1", b"key3"]) - assert result == {b'key1': b'value1'} + assert result == {b"key1": b"value1"} def test_get_many_bad_server_data(self): - client = self.make_client(*[ - [b'STORED\r\n', b'VAXLUE key3 0 6\r\nvalue2\r\nEND\r\n', ], - [b'STORED\r\n', b'VAXLUE key1 0 6\r\nvalue1\r\nEND\r\n', ], - ]) + client = self.make_client( + *[ + [ + b"STORED\r\n", + b"VAXLUE key3 0 6\r\nvalue2\r\nEND\r\n", + ], + [ + b"STORED\r\n", + b"VAXLUE key1 0 6\r\nvalue1\r\nEND\r\n", + ], + ] + ) def get_clients(key): - if key == b'key3': - return client.clients['127.0.0.1:11012'] + if key == b"key3": + return client.clients["127.0.0.1:11012"] else: - return client.clients['127.0.0.1:11013'] + return client.clients["127.0.0.1:11013"] client._get_client = get_clients with pytest.raises(MemcacheUnknownError): - client.set(b'key1', b'value1', noreply=False) - client.set(b'key3', b'value2', noreply=False) - client.get_many([b'key1', b'key3']) + client.set(b"key1", b"value1", noreply=False) + client.set(b"key3", b"value2", noreply=False) + client.get_many([b"key1", b"key3"]) def test_get_many_bad_server_data_ignore(self): - client = self.make_client(*[ - [b'STORED\r\n', b'VAXLUE key3 0 6\r\nvalue2\r\nEND\r\n', ], - [b'STORED\r\n', b'VAXLUE key1 0 6\r\nvalue1\r\nEND\r\n', ], - ], ignore_exc=True) + client = self.make_client( + *[ + [ + b"STORED\r\n", + b"VAXLUE key3 0 6\r\nvalue2\r\nEND\r\n", + ], + [ + b"STORED\r\n", + b"VAXLUE key1 0 6\r\nvalue1\r\nEND\r\n", + ], + ], + ignore_exc=True, + ) def get_clients(key): - if key == b'key3': - return client.clients['127.0.0.1:11012'] + if key == b"key3": + return client.clients["127.0.0.1:11012"] else: - return client.clients['127.0.0.1:11013'] + return client.clients["127.0.0.1:11013"] client._get_client = get_clients - client.set(b'key1', b'value1', noreply=False) - client.set(b'key3', b'value2', noreply=False) - result = client.get_many([b'key1', b'key3']) + client.set(b"key1", b"value1", noreply=False) + client.set(b"key3", b"value2", noreply=False) + result = client.get_many([b"key1", b"key3"]) assert result == {} def test_gets_many(self): - client = self.make_client(*[ - [b'STORED\r\n', b'VALUE key3 0 6 1\r\nvalue2\r\nEND\r\n', ], - [b'STORED\r\n', b'VALUE key1 0 6 1\r\nvalue1\r\nEND\r\n', ], - ]) + client = self.make_client( + *[ + [ + b"STORED\r\n", + b"VALUE key3 0 6 1\r\nvalue2\r\nEND\r\n", + ], + [ + b"STORED\r\n", + b"VALUE key1 0 6 1\r\nvalue1\r\nEND\r\n", + ], + ] + ) def get_clients(key): - if key == b'key3': - return client.clients['127.0.0.1:11012'] + if key == b"key3": + return client.clients["127.0.0.1:11012"] else: - return client.clients['127.0.0.1:11013'] + return client.clients["127.0.0.1:11013"] client._get_client = get_clients - assert client.set(b'key1', b'value1', noreply=False) is True - assert client.set(b'key3', b'value2', noreply=False) is True - result = client.gets_many([b'key1', b'key3']) - assert (result == - {b'key1': (b'value1', b'1'), b'key3': (b'value2', b'1')}) + assert client.set(b"key1", b"value1", noreply=False) is True + assert client.set(b"key3", b"value2", noreply=False) is True + result = client.gets_many([b"key1", b"key3"]) + assert result == {b"key1": (b"value1", b"1"), b"key3": (b"value2", b"1")} def test_touch_not_found(self): - client = self.make_client([b'NOT_FOUND\r\n']) - result = client.touch(b'key', noreply=False) + client = self.make_client([b"NOT_FOUND\r\n"]) + result = client.touch(b"key", noreply=False) assert result is False def test_touch_no_expiry_found(self): - client = self.make_client([b'TOUCHED\r\n']) - result = client.touch(b'key', noreply=False) + client = self.make_client([b"TOUCHED\r\n"]) + result = client.touch(b"key", noreply=False) assert result is True def test_touch_with_expiry_found(self): - client = self.make_client([b'TOUCHED\r\n']) - result = client.touch(b'key', 1, noreply=False) + client = self.make_client([b"TOUCHED\r\n"]) + result = client.touch(b"key", 1, noreply=False) assert result is True def test_close(self): @@ -214,141 +252,139 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): def test_no_servers_left(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=True, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=True, timeout=1, connect_timeout=1 ) - hashed_client = client._get_client('foo') + hashed_client = client._get_client("foo") assert hashed_client is None def test_no_servers_left_raise_exception(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=False, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=False, timeout=1, connect_timeout=1 ) with pytest.raises(MemcacheError) as e: - client._get_client('foo') + client._get_client("foo") - assert str(e.value) == 'All servers seem to be down right now' + assert str(e.value) == "All servers seem to be down right now" def test_unavailable_servers_zero_retry_raise_exception(self): from pymemcache.client.hash import HashClient + client = HashClient( - [('example.com', 11211)], use_pooling=True, + [("example.com", 11211)], + use_pooling=True, ignore_exc=False, - retry_attempts=0, timeout=1, connect_timeout=1 + retry_attempts=0, + timeout=1, + connect_timeout=1, ) with pytest.raises(socket.error): - client.get('foo') + client.get("foo") def test_no_servers_left_with_commands_return_default_value(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=True, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=True, timeout=1, connect_timeout=1 ) - result = client.get('foo') + result = client.get("foo") assert result is None - result = client.get('foo', default='default') - assert result == 'default' - result = client.set('foo', 'bar') + result = client.get("foo", default="default") + assert result == "default" + result = client.set("foo", "bar") assert result is False def test_no_servers_left_return_positional_default(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=True, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=True, timeout=1, connect_timeout=1 ) # Ensure compatibility with clients that pass the default as a # positional argument - result = client.get('foo', 'default') - assert result == 'default' + result = client.get("foo", "default") + assert result == "default" def test_no_servers_left_with_set_many(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=True, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=True, timeout=1, connect_timeout=1 ) - result = client.set_many({'foo': 'bar'}) - assert result == ['foo'] + result = client.set_many({"foo": "bar"}) + assert result == ["foo"] def test_no_servers_left_with_get_many(self): from pymemcache.client.hash import HashClient + client = HashClient( - [], use_pooling=True, - ignore_exc=True, - timeout=1, connect_timeout=1 + [], use_pooling=True, ignore_exc=True, timeout=1, connect_timeout=1 ) - result = client.get_many(['foo', 'bar']) + result = client.get_many(["foo", "bar"]) assert result == {} def test_ignore_exec_set_many(self): - values = { - 'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3' - } + values = {"key1": "value1", "key2": "value2", "key3": "value3"} with pytest.raises(MemcacheUnknownError): - client = self.make_client(*[ - [b'STORED\r\n', b'UNKNOWN\r\n', b'STORED\r\n'], - [b'STORED\r\n', b'UNKNOWN\r\n', b'STORED\r\n'], - ]) + client = self.make_client( + *[ + [b"STORED\r\n", b"UNKNOWN\r\n", b"STORED\r\n"], + [b"STORED\r\n", b"UNKNOWN\r\n", b"STORED\r\n"], + ] + ) client.set_many(values, noreply=False) - client = self.make_client(*[ - [b'STORED\r\n', b'UNKNOWN\r\n', b'STORED\r\n'], - ], ignore_exc=True) + client = self.make_client( + *[ + [b"STORED\r\n", b"UNKNOWN\r\n", b"STORED\r\n"], + ], + ignore_exc=True, + ) result = client.set_many(values, noreply=False) assert len(result) == 0 def test_noreply_set_many(self): - values = { - 'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3' - } + values = {"key1": "value1", "key2": "value2", "key3": "value3"} - client = self.make_client(*[ - [b'STORED\r\n', b'NOT_STORED\r\n', b'STORED\r\n'], - ]) + client = self.make_client( + *[ + [b"STORED\r\n", b"NOT_STORED\r\n", b"STORED\r\n"], + ] + ) result = client.set_many(values, noreply=False) assert len(result) == 1 - client = self.make_client(*[ - [b'STORED\r\n', b'NOT_STORED\r\n', b'STORED\r\n'], - ]) + client = self.make_client( + *[ + [b"STORED\r\n", b"NOT_STORED\r\n", b"STORED\r\n"], + ] + ) result = client.set_many(values, noreply=True) assert result == [] def test_set_many_unix(self): - values = { - 'key1': 'value1', - 'key2': 'value2', - 'key3': 'value3' - } + values = {"key1": "value1", "key2": "value2", "key3": "value3"} pid = os.getpid() - sockets = ['/tmp/pymemcache.%d' % pid] - client = self.make_unix_client(sockets, *[ - [b'STORED\r\n', b'NOT_STORED\r\n', b'STORED\r\n'], - ]) + sockets = ["/tmp/pymemcache.%d" % pid] + client = self.make_unix_client( + sockets, + *[ + [b"STORED\r\n", b"NOT_STORED\r\n", b"STORED\r\n"], + ], + ) result = client.set_many(values, noreply=False) assert len(result) == 1 @@ -357,11 +393,11 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): """ test passed encoding from hash client to pooled clients """ - encoding = 'utf8' + encoding = "utf8" from pymemcache.client.hash import HashClient + hash_client = HashClient( - [('example.com', 11211)], use_pooling=True, - encoding=encoding + [("example.com", 11211)], use_pooling=True, encoding=encoding ) for client in hash_client.clients.values(): @@ -371,11 +407,10 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): """ test passed encoding from hash client to clients """ - encoding = 'utf8' + encoding = "utf8" from pymemcache.client.hash import HashClient - hash_client = HashClient( - [('example.com', 11211)], encoding=encoding - ) + + hash_client = HashClient([("example.com", 11211)], encoding=encoding) for client in hash_client.clients.values(): assert client.encoding == encoding @@ -424,8 +459,8 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): client = HashClient([]) client.client_class = MyClient - client.add_server(('host', 11211)) - assert isinstance(client.clients['host:11211'], MyClient) + client.add_server(("host", 11211)) + assert isinstance(client.clients["host:11211"], MyClient) def test_custom_client_with_pooling(self): class MyClient(Client): @@ -433,36 +468,38 @@ class TestHashClient(ClientTestMixin, unittest.TestCase): client = HashClient([], use_pooling=True) client.client_class = MyClient - client.add_server(('host', 11211)) - assert isinstance(client.clients['host:11211'], PooledClient) + client.add_server(("host", 11211)) + assert isinstance(client.clients["host:11211"], PooledClient) - pool = client.clients['host:11211'].client_pool + pool = client.clients["host:11211"].client_pool with pool.get_and_release(destroy_on_fail=True) as c: assert isinstance(c, MyClient) def test_mixed_inet_and_unix_sockets(self): expected = { - f'/tmp/pymemcache.{os.getpid()}', - ('127.0.0.1', 11211), - ('::1', 11211), + f"/tmp/pymemcache.{os.getpid()}", + ("127.0.0.1", 11211), + ("::1", 11211), } - client = HashClient([ - f'/tmp/pymemcache.{os.getpid()}', - '127.0.0.1', - '127.0.0.1:11211', - '[::1]', - '[::1]:11211', - ('127.0.0.1', 11211), - ('::1', 11211), - ]) + client = HashClient( + [ + f"/tmp/pymemcache.{os.getpid()}", + "127.0.0.1", + "127.0.0.1:11211", + "[::1]", + "[::1]:11211", + ("127.0.0.1", 11211), + ("::1", 11211), + ] + ) assert expected == {c.server for c in client.clients.values()} def test_legacy_add_remove_server_signature(self): - server = ('127.0.0.1', 11211) + server = ("127.0.0.1", 11211) client = HashClient([]) assert client.clients == {} client.add_server(*server) # Unpack (host, port) tuple. - assert ('%s:%s' % server) in client.clients + assert ("%s:%s" % server) in client.clients client._mark_failed_server(server) assert server in client._failed_clients client.remove_server(*server) # Unpack (host, port) tuple. diff --git a/pymemcache/test/test_client_retry.py b/pymemcache/test/test_client_retry.py index 2a82ea1..bcf5396 100644 --- a/pymemcache/test/test_client_retry.py +++ b/pymemcache/test/test_client_retry.py @@ -14,15 +14,15 @@ from pymemcache.exceptions import MemcacheUnknownError, MemcacheClientError # Test pure passthroughs with no retry action. class TestRetryingClientPassthrough(ClientTestMixin, unittest.TestCase): - def make_base_client(self, mock_socket_values, **kwargs): base_client = Client(None, **kwargs) # mock out client._connect() rather than hard-setting client.sock to # ensure methods are checking whether self.sock is None before # attempting to use it sock = MockSocket(list(mock_socket_values)) - base_client._connect = mock.Mock(side_effect=functools.partial( - setattr, base_client, "sock", sock)) + base_client._connect = mock.Mock( + side_effect=functools.partial(setattr, base_client, "sock", sock) + ) return base_client def make_client(self, mock_socket_values, **kwargs): @@ -39,16 +39,16 @@ class TestRetryingClientPassthrough(ClientTestMixin, unittest.TestCase): # Retry specific tests. @pytest.mark.unit() class TestRetryingClient(object): - def make_base_client(self, mock_socket_values, **kwargs): - """ Creates a regular mock client to wrap in the RetryClient. """ + """Creates a regular mock client to wrap in the RetryClient.""" base_client = Client(None, **kwargs) # mock out client._connect() rather than hard-setting client.sock to # ensure methods are checking whether self.sock is None before # attempting to use it sock = MockSocket(list(mock_socket_values)) - base_client._connect = mock.Mock(side_effect=functools.partial( - setattr, base_client, "sock", sock)) + base_client._connect = mock.Mock( + side_effect=functools.partial(setattr, base_client, "sock", sock) + ) return base_client def make_client(self, mock_socket_values, **kwargs): @@ -57,9 +57,7 @@ class TestRetryingClient(object): configured using kwargs. """ # Create a base client to wrap. - base_client = self.make_base_client( - mock_socket_values=mock_socket_values - ) + base_client = self.make_base_client(mock_socket_values=mock_socket_values) # Wrap the client in the retrying class, and pass kwargs on. client = RetryingClient(base_client, **kwargs) @@ -147,7 +145,7 @@ class TestRetryingClient(object): rc = RetryingClient( base_client, retry_for=[Exception, IOError], - do_not_retry_for=[ValueError, MemcacheUnknownError] + do_not_retry_for=[ValueError, MemcacheUnknownError], ) assert rc._retry_for == (Exception, IOError) assert rc._do_not_retry_for == (ValueError, MemcacheUnknownError) @@ -157,7 +155,7 @@ class TestRetryingClient(object): rc = RetryingClient( base_client, retry_for=[Exception, IOError, MemcacheUnknownError], - do_not_retry_for=[ValueError, MemcacheUnknownError] + do_not_retry_for=[ValueError, MemcacheUnknownError], ) def test_dir_passthrough(self): @@ -167,74 +165,58 @@ class TestRetryingClient(object): assert dir(base) == dir(client) def test_retry_dict_set_is_supported(self): - client = self.make_client([b'UNKNOWN\r\n', b'STORED\r\n']) - client[b'key'] = b'value' + client = self.make_client([b"UNKNOWN\r\n", b"STORED\r\n"]) + client[b"key"] = b"value" def test_retry_dict_get_is_supported(self): client = self.make_client( - [ - b'UNKNOWN\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ] + [b"UNKNOWN\r\n", b"VALUE key 0 5\r\nvalue\r\nEND\r\n"] ) - assert client[b'key'] == b'value' + assert client[b"key"] == b"value" def test_retry_dict_get_not_found_is_supported(self): - client = self.make_client([b'UNKNOWN\r\n', b'END\r\n']) + client = self.make_client([b"UNKNOWN\r\n", b"END\r\n"]) with pytest.raises(KeyError): - client[b'key'] + client[b"key"] def test_retry_dict_del_is_supported(self): - client = self.make_client([b'UNKNOWN\r\n', b'DELETED\r\n']) - del client[b'key'] + client = self.make_client([b"UNKNOWN\r\n", b"DELETED\r\n"]) + del client[b"key"] def test_retry_get_found(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], attempts=2) + client = self.make_client( + [b"UNKNOWN\r\n", b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=2 + ) result = client.get("key") - assert result == b'value' + assert result == b"value" def test_retry_get_not_found(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'END\r\n' - ], attempts=2) + client = self.make_client([b"UNKNOWN\r\n", b"END\r\n"], attempts=2) result = client.get("key") assert result is None def test_retry_get_exception(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'UNKNOWN\r\n' - ], attempts=2) + client = self.make_client([b"UNKNOWN\r\n", b"UNKNOWN\r\n"], attempts=2) with pytest.raises(MemcacheUnknownError): client.get("key") def test_retry_set_success(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'STORED\r\n' - ], attempts=2) + client = self.make_client([b"UNKNOWN\r\n", b"STORED\r\n"], attempts=2) result = client.set("key", "value", noreply=False) assert result is True def test_retry_set_fail(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'UNKNOWN\r\n', - b'STORED\r\n' - ], attempts=2) + client = self.make_client( + [b"UNKNOWN\r\n", b"UNKNOWN\r\n", b"STORED\r\n"], attempts=2 + ) with pytest.raises(MemcacheUnknownError): client.set("key", "value", noreply=False) def test_no_retry(self): - client = self.make_client([ - b'UNKNOWN\r\n', - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], attempts=1) + client = self.make_client( + [b"UNKNOWN\r\n", b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=1 + ) with pytest.raises(MemcacheUnknownError): client.get("key") @@ -242,25 +224,19 @@ class TestRetryingClient(object): def test_retry_for_exception_success(self): # Test that we retry for the exception specified. client = self.make_client( - [ - MemcacheClientError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], + [MemcacheClientError("Whoops."), b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=2, - retry_for=tuple([MemcacheClientError]) + retry_for=tuple([MemcacheClientError]), ) result = client.get("key") - assert result == b'value' + assert result == b"value" def test_retry_for_exception_fail(self): # Test that we do not retry for unapproved exception. client = self.make_client( - [ - MemcacheUnknownError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], + [MemcacheUnknownError("Whoops."), b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=2, - retry_for=tuple([MemcacheClientError]) + retry_for=tuple([MemcacheClientError]), ) with pytest.raises(MemcacheUnknownError): @@ -269,25 +245,19 @@ class TestRetryingClient(object): def test_do_not_retry_for_exception_success(self): # Test that we retry for exceptions not specified. client = self.make_client( - [ - MemcacheClientError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], + [MemcacheClientError("Whoops."), b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=2, - do_not_retry_for=tuple([MemcacheUnknownError]) + do_not_retry_for=tuple([MemcacheUnknownError]), ) result = client.get("key") - assert result == b'value' + assert result == b"value" def test_do_not_retry_for_exception_fail(self): # Test that we do not retry for the exception specified. client = self.make_client( - [ - MemcacheClientError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n' - ], + [MemcacheClientError("Whoops."), b"VALUE key 0 5\r\nvalue\r\nEND\r\n"], attempts=2, - do_not_retry_for=tuple([MemcacheClientError]) + do_not_retry_for=tuple([MemcacheClientError]), ) with pytest.raises(MemcacheClientError): @@ -298,18 +268,18 @@ class TestRetryingClient(object): client = self.make_client( [ MemcacheClientError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n', + b"VALUE key 0 5\r\nvalue\r\nEND\r\n", MemcacheUnknownError("Whoops."), - b'VALUE key 0 5\r\nvalue\r\nEND\r\n', + b"VALUE key 0 5\r\nvalue\r\nEND\r\n", ], attempts=2, retry_for=tuple([MemcacheClientError]), - do_not_retry_for=tuple([MemcacheUnknownError]) + do_not_retry_for=tuple([MemcacheUnknownError]), ) # Check that we succeed where allowed. result = client.get("key") - assert result == b'value' + assert result == b"value" # Check that no retries are attempted for the banned exception. with pytest.raises(MemcacheUnknownError): diff --git a/pymemcache/test/test_integration.py b/pymemcache/test/test_integration.py index 8ca3ba7..02d7a60 100644 --- a/pymemcache/test/test_integration.py +++ b/pymemcache/test/test_integration.py @@ -17,14 +17,8 @@ import json import pytest from pymemcache.client.base import Client -from pymemcache.exceptions import ( - MemcacheIllegalInputError, - MemcacheClientError -) -from pymemcache.serde import ( - PickleSerde, - pickle_serde -) +from pymemcache.exceptions import MemcacheIllegalInputError, MemcacheClientError +from pymemcache.serde import PickleSerde, pickle_serde def get_set_helper(client, key, value, key2, value2): @@ -51,23 +45,24 @@ def test_get_set(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - key = b'key' - value = b'value' - key2 = b'key2' - value2 = b'value2' + key = b"key" + value = b"value" + key2 = b"key2" + value2 = b"value2" get_set_helper(client, key, value, key2, value2) @pytest.mark.integration() def test_get_set_unicode_key(client_class, host, port, socket_module): - client = client_class((host, port), socket_module=socket_module, - allow_unicode_keys=True) + client = client_class( + (host, port), socket_module=socket_module, allow_unicode_keys=True + ) client.flush_all() key = "こんにちは" - value = b'hello' - key2 = 'my☃' - value2 = b'value2' + value = b"hello" + key2 = "my☃" + value2 = b"value2" get_set_helper(client, key, value, key2, value2) @@ -76,25 +71,25 @@ def test_add_replace(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.add(b'key', b'value', noreply=False) + result = client.add(b"key", b"value", noreply=False) assert result is True - result = client.get(b'key') - assert result == b'value' + result = client.get(b"key") + assert result == b"value" - result = client.add(b'key', b'value2', noreply=False) + result = client.add(b"key", b"value2", noreply=False) assert result is False - result = client.get(b'key') - assert result == b'value' + result = client.get(b"key") + assert result == b"value" - result = client.replace(b'key1', b'value1', noreply=False) + result = client.replace(b"key1", b"value1", noreply=False) assert result is False - result = client.get(b'key1') + result = client.get(b"key1") assert result is None - result = client.replace(b'key', b'value2', noreply=False) + result = client.replace(b"key", b"value2", noreply=False) assert result is True - result = client.get(b'key') - assert result == b'value2' + result = client.get(b"key") + assert result == b"value2" @pytest.mark.integration() @@ -102,54 +97,54 @@ def test_append_prepend(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.append(b'key', b'value', noreply=False) + result = client.append(b"key", b"value", noreply=False) assert result is False - result = client.get(b'key') + result = client.get(b"key") assert result is None - result = client.set(b'key', b'value', noreply=False) + result = client.set(b"key", b"value", noreply=False) assert result is True - result = client.append(b'key', b'after', noreply=False) + result = client.append(b"key", b"after", noreply=False) assert result is True - result = client.get(b'key') - assert result == b'valueafter' + result = client.get(b"key") + assert result == b"valueafter" - result = client.prepend(b'key1', b'value', noreply=False) + result = client.prepend(b"key1", b"value", noreply=False) assert result is False - result = client.get(b'key1') + result = client.get(b"key1") assert result is None - result = client.prepend(b'key', b'before', noreply=False) + result = client.prepend(b"key", b"before", noreply=False) assert result is True - result = client.get(b'key') - assert result == b'beforevalueafter' + result = client.get(b"key") + assert result == b"beforevalueafter" @pytest.mark.integration() def test_cas(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.cas(b'key', b'value', b'1', noreply=False) + result = client.cas(b"key", b"value", b"1", noreply=False) assert result is None - result = client.set(b'key', b'value', noreply=False) + result = client.set(b"key", b"value", noreply=False) assert result is True # binary, string, and raw int all match -- should all be encoded as b'1' - result = client.cas(b'key', b'value', b'1', noreply=False) + result = client.cas(b"key", b"value", b"1", noreply=False) assert result is False - result = client.cas(b'key', b'value', '1', noreply=False) + result = client.cas(b"key", b"value", "1", noreply=False) assert result is False - result = client.cas(b'key', b'value', 1, noreply=False) + result = client.cas(b"key", b"value", 1, noreply=False) assert result is False - result, cas = client.gets(b'key') - assert result == b'value' + result, cas = client.gets(b"key") + assert result == b"value" - result = client.cas(b'key', b'value1', cas, noreply=False) + result = client.cas(b"key", b"value1", cas, noreply=False) assert result is True - result = client.cas(b'key', b'value2', cas, noreply=False) + result = client.cas(b"key", b"value2", cas, noreply=False) assert result is False @@ -158,13 +153,13 @@ def test_gets(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.gets(b'key') + result = client.gets(b"key") assert result == (None, None) - result = client.set(b'key', b'value', noreply=False) + result = client.set(b"key", b"value", noreply=False) assert result is True - result = client.gets(b'key') - assert result[0] == b'value' + result = client.gets(b"key") + assert result[0] == b"value" @pytest.mark.integration() @@ -172,16 +167,16 @@ def test_delete(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.delete(b'key', noreply=False) + result = client.delete(b"key", noreply=False) assert result is False - result = client.get(b'key') + result = client.get(b"key") assert result is None - result = client.set(b'key', b'value', noreply=False) + result = client.set(b"key", b"value", noreply=False) assert result is True - result = client.delete(b'key', noreply=False) + result = client.delete(b"key", noreply=False) assert result is True - result = client.get(b'key') + result = client.get(b"key") assert result is None @@ -190,27 +185,27 @@ def test_incr_decr(client_class, host, port, socket_module): client = Client((host, port), socket_module=socket_module) client.flush_all() - result = client.incr(b'key', 1, noreply=False) + result = client.incr(b"key", 1, noreply=False) assert result is None - result = client.set(b'key', b'0', noreply=False) + result = client.set(b"key", b"0", noreply=False) assert result is True - result = client.incr(b'key', 1, noreply=False) + result = client.incr(b"key", 1, noreply=False) assert result == 1 def _bad_int(): - client.incr(b'key', b'foobar') + client.incr(b"key", b"foobar") with pytest.raises(MemcacheClientError): _bad_int() - result = client.decr(b'key1', 1, noreply=False) + result = client.decr(b"key1", 1, noreply=False) assert result is None - result = client.decr(b'key', 1, noreply=False) + result = client.decr(b"key", 1, noreply=False) assert result == 0 - result = client.get(b'key') - assert result == b'0' + result = client.get(b"key") + assert result == b"0" @pytest.mark.integration() @@ -218,16 +213,16 @@ def test_touch(client_class, host, port, socket_module): client = client_class((host, port), socket_module=socket_module) client.flush_all() - result = client.touch(b'key', noreply=False) + result = client.touch(b"key", noreply=False) assert result is False - result = client.set(b'key', b'0', 1, noreply=False) + result = client.set(b"key", b"0", 1, noreply=False) assert result is True - result = client.touch(b'key', noreply=False) + result = client.touch(b"key", noreply=False) assert result is True - result = client.touch(b'key', 1, noreply=False) + result = client.touch(b"key", 1, noreply=False) assert result is True @@ -241,69 +236,63 @@ def test_misc(client_class, host, port, socket_module): def test_serialization_deserialization(host, port, socket_module): class JsonSerde: def serialize(self, key, value): - return json.dumps(value).encode('ascii'), 1 + return json.dumps(value).encode("ascii"), 1 def deserialize(self, key, value, flags): if flags == 1: - return json.loads(value.decode('ascii')) + return json.loads(value.decode("ascii")) return value - client = Client((host, port), serde=JsonSerde(), - socket_module=socket_module) + client = Client((host, port), serde=JsonSerde(), socket_module=socket_module) client.flush_all() - value = {'a': 'b', 'c': ['d']} - client.set(b'key', value) - result = client.get(b'key') + value = {"a": "b", "c": ["d"]} + client.set(b"key", value) + result = client.get(b"key") assert result == value -def serde_serialization_helper(client_class, host, port, - socket_module, serde): +def serde_serialization_helper(client_class, host, port, socket_module, serde): def check(value): - client.set(b'key', value, noreply=False) - result = client.get(b'key') + client.set(b"key", value, noreply=False) + result = client.get(b"key") assert result == value assert type(result) is type(value) - client = client_class((host, port), serde=serde, - socket_module=socket_module) + client = client_class((host, port), serde=serde, socket_module=socket_module) client.flush_all() - check(b'byte string') - check('unicode string') - check('olé') - check('olé') + check(b"byte string") + check("unicode string") + check("olé") + check("olé") check(1) check(123123123123123123123) - check({'a': 'pickle'}) - check(['one pickle', 'two pickle']) + check({"a": "pickle"}) + check(["one pickle", "two pickle"]) testdict = defaultdict(int) - testdict['one pickle'] - testdict[b'two pickle'] + testdict["one pickle"] + testdict[b"two pickle"] check(testdict) @pytest.mark.integration() def test_serde_serialization(client_class, host, port, socket_module): - serde_serialization_helper(client_class, host, port, - socket_module, pickle_serde) + serde_serialization_helper(client_class, host, port, socket_module, pickle_serde) @pytest.mark.integration() def test_serde_serialization0(client_class, host, port, socket_module): serde_serialization_helper( - client_class, host, port, - socket_module, - PickleSerde(pickle_version=0)) + client_class, host, port, socket_module, PickleSerde(pickle_version=0) + ) @pytest.mark.integration() def test_serde_serialization2(client_class, host, port, socket_module): serde_serialization_helper( - client_class, host, port, - socket_module, - PickleSerde(pickle_version=2)) + client_class, host, port, socket_module, PickleSerde(pickle_version=2) + ) @pytest.mark.integration() @@ -312,37 +301,37 @@ def test_errors(client_class, host, port, socket_module): client.flush_all() def _key_with_ws(): - client.set(b'key with spaces', b'value', noreply=False) + client.set(b"key with spaces", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _key_with_ws() def _key_with_illegal_carriage_return(): - client.set(b'\r\nflush_all', b'value', noreply=False) + client.set(b"\r\nflush_all", b"value", noreply=False) with pytest.raises(MemcacheIllegalInputError): _key_with_illegal_carriage_return() def _key_too_long(): - client.set(b'x' * 1024, b'value', noreply=False) + client.set(b"x" * 1024, b"value", noreply=False) with pytest.raises(MemcacheClientError): _key_too_long() def _unicode_key_in_set(): - client.set('\u0FFF', b'value', noreply=False) + client.set("\u0FFF", b"value", noreply=False) with pytest.raises(MemcacheClientError): _unicode_key_in_set() def _unicode_key_in_get(): - client.get('\u0FFF') + client.get("\u0FFF") with pytest.raises(MemcacheClientError): _unicode_key_in_get() def _unicode_value_in_set(): - client.set(b'key', '\u0FFF', noreply=False) + client.set(b"key", "\u0FFF", noreply=False) with pytest.raises(MemcacheClientError): _unicode_value_in_set() @@ -351,14 +340,12 @@ def test_errors(client_class, host, port, socket_module): @pytest.mark.integration() def test_tls(client_class, tls_host, tls_port, socket_module, tls_context): client = client_class( - (tls_host, tls_port), - socket_module=socket_module, - tls_context=tls_context + (tls_host, tls_port), socket_module=socket_module, tls_context=tls_context ) client.flush_all() - key = b'key' - value = b'value' - key2 = b'key2' - value2 = b'value2' + key = b"key" + value = b"value" + key2 = b"key2" + value2 = b"value2" get_set_helper(client, key, value, key2, value2) diff --git a/pymemcache/test/test_rendezvous.py b/pymemcache/test/test_rendezvous.py index 067b760..2582df5 100644 --- a/pymemcache/test/test_rendezvous.py +++ b/pymemcache/test/test_rendezvous.py @@ -6,94 +6,94 @@ import pytest def test_init_no_options(): rendezvous = RendezvousHash() assert 0 == len(rendezvous.nodes) - assert 1361238019 == rendezvous.hash_function('6666') + assert 1361238019 == rendezvous.hash_function("6666") @pytest.mark.unit() def test_init(): - nodes = ['0', '1', '2'] + nodes = ["0", "1", "2"] rendezvous = RendezvousHash(nodes=nodes) assert 3 == len(rendezvous.nodes) - assert 1361238019 == rendezvous.hash_function('6666') + assert 1361238019 == rendezvous.hash_function("6666") @pytest.mark.unit() def test_seed(): rendezvous = RendezvousHash(seed=10) - assert 2981722772 == rendezvous.hash_function('6666') + assert 2981722772 == rendezvous.hash_function("6666") @pytest.mark.unit() def test_add_node(): rendezvous = RendezvousHash() - rendezvous.add_node('1') + rendezvous.add_node("1") assert 1 == len(rendezvous.nodes) - rendezvous.add_node('1') + rendezvous.add_node("1") assert 1 == len(rendezvous.nodes) - rendezvous.add_node('2') + rendezvous.add_node("2") assert 2 == len(rendezvous.nodes) - rendezvous.add_node('1') + rendezvous.add_node("1") assert 2 == len(rendezvous.nodes) @pytest.mark.unit() def test_remove_node(): - nodes = ['0', '1', '2'] + nodes = ["0", "1", "2"] rendezvous = RendezvousHash(nodes=nodes) - rendezvous.remove_node('2') + rendezvous.remove_node("2") assert 2 == len(rendezvous.nodes) with pytest.raises(ValueError): - rendezvous.remove_node('2') + rendezvous.remove_node("2") assert 2 == len(rendezvous.nodes) - rendezvous.remove_node('1') + rendezvous.remove_node("1") assert 1 == len(rendezvous.nodes) - rendezvous.remove_node('0') + rendezvous.remove_node("0") assert 0 == len(rendezvous.nodes) @pytest.mark.unit() def test_get_node(): - nodes = ['0', '1', '2'] + nodes = ["0", "1", "2"] rendezvous = RendezvousHash(nodes=nodes) - assert '0' == rendezvous.get_node('ok') - assert '1' == rendezvous.get_node('mykey') - assert '2' == rendezvous.get_node('wat') + assert "0" == rendezvous.get_node("ok") + assert "1" == rendezvous.get_node("mykey") + assert "2" == rendezvous.get_node("wat") @pytest.mark.unit() def test_get_node_after_removal(): - nodes = ['0', '1', '2'] + nodes = ["0", "1", "2"] rendezvous = RendezvousHash(nodes=nodes) - rendezvous.remove_node('1') + rendezvous.remove_node("1") - assert '0' == rendezvous.get_node('ok') - assert '0' == rendezvous.get_node('mykey') - assert '2' == rendezvous.get_node('wat') + assert "0" == rendezvous.get_node("ok") + assert "0" == rendezvous.get_node("mykey") + assert "2" == rendezvous.get_node("wat") @pytest.mark.unit() def test_get_node_after_addition(): - nodes = ['0', '1', '2'] + nodes = ["0", "1", "2"] rendezvous = RendezvousHash(nodes=nodes) - assert '0' == rendezvous.get_node('ok') - assert '1' == rendezvous.get_node('mykey') - assert '2' == rendezvous.get_node('wat') - assert '2' == rendezvous.get_node('lol') - rendezvous.add_node('3') + assert "0" == rendezvous.get_node("ok") + assert "1" == rendezvous.get_node("mykey") + assert "2" == rendezvous.get_node("wat") + assert "2" == rendezvous.get_node("lol") + rendezvous.add_node("3") - assert '0' == rendezvous.get_node('ok') - assert '1' == rendezvous.get_node('mykey') - assert '2' == rendezvous.get_node('wat') - assert '3' == rendezvous.get_node('lol') + assert "0" == rendezvous.get_node("ok") + assert "1" == rendezvous.get_node("mykey") + assert "2" == rendezvous.get_node("wat") + assert "3" == rendezvous.get_node("lol") @pytest.mark.unit() @@ -150,7 +150,7 @@ def test_shrink(): node = rendezvous.get_node(str(i)) placements[node].append(i) - rendezvous.remove_node('9') + rendezvous.remove_node("9") new_placements = {} for i in range(9): new_placements[str(i)] = [] @@ -181,23 +181,23 @@ def collide(key, seed): @pytest.mark.unit() def test_rendezvous_collision(): - nodes = ['c', 'b', 'a'] + nodes = ["c", "b", "a"] rendezvous = RendezvousHash(nodes, hash_function=collide) for i in range(1000): - assert 'c' == rendezvous.get_node(i) + assert "c" == rendezvous.get_node(i) @pytest.mark.unit() def test_rendezvous_names(): - nodes = [1, 2, 3, 'a', 'b', 'lol.wat.com'] + nodes = [1, 2, 3, "a", "b", "lol.wat.com"] rendezvous = RendezvousHash(nodes, hash_function=collide) for i in range(10): - assert 'lol.wat.com' == rendezvous.get_node(i) + assert "lol.wat.com" == rendezvous.get_node(i) - nodes = [1, 'a', '0'] + nodes = [1, "a", "0"] rendezvous = RendezvousHash(nodes, hash_function=collide) for i in range(10): - assert 'a' == rendezvous.get_node(i) + assert "a" == rendezvous.get_node(i) diff --git a/pymemcache/test/test_serde.py b/pymemcache/test/test_serde.py index d4c58dc..e36e213 100644 --- a/pymemcache/test/test_serde.py +++ b/pymemcache/test/test_serde.py @@ -1,9 +1,13 @@ from unittest import TestCase -from pymemcache.serde import (pickle_serde, - PickleSerde, - FLAG_BYTES, - FLAG_PICKLE, FLAG_INTEGER, FLAG_TEXT) +from pymemcache.serde import ( + pickle_serde, + PickleSerde, + FLAG_BYTES, + FLAG_PICKLE, + FLAG_INTEGER, + FLAG_TEXT, +) import pytest import pickle @@ -15,6 +19,7 @@ class CustomInt(int): Entirely useless, but used to show that built in types get serialized and deserialized back as the same type of object. """ + pass @@ -23,30 +28,30 @@ class TestSerde(TestCase): serde = pickle_serde def check(self, value, expected_flags): - serialized, flags = self.serde.serialize(b'key', value) + serialized, flags = self.serde.serialize(b"key", value) assert flags == expected_flags # pymemcache stores values as byte strings, so we immediately the value # if needed so deserialized works as it would with a real server if not isinstance(serialized, bytes): - serialized = str(serialized).encode('ascii') + serialized = str(serialized).encode("ascii") - deserialized = self.serde.deserialize(b'key', serialized, flags) + deserialized = self.serde.deserialize(b"key", serialized, flags) assert deserialized == value def test_bytes(self): - self.check(b'value', FLAG_BYTES) - self.check(b'\xc2\xa3 $ \xe2\x82\xac', FLAG_BYTES) # £ $ € + self.check(b"value", FLAG_BYTES) + self.check(b"\xc2\xa3 $ \xe2\x82\xac", FLAG_BYTES) # £ $ € def test_unicode(self): - self.check('value', FLAG_TEXT) - self.check('£ $ €', FLAG_TEXT) + self.check("value", FLAG_TEXT) + self.check("£ $ €", FLAG_TEXT) def test_int(self): self.check(1, FLAG_INTEGER) def test_pickleable(self): - self.check({'a': 'dict'}, FLAG_PICKLE) + self.check({"a": "dict"}, FLAG_PICKLE) def test_subtype(self): # Subclass of a native type will be restored as the same type @@ -70,6 +75,4 @@ class TestSerdePickleVersion2(TestCase): @pytest.mark.unit() class TestSerdePickleVersionHighest(TestCase): - serde = PickleSerde( - pickle_version=pickle.HIGHEST_PROTOCOL - ) + serde = PickleSerde(pickle_version=pickle.HIGHEST_PROTOCOL) diff --git a/pymemcache/test/test_utils.py b/pymemcache/test/test_utils.py index dac4ce3..6dc6a9a 100644 --- a/pymemcache/test/test_utils.py +++ b/pymemcache/test/test_utils.py @@ -27,7 +27,7 @@ def test_get_set_non_ascii_value(): assert client.get(b"hello") is None # This is the value of msgpack.packb('non_ascii') - non_ascii_str = b'\xa9non_ascii' + non_ascii_str = b"\xa9non_ascii" client.set(b"hello", non_ascii_str) assert client.get(b"hello") == non_ascii_str @@ -41,7 +41,7 @@ def test_get_many_set_many(): assert result == {b"h": 1} # Convert keys into bytes - d = {k.encode('ascii'): v for k, v in dict(h=1, e=2, z=3).items()} + d = {k.encode("ascii"): v for k, v in dict(h=1, e=2, z=3).items()} client.set_many(d) assert client.get_many([b"h", b"e", b"z", b"o"]) == d @@ -51,17 +51,19 @@ def test_get_many_set_many_non_ascii_values(): client = MockMemcacheClient() # These are the values of calling msgpack.packb() on '1', '2', and '3' - non_ascii_1 = b'\xa11' - non_ascii_2 = b'\xa12' - non_ascii_3 = b'\xa13' + non_ascii_1 = b"\xa11" + non_ascii_2 = b"\xa12" + non_ascii_3 = b"\xa13" client.set(b"h", non_ascii_1) result = client.get_many([b"h", b"e", b"l", b"o"]) assert result == {b"h": non_ascii_1} # Convert keys into bytes - d = {k.encode('ascii'): v - for k, v in dict(h=non_ascii_1, e=non_ascii_2, z=non_ascii_3).items()} + d = { + k.encode("ascii"): v + for k, v in dict(h=non_ascii_1, e=non_ascii_2, z=non_ascii_3).items() + } client.set_many(d) assert client.get_many([b"h", b"e", b"z", b"o"]) == d @@ -105,7 +107,7 @@ def test_incr_decr(): def test_prepand_append(): client = MockMemcacheClient() - client.set(b"k", '1') - client.append(b"k", 'a') - client.prepend(b"k", 'p') - assert client.get(b"k") == b'p1a' + client.set(b"k", "1") + client.append(b"k", "a") + client.prepend(b"k", "p") + assert client.get(b"k") == b"p1a" diff --git a/pymemcache/test/utils.py b/pymemcache/test/utils.py index 52310ab..0ca7f16 100644 --- a/pymemcache/test/utils.py +++ b/pymemcache/test/utils.py @@ -20,20 +20,22 @@ class MockMemcacheClient: """ - def __init__(self, - server=None, - serde=None, - serializer=None, - deserializer=None, - connect_timeout=None, - timeout=None, - no_delay=False, - ignore_exc=False, - socket_module=None, - default_noreply=True, - allow_unicode_keys=False, - encoding='ascii', - tls_context=None): + def __init__( + self, + server=None, + serde=None, + serializer=None, + deserializer=None, + connect_timeout=None, + timeout=None, + no_delay=False, + ignore_exc=False, + socket_module=None, + default_noreply=True, + allow_unicode_keys=False, + encoding="ascii", + tls_context=None, + ): self._contents = {} @@ -84,8 +86,7 @@ class MockMemcacheClient: def set(self, key, value, expire=0, noreply=True, flags=None): key = self.check_key(key) - if (isinstance(value, str) and - not isinstance(value, bytes)): + if isinstance(value, str) and not isinstance(value, bytes): try: value = value.encode(self.encoding) except (UnicodeEncodeError, UnicodeDecodeError): @@ -144,8 +145,7 @@ class MockMemcacheClient: def prepend(self, key, value, expire=0, noreply=True, flags=None): current = self.get(key) if current is not None: - if (isinstance(value, str) and - not isinstance(value, bytes)): + if isinstance(value, str) and not isinstance(value, bytes): try: value = value.encode(self.encoding) except (UnicodeEncodeError, UnicodeDecodeError): @@ -156,8 +156,7 @@ class MockMemcacheClient: def append(self, key, value, expire=0, noreply=True, flags=None): current = self.get(key) if current is not None: - if (isinstance(value, str) and - not isinstance(value, bytes)): + if isinstance(value, str) and not isinstance(value, bytes): try: value = value.encode(self.encoding) except (UnicodeEncodeError, UnicodeDecodeError): @@ -197,7 +196,7 @@ class MockMemcacheClient: return noreply or present def cas(self, key, value, cas, expire=0, noreply=False, flags=None): - raise MemcacheClientError('CAS is not enabled for this instance') + raise MemcacheClientError("CAS is not enabled for this instance") def touch(self, key, expire=0, noreply=True): current = self.get(key) @@ -210,7 +209,7 @@ class MockMemcacheClient: return True def version(self): - return 'MockMemcacheClient' + return "MockMemcacheClient" def flush_all(self, delay=0, noreply=True): self.clear() |