mirror of
https://github.com/kevin1024/vcrpy.git
synced 2025-12-08 16:53:23 +00:00
feat: add an option to exclude unused interactions
Introduce the `drop_unused_requests` option (False by default). If True, it will force the `Cassette` saving operation with only played old interactions and new ones if they exist. As a result, unused old requests are dropped. Add `_old_interactions`, `_played_interactions` and `_new_interactions()`. The `_old_interactions` are previously recorded interactions loaded from Cassette files. The `_played_interactions` is a set of old interactions that were marked as played. A new interaction is a tuple (request, response) in `self.data` that is not in `_old_interactions` list.
This commit is contained in:
@@ -197,6 +197,7 @@ class Cassette:
|
||||
custom_patches=(),
|
||||
inject=False,
|
||||
allow_playback_repeats=False,
|
||||
drop_unused_requests=False,
|
||||
):
|
||||
self._persister = persister or FilesystemPersister
|
||||
self._path = path
|
||||
@@ -209,6 +210,7 @@ class Cassette:
|
||||
self.record_mode = record_mode
|
||||
self.custom_patches = custom_patches
|
||||
self.allow_playback_repeats = allow_playback_repeats
|
||||
self.drop_unused_requests = drop_unused_requests
|
||||
|
||||
# self.data is the list of (req, resp) tuples
|
||||
self.data = []
|
||||
@@ -216,6 +218,10 @@ class Cassette:
|
||||
self.dirty = False
|
||||
self.rewound = False
|
||||
|
||||
# Subsets of self.data to store old and played interactions
|
||||
self._old_interactions = []
|
||||
self._played_interactions = []
|
||||
|
||||
@property
|
||||
def play_count(self):
|
||||
return sum(self.play_counts.values())
|
||||
@@ -277,6 +283,7 @@ class Cassette:
|
||||
for index, response in self._responses(request):
|
||||
if self.play_counts[index] == 0 or self.allow_playback_repeats:
|
||||
self.play_counts[index] += 1
|
||||
self._played_interactions.append((request, response))
|
||||
return response
|
||||
# The cassette doesn't contain the request asked for.
|
||||
raise UnhandledHTTPRequestError(
|
||||
@@ -337,10 +344,27 @@ class Cassette:
|
||||
|
||||
return final_best_matches
|
||||
|
||||
def _new_interactions(self):
|
||||
"""List of new HTTP interactions (request/response tuples)"""
|
||||
new_interactions = []
|
||||
for request, response in self.data:
|
||||
if all(not requests_match(request, old_request, self._match_on)
|
||||
for old_request, _ in self._old_interactions):
|
||||
new_interactions.append((request, response))
|
||||
return new_interactions
|
||||
|
||||
def _as_dict(self):
|
||||
return {"requests": self.requests, "responses": self.responses}
|
||||
requests = self.requests
|
||||
responses = self.responses
|
||||
if self.drop_unused_requests:
|
||||
interactions = self._played_interactions + self._new_interactions()
|
||||
requests = [request for request, _ in interactions]
|
||||
responses = [response for _, response in interactions]
|
||||
return {"requests": requests, "responses": responses}
|
||||
|
||||
def _save(self, force=False):
|
||||
if (len(self._played_interactions) < len(self._old_interactions)):
|
||||
force = True
|
||||
if force or self.dirty:
|
||||
self._persister.save_cassette(self._path, self._as_dict(), serializer=self._serializer)
|
||||
self.dirty = False
|
||||
@@ -350,6 +374,7 @@ class Cassette:
|
||||
requests, responses = self._persister.load_cassette(self._path, serializer=self._serializer)
|
||||
for request, response in zip(requests, responses):
|
||||
self.append(request, response)
|
||||
self._old_interactions.append((request, response))
|
||||
self.dirty = False
|
||||
self.rewound = True
|
||||
except ValueError:
|
||||
|
||||
@@ -50,6 +50,7 @@ class VCR:
|
||||
func_path_generator=None,
|
||||
decode_compressed_response=False,
|
||||
record_on_exception=True,
|
||||
drop_unused_requests=False,
|
||||
):
|
||||
self.serializer = serializer
|
||||
self.match_on = match_on
|
||||
@@ -83,6 +84,7 @@ class VCR:
|
||||
self.decode_compressed_response = decode_compressed_response
|
||||
self.record_on_exception = record_on_exception
|
||||
self._custom_patches = tuple(custom_patches)
|
||||
self.drop_unused_requests = drop_unused_requests
|
||||
|
||||
def _get_serializer(self, serializer_name):
|
||||
try:
|
||||
@@ -153,6 +155,7 @@ class VCR:
|
||||
"func_path_generator": func_path_generator,
|
||||
"allow_playback_repeats": kwargs.get("allow_playback_repeats", False),
|
||||
"record_on_exception": record_on_exception,
|
||||
"drop_unused_requests": kwargs.get("drop_unused_requests", self.drop_unused_requests),
|
||||
}
|
||||
path = kwargs.get("path")
|
||||
if path:
|
||||
|
||||
Reference in New Issue
Block a user