-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Python 3 serialization fixes, serialization improvements #131
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
7658ee0
Add integration test for serde serialization
tomkins b6c8921
Use byte strings after serializing with serde
tomkins f5ade4d
Improve serde
tomkins 7f611e9
Test for expected flags with serde tests
tomkins 1c565fb
Add test for subclasses of builtin types
tomkins f5e3538
Use is type for type comparisons
tomkins 4621b2e
Switch to is bytes for bytes comparision
tomkins 346984a
Add a few more serde integration tests
tomkins ea84e33
Add more serde unit tests for bytes/unicode
tomkins be8977c
Add FLAG_BYTES
tomkins 164f4cf
Ensure serde integration tests return the same type
tomkins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from collections import defaultdict | ||
import json | ||
import pytest | ||
import six | ||
|
@@ -22,6 +23,10 @@ | |
MemcacheIllegalInputError, | ||
MemcacheClientError | ||
) | ||
from pymemcache.serde import ( | ||
python_memcache_serializer, | ||
python_memcache_deserializer | ||
) | ||
|
||
|
||
def get_set_helper(client, key, value, key2, value2): | ||
|
@@ -231,6 +236,33 @@ def _des(key, value, flags): | |
assert result == value | ||
|
||
|
||
@pytest.mark.integration() | ||
def test_serde_serialization(client_class, host, port, socket_module): | ||
def check(value): | ||
client.set(b'key', value, noreply=False) | ||
result = client.get(b'key') | ||
assert result == value | ||
assert type(result) is type(value) | ||
|
||
client = client_class((host, port), serializer=python_memcache_serializer, | ||
deserializer=python_memcache_deserializer, | ||
socket_module=socket_module) | ||
client.flush_all() | ||
|
||
check(b'byte string') | ||
check(u'unicode string') | ||
check('olé') | ||
check(u'olé') | ||
check(1) | ||
check(123123123123123123123) | ||
check({'a': 'pickle'}) | ||
check([u'one pickle', u'two pickle']) | ||
testdict = defaultdict(int) | ||
testdict[u'one pickle'] | ||
testdict[b'two pickle'] | ||
check(testdict) | ||
|
||
|
||
@pytest.mark.integration() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
def test_errors(client_class, host, port, socket_module): | ||
client = client_class((host, port), socket_module=socket_module) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,61 @@ | ||
# -*- coding: utf-8 -*- | ||
from unittest import TestCase | ||
|
||
from pymemcache.serde import (python_memcache_serializer, | ||
python_memcache_deserializer) | ||
python_memcache_deserializer, FLAG_BYTES, | ||
FLAG_PICKLE, FLAG_INTEGER, FLAG_LONG, FLAG_TEXT) | ||
import pytest | ||
import six | ||
|
||
|
||
class CustomInt(int): | ||
""" | ||
Custom integer type for testing. | ||
|
||
Entirely useless, but used to show that built in types get serialized and | ||
deserialized back as the same type of object. | ||
""" | ||
pass | ||
|
||
|
||
@pytest.mark.unit() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the manual call to make sure it's called? Thanks for adding! |
||
class TestSerde(TestCase): | ||
|
||
def check(self, value): | ||
def check(self, value, expected_flags): | ||
serialized, flags = python_memcache_serializer(b'key', value) | ||
assert flags == expected_flags | ||
|
||
# pymemcache stores values as byte strings, so we immediately the value | ||
# if needed so deserialized works as it would with a real server | ||
if not isinstance(serialized, six.binary_type): | ||
serialized = six.text_type(serialized).encode('ascii') | ||
|
||
deserialized = python_memcache_deserializer(b'key', serialized, flags) | ||
assert deserialized == value | ||
|
||
def test_str(self): | ||
self.check('value') | ||
def test_bytes(self): | ||
self.check(b'value', FLAG_BYTES) | ||
self.check(b'\xc2\xa3 $ \xe2\x82\xac', FLAG_BYTES) # £ $ € | ||
|
||
def test_unicode(self): | ||
self.check(u'value', FLAG_TEXT) | ||
self.check(u'£ $ €', FLAG_TEXT) | ||
|
||
def test_int(self): | ||
self.check(1) | ||
self.check(1, FLAG_INTEGER) | ||
|
||
def test_long(self): | ||
self.check(123123123123123123123) | ||
# long only exists with Python 2, so we're just testing for another | ||
# integer with Python 3 | ||
if six.PY2: | ||
expected_flags = FLAG_LONG | ||
else: | ||
expected_flags = FLAG_INTEGER | ||
self.check(123123123123123123123, expected_flags) | ||
|
||
def test_pickleable(self): | ||
self.check({'a': 'dict'}) | ||
self.check({'a': 'dict'}, FLAG_PICKLE) | ||
|
||
def test_subtype(self): | ||
# Subclass of a native type will be restored as the same type | ||
self.check(CustomInt(123123), FLAG_PICKLE) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also check try some harder cases:
'olé'
(with and without specifying theu
unicode prefixThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added in defaultdict (a subclass of dict) to test pickle comparisons as well - as it's available in Python 2.5+.