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:
@@ -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
|
||||||
|
|||||||
@@ -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
33
vcr/serialize.py
Normal 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)
|
||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user