summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Parise <jon@pinterest.com>2022-02-22 09:17:32 -0800
committerGitHub <noreply@github.com>2022-02-22 09:17:32 -0800
commit29c1c5ab9a46e7d83b8e44efcd962bb78a28031e (patch)
tree530bd931d1a5c9c7c8caa3b1000a7a8fa40ab4fb
parenta2be8250c68b22315e278686b9e57c2dcbee3b62 (diff)
downloadpymemcache-29c1c5ab9a46e7d83b8e44efcd962bb78a28031e.tar.gz
Formalize typing for server specifications (#376)
This also drops support for passing None as a server spec, which is something many tests were doing out of lazy convenience. I can't think of a reason why we'd want to support that for real world usage.
-rw-r--r--pymemcache/client/base.py21
-rw-r--r--pymemcache/test/test_client.py37
-rw-r--r--pymemcache/test/test_client_retry.py4
3 files changed, 31 insertions, 31 deletions
diff --git a/pymemcache/client/base.py b/pymemcache/client/base.py
index d1392d4..bcfce10 100644
--- a/pymemcache/client/base.py
+++ b/pymemcache/client/base.py
@@ -11,9 +11,11 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+
import errno
import platform
import socket
+from typing import Tuple, Union
from pymemcache import pool
@@ -49,6 +51,8 @@ STORE_RESULTS_VALUE = {
b"EXISTS": False,
}
+ServerSpec = Union[Tuple[str, int], str]
+
# Some of the values returned by the "stats" command
# need mapping into native Python types
@@ -116,13 +120,11 @@ def check_key_helper(key, allow_unicode_keys, key_prefix=b""):
return key
-def normalize_server_spec(server):
- if isinstance(server, tuple) or server is None:
+def normalize_server_spec(server: ServerSpec) -> ServerSpec:
+ if isinstance(server, tuple):
return server
- if isinstance(server, list):
- return tuple(server) # Assume [host, port] provided.
if not isinstance(server, str):
- raise ValueError("Unknown server provided: %r" % server)
+ raise ValueError(f"Unsupported server specification: {server!r}")
if server.startswith("unix:"):
return server[5:]
if server.startswith("/"):
@@ -130,8 +132,8 @@ def normalize_server_spec(server):
if ":" not in server or server.endswith("]"):
host, port = server, 11211
else:
- host, port = server.rsplit(":", 1)
- port = int(port)
+ parts = server.rsplit(":", 1)
+ host, port = parts[0], int(parts[1])
if host.startswith("["):
host = host.strip("[]")
return (host, port)
@@ -267,7 +269,7 @@ class Client:
def __init__(
self,
- server,
+ server: ServerSpec,
serde=None,
serializer=None,
deserializer=None,
@@ -376,7 +378,6 @@ class Client:
if not isinstance(self.server, tuple):
sockaddr = self.server
sock = s.socket(s.AF_UNIX, s.SOCK_STREAM)
-
else:
sock = None
error = None
@@ -1191,7 +1192,7 @@ class PooledClient:
def __init__(
self,
- server,
+ server: ServerSpec,
serde=None,
serializer=None,
deserializer=None,
diff --git a/pymemcache/test/test_client.py b/pymemcache/test/test_client.py
index 56f3895..421d923 100644
--- a/pymemcache/test/test_client.py
+++ b/pymemcache/test/test_client.py
@@ -178,7 +178,7 @@ class CustomizedClient(Client):
@pytest.mark.unit()
class ClientTestMixin:
def make_client(self, mock_socket_values, **kwargs):
- client = Client(None, **kwargs)
+ client = Client("localhost", **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
@@ -189,7 +189,7 @@ class ClientTestMixin:
return client
def make_customized_client(self, mock_socket_values, **kwargs):
- client = CustomizedClient(None, **kwargs)
+ client = CustomizedClient("localhost", **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
@@ -1290,9 +1290,9 @@ class TestClientSocketConnect(unittest.TestCase):
class TestPooledClient(ClientTestMixin, unittest.TestCase):
def make_client(self, mock_socket_values, **kwargs):
- mock_client = Client(None, **kwargs)
+ mock_client = Client("localhost", **kwargs)
mock_client.sock = MockSocket(list(mock_socket_values))
- client = PooledClient(None, **kwargs)
+ client = PooledClient("localhost", **kwargs)
client.client_pool = pool.ObjectPool(lambda: mock_client)
return client
@@ -1360,9 +1360,9 @@ class TestPooledClient(ClientTestMixin, unittest.TestCase):
class TestPooledClientIdleTimeout(ClientTestMixin, unittest.TestCase):
def make_client(self, mock_socket_values, **kwargs):
- mock_client = Client(None, **kwargs)
+ mock_client = Client("localhost", **kwargs)
mock_client.sock = MockSocket(list(mock_socket_values))
- client = PooledClient(None, pool_idle_timeout=60, **kwargs)
+ client = PooledClient("localhost", pool_idle_timeout=60, **kwargs)
client.client_pool = pool.ObjectPool(lambda: mock_client)
return client
@@ -1392,7 +1392,7 @@ class TestPooledClientIdleTimeout(ClientTestMixin, unittest.TestCase):
class TestMockClient(ClientTestMixin, unittest.TestCase):
def make_client(self, mock_socket_values, **kwargs):
- client = MockMemcacheClient(None, **kwargs)
+ client = MockMemcacheClient("localhost", **kwargs)
client.sock = MockSocket(list(mock_socket_values))
return client
@@ -1440,7 +1440,7 @@ class TestMockClient(ClientTestMixin, unittest.TestCase):
class TestPrefixedClient(ClientTestMixin, unittest.TestCase):
def make_client(self, mock_socket_values, **kwargs):
- client = Client(None, key_prefix=b"xyz:", **kwargs)
+ client = Client("localhost", key_prefix=b"xyz:", **kwargs)
client.sock = MockSocket(list(mock_socket_values))
return client
@@ -1487,9 +1487,9 @@ class TestPrefixedClient(ClientTestMixin, unittest.TestCase):
class TestPrefixedPooledClient(TestPrefixedClient):
def make_client(self, mock_socket_values, **kwargs):
- mock_client = Client(None, key_prefix=b"xyz:", **kwargs)
+ mock_client = Client("localhost", key_prefix=b"xyz:", **kwargs)
mock_client.sock = MockSocket(list(mock_socket_values))
- client = PooledClient(None, key_prefix=b"xyz:", **kwargs)
+ client = PooledClient("localhost", key_prefix=b"xyz:", **kwargs)
client.client_pool = pool.ObjectPool(lambda: mock_client)
return client
@@ -1497,7 +1497,7 @@ class TestPrefixedPooledClient(TestPrefixedClient):
@pytest.mark.unit()
class TestRetryOnEINTR(unittest.TestCase):
def make_client(self, values):
- client = Client(None)
+ client = Client("localhost")
client.sock = MockSocket(list(values))
return client
@@ -1518,9 +1518,7 @@ class TestRetryOnEINTR(unittest.TestCase):
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)
@@ -1530,13 +1528,14 @@ class TestNormalizeServerSpec(unittest.TestCase):
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})
- assert str(excinfo.value) == "Unknown server provided: {'host': 12345}"
+ with pytest.raises(ValueError, match="Unsupported server specification"):
+ f(None) # type: ignore
- with pytest.raises(ValueError) as excinfo:
- f(12345)
- assert str(excinfo.value) == "Unknown server provided: 12345"
+ with pytest.raises(ValueError, match="Unsupported server specification"):
+ f({"host": 12345}) # type: ignore
+
+ with pytest.raises(ValueError, match="Unsupported server specification"):
+ f(12345) # type: ignore
@pytest.mark.unit()
diff --git a/pymemcache/test/test_client_retry.py b/pymemcache/test/test_client_retry.py
index bcf5396..293270f 100644
--- a/pymemcache/test/test_client_retry.py
+++ b/pymemcache/test/test_client_retry.py
@@ -15,7 +15,7 @@ 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)
+ base_client = Client("localhost", **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
@@ -41,7 +41,7 @@ class TestRetryingClientPassthrough(ClientTestMixin, unittest.TestCase):
class TestRetryingClient(object):
def make_base_client(self, mock_socket_values, **kwargs):
"""Creates a regular mock client to wrap in the RetryClient."""
- base_client = Client(None, **kwargs)
+ base_client = Client("localhost", **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