1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-09 01:03:24 +00:00

Make Serializers Dumber

Let's have the serializer just worry about serializing the dict
that we hand it, and move the unicode stuff up to a serialize module.

This should hopefully let us move toward using a version string in
cassettes.
This commit is contained in:
Kevin McCarthy
2014-05-06 18:48:29 -10:00
parent 4ab46f9643
commit e50f917cf4
5 changed files with 42 additions and 47 deletions

View File

@@ -10,7 +10,7 @@ class MockSerializer(object):
def deserialize(self, cassette_string): def deserialize(self, cassette_string):
self.serialize_count += 1 self.serialize_count += 1
self.cassette_string = cassette_string self.cassette_string = cassette_string
return ([], []) return []
def serialize(self, cassette_dict): def serialize(self, cassette_dict):
self.deserialize_count += 1 self.deserialize_count += 1

View File

@@ -2,6 +2,7 @@ import tempfile
from .persisters.filesystem import FilesystemPersister from .persisters.filesystem import FilesystemPersister
from . import migration from . import migration
from . import serialize
def _check_for_old_cassette(cassette_content): def _check_for_old_cassette(cassette_content):
@@ -21,7 +22,7 @@ def load_cassette(cassette_path, serializer):
with open(cassette_path) as f: with open(cassette_path) as f:
cassette_content = f.read() cassette_content = f.read()
try: try:
cassette = serializer.deserialize(cassette_content) cassette = serialize.deserialize(cassette_content, serializer)
except TypeError: except TypeError:
_check_for_old_cassette(cassette_content) _check_for_old_cassette(cassette_content)
raise raise
@@ -29,5 +30,5 @@ def load_cassette(cassette_path, serializer):
def save_cassette(cassette_path, cassette_dict, serializer): def save_cassette(cassette_path, cassette_dict, serializer):
data = serializer.serialize(cassette_dict) data = serialize.serialize(cassette_dict, serializer)
FilesystemPersister.write(cassette_path, data) FilesystemPersister.write(cassette_path, data)

33
vcr/serialize.py Normal file
View File

@@ -0,0 +1,33 @@
from serializers import compat
from vcr.request import Request
"""
Just a general note on the serialization philosophy here:
I prefer cassettes to be human-readable if possible. Yaml serializes
bytestrings to !!binary, which isn't readable, so I would like to serialize to
strings and from strings, which yaml will encode as utf-8 automatically.
All the internal HTTP stuff expects bytestrings, so this whole serialization
process feels backwards.
Serializing: bytestring -> string (yaml persists to utf-8)
Deserializing: string (yaml converts from utf-8) -> bytestring
"""
def deserialize(cassette_string, serializer):
data = serializer.deserialize(cassette_string)
requests = [Request._from_dict(r['request']) for r in data]
responses = [r['response'] for r in data]
responses = [compat.convert_to_bytes(r['response']) for r in data]
return requests, responses
def serialize(cassette_dict, serializer):
data = ([{
'request': request._to_dict(),
'response': compat.convert_to_unicode(response),
} for request, response in zip(
cassette_dict['requests'],
cassette_dict['responses'],
)])
return serializer.serialize(data)

View File

@@ -1,5 +1,3 @@
from vcr.request import Request
from . import compat
try: try:
import simplejson as json import simplejson as json
except ImportError: except ImportError:
@@ -7,26 +5,16 @@ except ImportError:
def deserialize(cassette_string): def deserialize(cassette_string):
data = json.loads(cassette_string) return json.loads(cassette_string)
requests = [Request._from_dict(r['request']) for r in data]
responses = [compat.convert_to_bytes(r['response']) for r in data]
return requests, responses
def serialize(cassette_dict): def serialize(cassette_dict):
data = ([{
'request': request._to_dict(),
'response': compat.convert_to_unicode(response),
} for request, response in zip(
cassette_dict['requests'],
cassette_dict['responses']
)])
try: try:
return json.dumps(data, indent=4) return json.dumps(cassette_dict, indent=4)
except UnicodeDecodeError: except UnicodeDecodeError:
raise UnicodeDecodeError( raise UnicodeDecodeError(
"Error serializing cassette to JSON. ", "Error serializing cassette to JSON. ",
"Does this HTTP interaction contain binary data? ", "Does this HTTP interaction contain binary data? ",
"If so, use a different serializer (like the yaml serializer) for", "If so, use a different serializer (like the yaml serializer) for ",
"this request" "this request"
) )

View File

@@ -1,41 +1,14 @@
import yaml import yaml
from vcr.request import Request
from . import compat
# Use the libYAML versions if possible # Use the libYAML versions if possible
try: try:
from yaml import CLoader as Loader, CDumper as Dumper from yaml import CLoader as Loader, CDumper as Dumper
except ImportError: except ImportError:
from yaml import Loader, Dumper from yaml import Loader, Dumper
"""
Just a general note on the serialization philosophy here:
I prefer cassettes to be human-readable if possible. Yaml serializes
bytestrings to !!binary, which isn't readable, so I would like to serialize to
strings and from strings, which yaml will encode as utf-8 automatically.
All the internal HTTP stuff expects bytestrings, so this whole serialization
process feels backwards.
Serializing: bytestring -> string (yaml persists to utf-8)
Deserializing: string (yaml converts from utf-8) -> bytestring
"""
def deserialize(cassette_string): def deserialize(cassette_string):
data = yaml.load(cassette_string, Loader=Loader) return yaml.load(cassette_string, Loader=Loader)
requests = [Request._from_dict(r['request']) for r in data]
responses = [r['response'] for r in data]
responses = [compat.convert_to_bytes(r['response']) for r in data]
return requests, responses
def serialize(cassette_dict): def serialize(cassette_dict):
data = ([{ return yaml.dump(cassette_dict, Dumper=Dumper)
'request': request._to_dict(),
'response': response,
} for request, response in zip(
cassette_dict['requests'],
[compat.convert_to_unicode(r) for r in cassette_dict['responses']],
)])
return yaml.dump(data, Dumper=Dumper)