Skip to content

Commit

Permalink
Fix support newbytes from future
Browse files Browse the repository at this point in the history
Previously python2 code using python-future to backport the py3 bytes
behavior would trigger the following exception:

code:

  from builtins import bytes as newbytes
  from pymemcache.client.base import Client
  client = Client(('localhost', 11211))
  client.set(newbytes('key'), 'value')

  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/local/lib/python2.7/site-packages/pymemcache/client/base.py", line 297, in set
      return self._store_cmd(b'set', key, expire, noreply, value)
    File "/usr/local/lib/python2.7/site-packages/pymemcache/client/base.py", line 770, in _store_cmd
      key = self.check_key(key)
    File "/usr/local/lib/python2.7/site-packages/pymemcache/client/base.py", line 251, in check_key
      key_prefix=self.key_prefix)
    File "/usr/local/lib/python2.7/site-packages/pymemcache/client/base.py", line 91, in _check_key
      key = key.encode('ascii')
    File "/usr/local/lib/python2.7/site-packages/future/types/newbytes.py", line 381, in __getattribute__
      raise AttributeError("encode method has been disabled in newbytes")
  AttributeError: encode method has been disabled in newbytes

Add a test case for this and fix.
  • Loading branch information
jogo committed Sep 7, 2018
1 parent b80eb74 commit 519f98e
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 3 deletions.
5 changes: 4 additions & 1 deletion pymemcache/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ def _check_key(key, allow_unicode_keys, key_prefix=b''):
key = key.encode('utf8')
elif isinstance(key, VALID_STRING_TYPES):
try:
key = key.encode('ascii')
if isinstance(key, bytes):
key = key.decode().encode('ascii')
else:
key = key.encode('ascii')
except (UnicodeEncodeError, UnicodeDecodeError):
raise MemcacheIllegalInputError("Non-ASCII key: '%r'" % key)

Expand Down
7 changes: 7 additions & 0 deletions pymemcache/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from builtins import bytes as newbytes

import collections
import errno
import functools
Expand Down Expand Up @@ -100,6 +102,11 @@ def test_set_success(self):
result = client.set(b'key', b'value', noreply=False)
assert result is True

def test_set_future(self):
client = self.make_client([b'STORED\r\n'])
result = client.set(newbytes(b'key'), newbytes(b'value'), noreply=False)
assert result is True

def test_set_unicode_key(self):
client = self.make_client([b''])

Expand Down
5 changes: 5 additions & 0 deletions pymemcache/test/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from builtins import bytes as newbytes

from collections import defaultdict
import json
import pytest
Expand Down Expand Up @@ -41,6 +43,9 @@ def get_set_helper(client, key, value, key2, value2):
result = client.get(key2)
assert result == value2

result = client.get(newbytes(key2))
assert result == value2

result = client.get_many([key, key2])
assert result == {key: value, key2: value2}

Expand Down
10 changes: 8 additions & 2 deletions pymemcache/test/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ def get(self, key, default=None):
raise MemcacheIllegalInputError(key)
if isinstance(key, six.string_types):
try:
key = key.encode('ascii')
if isinstance(key, bytes):
key = key.decode().encode('ascii')
else:
key = key.encode('ascii')
except (UnicodeEncodeError, UnicodeDecodeError):
raise MemcacheIllegalInputError

Expand Down Expand Up @@ -80,7 +83,10 @@ def set(self, key, value, expire=0, noreply=True):
raise MemcacheIllegalInputError(key)
if isinstance(key, six.string_types):
try:
key = key.encode('ascii')
if isinstance(key, bytes):
key = key.decode().encode('ascii')
else:
key = key.encode('ascii')
except (UnicodeEncodeError, UnicodeDecodeError):
raise MemcacheIllegalInputError
if isinstance(value, six.text_type):
Expand Down
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pytest-cov
gevent==1.3.6; "PyPy" not in platform_python_implementation
pylibmc
python-memcached
future

0 comments on commit 519f98e

Please sign in to comment.