@@ -145,28 +145,37 @@ def put_object(self,
145145 def update_object (self ,
146146 object_key : str ,
147147 updater : Callable [[bytes ], bytes ],
148- max_attempts : int = 10
148+ * ,
149+ max_attempts : int = 10 ,
150+ content_type : str | None = None ,
149151 ):
150152 """
151- Updates the contents of an object, based on its existing contents, while
152- ensuring that concurrent updates are not overwritten. Expects a callback
153- that returns the desired contents of the object given its current
154- contents. If the callback ever returns its argument unchanged, no
155- further writes will be attempted. If the object does not exist at any
156- point during the update, StorageObjectNotFound is raised.
153+ Updates the contents and/or content type of an object, based on its
154+ existing contents, while ensuring that concurrent updates are not
155+ overwritten. Expects a callback that returns the desired contents of the
156+ object given its current contents. If the callback returns its argument
157+ unchanged and the specified content type is None or matches the current
158+ content type, no further writes will be attempted. If the object does
159+ not exist at any point during the update, StorageObjectNotFound is
160+ raised.
157161 """
158162 for i in range (max_attempts ):
159163 response = self ._get_object (object_key )
160164 etag = response ['ETag' ]
161165 data = response ['Body' ].read ()
166+ if content_type is None :
167+ content_type = response ['ContentType' ]
162168 new_data = updater (data )
163- if new_data == data :
169+ if new_data == data and content_type == response [ 'ContentType' ] :
164170 log .info ('Object contents of %r is already up to date during attempt #%r/%r.' ,
165171 object_key , i + 1 , max_attempts )
166172 break
167173 else :
168174 try :
169- self .put_object (object_key = object_key , data = new_data , etag = etag )
175+ self .put_object (object_key = object_key ,
176+ data = new_data ,
177+ etag = etag ,
178+ content_type = content_type )
170179 except botocore .exceptions .ClientError as e :
171180 error = e .response ['Error' ]
172181 code , condition = error ['Code' ], error .get ('Condition' )
0 commit comments