Я создал этот контекстный менеджер для создания временного объекта в S3 в целях тестирования:
from types import TracebackType
from typing import BinaryIO, Optional, Type
import boto3
class S3Object:
def __init__(self, file_object: BinaryIO, bucket_name: str, key: str):
self.file_object = file_object
self.bucket_name = bucket_name
self.key = key
self.s3 = boto3.client("s3")
def __enter__(self) -> "S3Object":
self.s3.upload_fileobj(self.file_object, self.bucket_name, self.key)
return self
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> bool:
delete_object_response = self.s3.delete_object(Bucket=self.bucket_name, Key=self.key)
# Delete version marker
self.s3.delete_object(
Bucket=self.bucket_name, Key=self.key, VersionId=delete_object_response["VersionId"]
)
print("Deleted object") # debugging
return False # Propagate exception
Я использую это так в одном тесте:
with S3Object(BytesIO(), bucket_name, filename) as s3_object:
…
Странно то, что, несмотря на то, что выходные данные теста включают выходные данные отладки удаленного объекта, исходный элемент все еще находится в корзине. Из вывода cdk destroy
:
Сегмент, который вы пытались удалить, не пуст. Вы должны удалить все версии в корзине.
Это определенно правильный файл, потому что я создаю уникальное имя файла на основе имени теста. Это также не похоже на проблему синхронизации, потому что это 100% воспроизводимость.
Я могу удалить файл вручную, так что особой защиты тоже нет.
После изменения кода для печати обоих ответов мне интересно, дважды ли я удалял маркер удаления? Сокращено для удобства чтения:
{'ResponseMetadata': {'HTTPStatusCode': 204, 'HTTPHeaders': {'x-amz-version-id': 'd08uv05t7lU7YKle4kMSURa_jrMU.GSL', 'x-amz-delete-marker': 'true'}}, 'DeleteMarker': True, 'VersionId': 'd08uv05t7lU7YKle4kMSURa_jrMU.GSL'}
{'ResponseMetadata': {'HTTPStatusCode': 204, 'HTTPHeaders': {'x-amz-version-id': 'd08uv05t7lU7YKle4kMSURa_jrMU.GSL', 'x-amz-delete-marker': 'true'}}, 'DeleteMarker': True, 'VersionId': 'd08uv05t7lU7YKle4kMSURa_jrMU.GSL'}