Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-s3transfer for
openSUSE:Factory checked in at 2026-07-15 16:39:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-s3transfer (Old)
and /work/SRC/openSUSE:Factory/.python-s3transfer.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-s3transfer"
Wed Jul 15 16:39:33 2026 rev:45 rq:1365680 version:0.19.1
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-s3transfer/python-s3transfer.changes
2026-07-07 21:09:11.950736775 +0200
+++
/work/SRC/openSUSE:Factory/.python-s3transfer.new.1991/python-s3transfer.changes
2026-07-15 16:59:38.423125535 +0200
@@ -1,0 +2,7 @@
+Tue Jul 14 10:23:53 UTC 2026 - John Paul Adrian Glaubitz
<[email protected]>
+
+- Update to version 0.19.1
+ * bugfix:``s3``: Only pin VersionId if supplied by caller instead
+ of automatically using value from HeadObject response
+
+-------------------------------------------------------------------
Old:
----
s3transfer-0.19.0.tar.gz
New:
----
s3transfer-0.19.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-s3transfer.spec ++++++
--- /var/tmp/diff_new_pack.BtRtr5/_old 2026-07-15 16:59:39.751170159 +0200
+++ /var/tmp/diff_new_pack.BtRtr5/_new 2026-07-15 16:59:39.755170294 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-s3transfer
-Version: 0.19.0
+Version: 0.19.1
Release: 0
Summary: Python S3 transfer manager
License: Apache-2.0
++++++ s3transfer-0.19.0.tar.gz -> s3transfer-0.19.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/PKG-INFO
new/s3transfer-0.19.1/PKG-INFO
--- old/s3transfer-0.19.0/PKG-INFO 2026-06-16 20:24:04.006081600 +0200
+++ new/s3transfer-0.19.1/PKG-INFO 2026-07-10 20:11:52.433406800 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: s3transfer
-Version: 0.19.0
+Version: 0.19.1
Summary: An Amazon S3 Transfer Manager
Home-page: https://github.com/boto/s3transfer
Author: Amazon Web Services
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/s3transfer/__init__.py
new/s3transfer-0.19.1/s3transfer/__init__.py
--- old/s3transfer-0.19.0/s3transfer/__init__.py 2026-06-16
20:24:03.000000000 +0200
+++ new/s3transfer-0.19.1/s3transfer/__init__.py 2026-07-10
20:11:52.000000000 +0200
@@ -145,7 +145,7 @@
from s3transfer.exceptions import RetriesExceededError, S3UploadFailedError
__author__ = 'Amazon Web Services'
-__version__ = '0.19.0'
+__version__ = '0.19.1'
logger = logging.getLogger(__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/s3transfer/copies.py
new/s3transfer-0.19.1/s3transfer/copies.py
--- old/s3transfer-0.19.0/s3transfer/copies.py 2026-06-16 20:24:03.000000000
+0200
+++ new/s3transfer-0.19.1/s3transfer/copies.py 2026-07-10 20:11:52.000000000
+0200
@@ -130,8 +130,10 @@
transfer request that tasks are being submitted for
"""
preserved_metadata = {}
- source_version_id = None
call_args = transfer_future.meta.call_args
+ source_version_id = None
+ if isinstance(call_args.copy_source, dict):
+ source_version_id = call_args.copy_source.get('VersionId')
if (
transfer_future.meta.size is None
or transfer_future.meta.etag is None
@@ -166,9 +168,6 @@
# during a multipart copy.
transfer_future.meta.provide_object_etag(response.get('ETag'))
preserved_metadata = self._extract_preserved_metadata(response)
- # Pin the source version so all subsequent reads (tags,
annotations)
- # are consistent with the object from the head call
- source_version_id = response.get('VersionId')
# If it is greater than threshold do a multipart copy, otherwise
# do a regular copy object.
@@ -352,7 +351,8 @@
if extra_args.get('MetadataDirective') == 'REPLACE':
return extra_args
result = {
- k: v for k, v in extra_args.items()
+ k: v
+ for k, v in extra_args.items()
if k not in self.PRESERVED_METADATA_FIELDS
}
result.update(preserved_metadata)
@@ -418,7 +418,9 @@
client, call_args, source_version_id, dest_version_id, dest_etag
)
- def _apply_tags(self, client, call_args, source_version_id,
dest_version_id):
+ def _apply_tags(
+ self, client, call_args, source_version_id, dest_version_id
+ ):
extra_args = call_args.extra_args
directive = extra_args.get('TaggingDirective')
if directive not in ('COPY', 'REPLACE'):
@@ -506,7 +508,9 @@
'Bucket': call_args.bucket,
'Key': call_args.key,
'AnnotationName': name,
- 'AnnotationPayload':
payload_response['AnnotationPayload'].read(),
+ 'AnnotationPayload': payload_response[
+ 'AnnotationPayload'
+ ].read(),
**put_passthrough,
}
if dest_version_id:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/s3transfer/manager.py
new/s3transfer-0.19.1/s3transfer/manager.py
--- old/s3transfer-0.19.0/s3transfer/manager.py 2026-06-16 20:24:03.000000000
+0200
+++ new/s3transfer-0.19.1/s3transfer/manager.py 2026-07-10 20:11:52.000000000
+0200
@@ -462,14 +462,20 @@
# ignored unless the corresponding directive is set to 'REPLACE'. The
# warning surfaces this so callers don't get blindsided when their
# input has no effect.
- if extra_args.get('Metadata') and extra_args.get('MetadataDirective')
is None:
+ if (
+ extra_args.get('Metadata')
+ and extra_args.get('MetadataDirective') is None
+ ):
logger.warning(
"Metadata was supplied without a metadata directive. The "
"supplied metadata will be ignored and source metadata will "
"be preserved. Set the metadata directive to 'REPLACE' to "
"apply the supplied metadata."
)
- if extra_args.get('Tagging') and extra_args.get('TaggingDirective') is
None:
+ if (
+ extra_args.get('Tagging')
+ and extra_args.get('TaggingDirective') is None
+ ):
logger.warning(
"Tagging was supplied without a tagging directive. The "
"supplied tagging will be ignored and source tags will be "
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/s3transfer.egg-info/PKG-INFO
new/s3transfer-0.19.1/s3transfer.egg-info/PKG-INFO
--- old/s3transfer-0.19.0/s3transfer.egg-info/PKG-INFO 2026-06-16
20:24:03.000000000 +0200
+++ new/s3transfer-0.19.1/s3transfer.egg-info/PKG-INFO 2026-07-10
20:11:52.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: s3transfer
-Version: 0.19.0
+Version: 0.19.1
Summary: An Amazon S3 Transfer Manager
Home-page: https://github.com/boto/s3transfer
Author: Amazon Web Services
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/tests/functional/test_copy.py
new/s3transfer-0.19.1/tests/functional/test_copy.py
--- old/s3transfer-0.19.0/tests/functional/test_copy.py 2026-06-16
20:24:03.000000000 +0200
+++ new/s3transfer-0.19.1/tests/functional/test_copy.py 2026-07-10
20:11:52.000000000 +0200
@@ -764,7 +764,7 @@
future.result()
self.stubber.assert_no_pending_responses()
- def test_mp_copy_tagging_copy_pins_source_version_id(self):
+ def test_mp_copy_tagging_copy_does_not_pin_discovered_version_id(self):
source_version_id = 'abc123version'
source_tags = [{'Key': 'env', 'Value': 'prod'}]
self.stubber.add_response(
@@ -781,6 +781,36 @@
)
_, add_copy_kwargs = self._get_expected_params()
self.add_successful_copy_responses(**add_copy_kwargs)
+ self.add_get_object_tagging_response(source_tags)
+ self.add_put_object_tagging_response(source_tags)
+ future = self.manager.copy(
+ self.copy_source,
+ self.bucket,
+ self.key,
+ {'TaggingDirective': 'COPY'},
+ )
+ future.result()
+ self.stubber.assert_no_pending_responses()
+
+ def test_mp_copy_tagging_copy_pins_user_supplied_source_version_id(self):
+ source_version_id = 'abc123version'
+ source_tags = [{'Key': 'env', 'Value': 'prod'}]
+ self.copy_source['VersionId'] = source_version_id
+ self.stubber.add_response(
+ 'head_object',
+ service_response={
+ 'ContentLength': len(self.content),
+ 'ETag': self.etag,
+ 'VersionId': source_version_id,
+ },
+ expected_params={
+ 'Bucket': 'mysourcebucket',
+ 'Key': 'mysourcekey',
+ 'VersionId': source_version_id,
+ },
+ )
+ _, add_copy_kwargs = self._get_expected_params()
+ self.add_successful_copy_responses(**add_copy_kwargs)
self.stubber.add_response(
'get_object_tagging',
service_response={'TagSet': source_tags},
@@ -792,7 +822,9 @@
)
self.add_put_object_tagging_response(source_tags)
future = self.manager.copy(
- self.copy_source, self.bucket, self.key,
+ self.copy_source,
+ self.bucket,
+ self.key,
{'TaggingDirective': 'COPY'},
)
future.result()
@@ -823,13 +855,17 @@
},
)
future = self.manager.copy(
- self.copy_source, self.bucket, self.key,
+ self.copy_source,
+ self.bucket,
+ self.key,
{'Tagging': 'env=prod', 'TaggingDirective': 'REPLACE'},
)
future.result()
self.stubber.assert_no_pending_responses()
- def
test_mp_copy_forwards_passthrough_args_to_tag_and_annotation_calls(self):
+ def test_mp_copy_forwards_passthrough_args_to_tag_and_annotation_calls(
+ self,
+ ):
# RequestPayer/ExpectedBucketOwner go to all five tag/annotation ops;
# ChecksumAlgorithm only to the put ops. Stubber's expected_params
# asserts each call carries the right subset.
@@ -882,13 +918,15 @@
self.stubber.add_response(
'list_object_annotations',
service_response={
- 'Annotations': [{
- 'AnnotationName': 'note',
- 'LastModified': datetime.datetime(
- 2026, 1, 1, tzinfo=datetime.timezone.utc
- ),
- 'Size': len(annotation_payload),
- }],
+ 'Annotations': [
+ {
+ 'AnnotationName': 'note',
+ 'LastModified': datetime.datetime(
+ 2026, 1, 1, tzinfo=datetime.timezone.utc
+ ),
+ 'Size': len(annotation_payload),
+ }
+ ],
},
expected_params={
'Bucket': 'mysourcebucket',
@@ -920,7 +958,9 @@
},
)
future = self.manager.copy(
- self.copy_source, self.bucket, self.key,
+ self.copy_source,
+ self.bucket,
+ self.key,
{
'TaggingDirective': 'COPY',
'AnnotationDirective': 'COPY',
@@ -938,7 +978,9 @@
future.result()
self.stubber.assert_no_pending_responses()
- def
test_mp_copy_metadata_supplied_without_directive_preserves_source(self):
+ def test_mp_copy_metadata_supplied_without_directive_preserves_source(
+ self,
+ ):
head_metadata = {
'ContentType': 'application/octet-stream',
'Metadata': {'original': 'value'},
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/s3transfer-0.19.0/tests/unit/test_copies.py
new/s3transfer-0.19.1/tests/unit/test_copies.py
--- old/s3transfer-0.19.0/tests/unit/test_copies.py 2026-06-16
20:24:03.000000000 +0200
+++ new/s3transfer-0.19.1/tests/unit/test_copies.py 2026-07-10
20:11:52.000000000 +0200
@@ -50,7 +50,9 @@
class FakeCallArgs:
- def __init__(self, copy_source, bucket, key, extra_args=None,
source_client=None):
+ def __init__(
+ self, copy_source, bucket, key, extra_args=None, source_client=None
+ ):
self.copy_source = copy_source
self.bucket = bucket
self.key = key
@@ -69,11 +71,16 @@
def _make_call_args(self, extra_args, source_client=None):
return FakeCallArgs(
- self.copy_source, self.bucket, self.key, extra_args,
+ self.copy_source,
+ self.bucket,
+ self.key,
+ extra_args,
source_client=source_client,
)
- def _apply(self, client, call_args, source_version_id=None,
dest_version_id=None):
+ def _apply(
+ self, client, call_args, source_version_id=None, dest_version_id=None
+ ):
# Default source_client to the same client unless test overrode it
if call_args.source_client is None:
call_args.source_client = client
@@ -92,39 +99,55 @@
{'TaggingDirective': 'REPLACE', 'Tagging': 'env=prod&team=sdk'}
)
self._apply(client, call_args)
- self.assertEqual(client.calls, [
- ('put_object_tagging', {
- 'Bucket': self.bucket,
- 'Key': self.key,
- 'Tagging': {'TagSet': [
- {'Key': 'env', 'Value': 'prod'},
- {'Key': 'team', 'Value': 'sdk'},
- ]},
- })
- ])
+ self.assertEqual(
+ client.calls,
+ [
+ (
+ 'put_object_tagging',
+ {
+ 'Bucket': self.bucket,
+ 'Key': self.key,
+ 'Tagging': {
+ 'TagSet': [
+ {'Key': 'env', 'Value': 'prod'},
+ {'Key': 'team', 'Value': 'sdk'},
+ ]
+ },
+ },
+ )
+ ],
+ )
def test_copy_directive_fetches_and_applies_source_tags(self):
source_tags = [{'Key': 'env', 'Value': 'prod'}]
- client = RecordingClient(responses={
- 'get_object_tagging': {'TagSet': source_tags},
- })
+ client = RecordingClient(
+ responses={
+ 'get_object_tagging': {'TagSet': source_tags},
+ }
+ )
call_args = self._make_call_args({'TaggingDirective': 'COPY'})
self._apply(client, call_args)
methods = [c[0] for c in client.calls]
self.assertEqual(methods, ['get_object_tagging', 'put_object_tagging'])
- self.assertEqual(client.calls[1], (
- 'put_object_tagging', {
- 'Bucket': self.bucket,
- 'Key': self.key,
- 'Tagging': {'TagSet': source_tags},
- }
- ))
+ self.assertEqual(
+ client.calls[1],
+ (
+ 'put_object_tagging',
+ {
+ 'Bucket': self.bucket,
+ 'Key': self.key,
+ 'Tagging': {'TagSet': source_tags},
+ },
+ ),
+ )
def test_copy_directive_passes_version_id_to_get_object_tagging(self):
source_tags = [{'Key': 'env', 'Value': 'prod'}]
- client = RecordingClient(responses={
- 'get_object_tagging': {'TagSet': source_tags},
- })
+ client = RecordingClient(
+ responses={
+ 'get_object_tagging': {'TagSet': source_tags},
+ }
+ )
call_args = self._make_call_args({'TaggingDirective': 'COPY'})
self._apply(client, call_args, source_version_id='v123')
_, kwargs = client.calls[0]
@@ -132,22 +155,28 @@
def test_replace_directive_pins_dest_version_id_on_put(self):
client = RecordingClient()
- call_args = self._make_call_args({'TaggingDirective': 'REPLACE',
'Tagging': 'k=v'})
+ call_args = self._make_call_args(
+ {'TaggingDirective': 'REPLACE', 'Tagging': 'k=v'}
+ )
self._apply(client, call_args, dest_version_id='dest-v1')
_, kwargs = client.calls[0]
self.assertEqual(kwargs.get('VersionId'), 'dest-v1')
def test_replace_directive_omits_dest_version_id_when_none(self):
client = RecordingClient()
- call_args = self._make_call_args({'TaggingDirective': 'REPLACE',
'Tagging': 'k=v'})
+ call_args = self._make_call_args(
+ {'TaggingDirective': 'REPLACE', 'Tagging': 'k=v'}
+ )
self._apply(client, call_args, dest_version_id=None)
_, kwargs = client.calls[0]
self.assertNotIn('VersionId', kwargs)
def test_copy_directive_omits_version_id_when_none(self):
- client = RecordingClient(responses={
- 'get_object_tagging': {'TagSet': []},
- })
+ client = RecordingClient(
+ responses={
+ 'get_object_tagging': {'TagSet': []},
+ }
+ )
call_args = self._make_call_args({'TaggingDirective': 'COPY'})
self._apply(client, call_args, source_version_id=None)
_, kwargs = client.calls[0]
@@ -172,6 +201,7 @@
class AnnotationListClient(RecordingClient):
"""RecordingClient whose list_object_annotations returns a single
'note' annotation."""
+
def list_object_annotations(self, **kwargs):
self.calls.append(('list_object_annotations', kwargs))
return {'Annotations': [{'AnnotationName': 'note'}]}
@@ -180,7 +210,10 @@
def _make_call_args(self, extra_args, source_client=None):
return FakeCallArgs(
- self.copy_source, self.bucket, self.key, extra_args,
+ self.copy_source,
+ self.bucket,
+ self.key,
+ extra_args,
source_client=source_client,
)
@@ -205,25 +238,33 @@
def test_exclude_directive_makes_no_calls(self):
client = RecordingClient()
- self._apply(client, self._make_call_args({'AnnotationDirective':
'EXCLUDE'}))
+ self._apply(
+ client, self._make_call_args({'AnnotationDirective': 'EXCLUDE'})
+ )
self.assertEqual(client.calls, [])
def test_copy_directive_copies_annotations(self):
annotation_payload = b'hello annotation'
- client = RecordingClient(responses={
- 'list_object_annotations': {
- 'Annotations': [{'AnnotationName': 'my-note'}]
- },
- 'get_object_annotation': {
- 'AnnotationPayload': io.BytesIO(annotation_payload)
- },
- })
+ client = RecordingClient(
+ responses={
+ 'list_object_annotations': {
+ 'Annotations': [{'AnnotationName': 'my-note'}]
+ },
+ 'get_object_annotation': {
+ 'AnnotationPayload': io.BytesIO(annotation_payload)
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args)
methods = [c[0] for c in client.calls]
self.assertEqual(
methods,
- ['list_object_annotations', 'get_object_annotation',
'put_object_annotation'],
+ [
+ 'list_object_annotations',
+ 'get_object_annotation',
+ 'put_object_annotation',
+ ],
)
_, put_kwargs = client.calls[2]
self.assertEqual(put_kwargs['Bucket'], self.bucket)
@@ -232,9 +273,11 @@
self.assertEqual(put_kwargs['AnnotationPayload'], annotation_payload)
def test_copy_directive_with_no_source_annotations_skips_put(self):
- client = RecordingClient(responses={
- 'list_object_annotations': {'Annotations': []},
- })
+ client = RecordingClient(
+ responses={
+ 'list_object_annotations': {'Annotations': []},
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args)
methods = [c[0] for c in client.calls]
@@ -242,52 +285,79 @@
self.assertNotIn('put_object_annotation', methods)
def test_copy_directive_pins_dest_version_and_etag_on_put(self):
- client = self.AnnotationListClient(responses={
- 'get_object_annotation': {'AnnotationPayload':
io.BytesIO(b'data')},
- })
+ client = self.AnnotationListClient(
+ responses={
+ 'get_object_annotation': {
+ 'AnnotationPayload': io.BytesIO(b'data')
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(
- client, call_args, dest_version_id='dest-v1',
dest_etag='"destetag"'
+ client,
+ call_args,
+ dest_version_id='dest-v1',
+ dest_etag='"destetag"',
+ )
+ _, put_kwargs = next(
+ (m, k) for m, k in client.calls if m == 'put_object_annotation'
)
- _, put_kwargs = next((m, k) for m, k in client.calls if m ==
'put_object_annotation')
self.assertEqual(put_kwargs.get('VersionId'), 'dest-v1')
self.assertEqual(put_kwargs.get('ObjectIfMatch'), '"destetag"')
def test_copy_directive_omits_dest_pins_when_not_in_result(self):
- client = self.AnnotationListClient(responses={
- 'get_object_annotation': {'AnnotationPayload':
io.BytesIO(b'data')},
- })
+ client = self.AnnotationListClient(
+ responses={
+ 'get_object_annotation': {
+ 'AnnotationPayload': io.BytesIO(b'data')
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args)
- _, put_kwargs = next((m, k) for m, k in client.calls if m ==
'put_object_annotation')
+ _, put_kwargs = next(
+ (m, k) for m, k in client.calls if m == 'put_object_annotation'
+ )
self.assertNotIn('VersionId', put_kwargs)
self.assertNotIn('ObjectIfMatch', put_kwargs)
def test_copy_directive_passes_version_id_to_annotation_reads(self):
annotation_payload = b'data'
- client = self.AnnotationListClient(responses={
- 'get_object_annotation': {
- 'AnnotationPayload': io.BytesIO(annotation_payload)
- },
- })
+ client = self.AnnotationListClient(
+ responses={
+ 'get_object_annotation': {
+ 'AnnotationPayload': io.BytesIO(annotation_payload)
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args, source_version_id='v456')
- list_kwargs = next(k for m, k in client.calls if m ==
'list_object_annotations')
- get_kwargs = next(k for m, k in client.calls if m ==
'get_object_annotation')
+ list_kwargs = next(
+ k for m, k in client.calls if m == 'list_object_annotations'
+ )
+ get_kwargs = next(
+ k for m, k in client.calls if m == 'get_object_annotation'
+ )
self.assertEqual(list_kwargs.get('VersionId'), 'v456')
self.assertEqual(get_kwargs.get('VersionId'), 'v456')
def test_copy_directive_omits_version_id_from_annotations_when_none(self):
annotation_payload = b'data'
- client = self.AnnotationListClient(responses={
- 'get_object_annotation': {
- 'AnnotationPayload': io.BytesIO(annotation_payload)
- },
- })
+ client = self.AnnotationListClient(
+ responses={
+ 'get_object_annotation': {
+ 'AnnotationPayload': io.BytesIO(annotation_payload)
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args, source_version_id=None)
- list_kwargs = next(k for m, k in client.calls if m ==
'list_object_annotations')
- get_kwargs = next(k for m, k in client.calls if m ==
'get_object_annotation')
+ list_kwargs = next(
+ k for m, k in client.calls if m == 'list_object_annotations'
+ )
+ get_kwargs = next(
+ k for m, k in client.calls if m == 'get_object_annotation'
+ )
self.assertNotIn('VersionId', list_kwargs)
self.assertNotIn('VersionId', get_kwargs)
@@ -297,14 +367,20 @@
class FailingPutClient(RecordingClient):
def list_object_annotations(self, **kwargs):
self.calls.append(('list_object_annotations', kwargs))
- return {'Annotations': [
- {'AnnotationName': 'note-a'},
- {'AnnotationName': 'note-b'},
- ]}
+ return {
+ 'Annotations': [
+ {'AnnotationName': 'note-a'},
+ {'AnnotationName': 'note-b'},
+ ]
+ }
def get_object_annotation(self, **kwargs):
self.calls.append(('get_object_annotation', kwargs))
- return {'AnnotationPayload':
io.BytesIO(payloads[kwargs['AnnotationName']])}
+ return {
+ 'AnnotationPayload': io.BytesIO(
+ payloads[kwargs['AnnotationName']]
+ )
+ }
def put_object_annotation(self, **kwargs):
self.calls.append(('put_object_annotation', kwargs))
@@ -330,24 +406,36 @@
class MultiAnnotationClient(RecordingClient):
def get_object_annotation(self, **kwargs):
self.calls.append(('get_object_annotation', kwargs))
- return {'AnnotationPayload':
io.BytesIO(payloads[kwargs['AnnotationName']])}
-
- client = MultiAnnotationClient(responses={
- 'list_object_annotations': {
- 'Annotations': [
- {'AnnotationName': 'note-a'},
- {'AnnotationName': 'note-b'},
- ]
- },
- })
+ return {
+ 'AnnotationPayload': io.BytesIO(
+ payloads[kwargs['AnnotationName']]
+ )
+ }
+
+ client = MultiAnnotationClient(
+ responses={
+ 'list_object_annotations': {
+ 'Annotations': [
+ {'AnnotationName': 'note-a'},
+ {'AnnotationName': 'note-b'},
+ ]
+ },
+ }
+ )
call_args = self._make_call_args({'AnnotationDirective': 'COPY'})
self._apply(client, call_args)
- put_calls = [(c[1]['AnnotationName'], c[1]['AnnotationPayload'])
- for c in client.calls if c[0] == 'put_object_annotation']
- self.assertEqual(put_calls, [
- ('note-a', b'payload-a'),
- ('note-b', b'payload-b'),
- ])
+ put_calls = [
+ (c[1]['AnnotationName'], c[1]['AnnotationPayload'])
+ for c in client.calls
+ if c[0] == 'put_object_annotation'
+ ]
+ self.assertEqual(
+ put_calls,
+ [
+ ('note-a', b'payload-a'),
+ ('note-b', b'payload-b'),
+ ],
+ )
class BaseCopyTaskTest(BaseTaskTest):