diff options
author | Stephen Rosen <sirosen@globus.org> | 2019-08-20 12:38:26 -0400 |
---|---|---|
committer | Jon Parise <jon@pinterest.com> | 2019-08-20 09:38:26 -0700 |
commit | 782d3ea20e671325a2125f17a3bdaf20ee3d3a7a (patch) | |
tree | 59949822dcd379f007f3747a267e908cab7eadcc /pymemcache/test/test_client.py | |
parent | 762856daf858360e4bd848fd82040f266bfdb2e2 (diff) | |
download | pymemcache-782d3ea20e671325a2125f17a3bdaf20ee3d3a7a.tar.gz |
Check integer input values to Client methods (#243)
If a caller tries to send
- a fractional expiration time
- a string for the "incr" command
- delay=None (instead of delay=0)
The pymemcache base client will now catch these usage mistakes a
throw a MemcacheIllegalInputError.
Although there are existing valid (but undocumented) usages of the
current string conversion behavior, the docs state that these values
are supposed to be ints. Now if a non-int value is used, it will
immediately trigger an error.
This behavior is superior to the prior behavior especially in the
case where a command is used with `noreply=True`. It can fail to
parse, but the client won't pick up on this until the next call to
memcache which reads the reply.
The especially bad case we're seeking to avoid is this:
from pymemcache.client.base import Client
client = Client(("localhost", 11211))
client.set("foo", "bar", expire=1.5, noreply=True)
client.get("foo") # triggers MemcacheUnknownCommandError
Applies to all commands using `expire`, `delay`, incr and decr
inputs, and memlimit.
Because this is can be a breaking change for some users, the changelog
entry is written under 3.0.0 (unreleased).
closes #240
Diffstat (limited to 'pymemcache/test/test_client.py')
-rw-r--r-- | pymemcache/test/test_client.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/pymemcache/test/test_client.py b/pymemcache/test/test_client.py index 0cebf32..a84e9c5 100644 --- a/pymemcache/test/test_client.py +++ b/pymemcache/test/test_client.py @@ -797,6 +797,23 @@ class TestClient(ClientTestMixin, unittest.TestCase): with pytest.raises(MemcacheIllegalInputError): _set() + def test_set_key_with_noninteger_expire(self): + client = self.make_client([b'']) + + class _OneLike(object): + """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) + + 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) |