Skip to content

Commit

Permalink
Return default from hash client when using positional argument
Browse files Browse the repository at this point in the history
When using `HashClient` with `ignore_exc`, `get` would always return
`None` if no server is available and the default is passed as a
positional argument. The other clients return the default
value in this case. An earlier fix only had the desired effect when
passing `default` as a keyword argument.

Return the default value so `HashClient` behaves like the other
clients even when using

Fixes another variation of issue #350
  • Loading branch information
Pankrat committed Oct 14, 2021
1 parent 25e38df commit c2071a9
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
5 changes: 5 additions & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Changelog
=========

Unreleased
----------
* ``Client.get`` returns the default when using ``ignore_exc`` and if memcached
is unavailable

New in version 3.5.0
--------------------
* Sockets are now closed on ``MemcacheUnexpectedCloseError``.
Expand Down
5 changes: 2 additions & 3 deletions pymemcache/client/hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,8 @@ def close(self):
def set(self, key, *args, **kwargs):
return self._run_cmd('set', key, False, *args, **kwargs)

def get(self, key, *args, **kwargs):
default = kwargs.get('default', None)
return self._run_cmd('get', key, default, *args, **kwargs)
def get(self, key, default=None, **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)
Expand Down
17 changes: 15 additions & 2 deletions pymemcache/test/test_client_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,19 @@ def test_no_servers_left_with_commands_return_default_value(self):
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
)

# Ensure compatibility with clients that pass the default as a
# positional argument
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(
Expand Down Expand Up @@ -381,7 +394,7 @@ def test_dead_server_comes_back(self, client_patch):
# Client gets removed because of socket timeout
assert ("127.0.0.1", 11211) in client._dead_clients

test_client.get.side_effect = lambda *_: "Some value"
test_client.get.side_effect = lambda *_, **_kw: "Some value"
# Client should be retried and brought back
assert client.get(b"key") == "Some value"
assert ("127.0.0.1", 11211) not in client._dead_clients
Expand All @@ -400,7 +413,7 @@ def test_failed_is_retried(self, client_patch):
with pytest.raises(socket.timeout):
client.get(b"key", noreply=False)

test_client.get.side_effect = lambda *_: "Some value"
test_client.get.side_effect = lambda *_, **_kw: "Some value"
assert client.get(b"key") == "Some value"

assert client_patch.call_count == 1
Expand Down

0 comments on commit c2071a9

Please sign in to comment.