diff options
author | Jon Parise <jon@pinterest.com> | 2022-02-22 09:17:32 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-22 09:17:32 -0800 |
commit | 29c1c5ab9a46e7d83b8e44efcd962bb78a28031e (patch) | |
tree | 530bd931d1a5c9c7c8caa3b1000a7a8fa40ab4fb | |
parent | a2be8250c68b22315e278686b9e57c2dcbee3b62 (diff) | |
download | pymemcache-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.py | 21 | ||||
-rw-r--r-- | pymemcache/test/test_client.py | 37 | ||||
-rw-r--r-- | pymemcache/test/test_client_retry.py | 4 |
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 |