1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-08 16:53:23 +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):
self.serialize_count += 1
self.cassette_string = cassette_string
return ([], [])
return []
def serialize(self, cassette_dict):
self.deserialize_count += 1

View File

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

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:
import simplejson as json
except ImportError:
@@ -7,26 +5,16 @@ except ImportError:
def deserialize(cassette_string):
data = 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
return json.loads(cassette_string)
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:
return json.dumps(data, indent=4)
return json.dumps(cassette_dict, indent=4)
except UnicodeDecodeError:
raise UnicodeDecodeError(
"Error serializing cassette to JSON. ",
"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"
)

View File

@@ -1,41 +1,14 @@
import yaml
from vcr.request import Request
from . import compat
# Use the libYAML versions if possible
try:
from yaml import CLoader as Loader, CDumper as Dumper
except ImportError:
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):
data = 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
return yaml.load(cassette_string, Loader=Loader)
def serialize(cassette_dict):
data = ([{
'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)
return yaml.dump(cassette_dict, Dumper=Dumper)