@@ -3198,6 +3198,7 @@ def compose(
3198
3198
timeout = _DEFAULT_TIMEOUT ,
3199
3199
if_generation_match = None ,
3200
3200
if_metageneration_match = None ,
3201
+ if_source_generation_match = None ,
3201
3202
retry = DEFAULT_RETRY_IF_GENERATION_SPECIFIED ,
3202
3203
):
3203
3204
"""Concatenate source blobs into this one.
@@ -3218,73 +3219,98 @@ def compose(
3218
3219
(Optional) The amount of time, in seconds, to wait
3219
3220
for the server response. See: :ref:`configuring_timeouts`
3220
3221
3221
- :type if_generation_match: list of long
3222
+ :type if_generation_match: long
3222
3223
:param if_generation_match:
3223
- (Optional) Make the operation conditional on whether the blob's
3224
- current generation matches the given value. Setting to 0 makes the
3225
- operation succeed only if there are no live versions of the blob.
3226
- The list must match ``sources`` item-to-item.
3224
+ (Optional) Makes the operation conditional on whether the
3225
+ destination object's current generation matches the given value.
3226
+ Setting to 0 makes the operation succeed only if there are no live
3227
+ versions of the object.
3228
+
3229
+ Note: In a previous version, this argument worked identically to the
3230
+ ``if_source_generation_match`` argument. For backwards-compatibility reasons,
3231
+ if a list is passed in, this argument will behave like ``if_source_generation_match``
3232
+ and also issue a DeprecationWarning.
3227
3233
3228
- :type if_metageneration_match: list of long
3234
+ :type if_metageneration_match: long
3229
3235
:param if_metageneration_match:
3230
- (Optional) Make the operation conditional on whether the blob's
3231
- current metageneration matches the given value. The list must match
3232
- ``sources`` item-to-item.
3236
+ (Optional) Makes the operation conditional on whether the
3237
+ destination object's current metageneration matches the given
3238
+ value.
3239
+
3240
+ If a list of long is passed in, no match operation will be performed.
3241
+ (Deprecated: type(list of long) is supported for backwards-compatability reasons only.)
3242
+
3243
+ :type if_source_generation_match: list of long
3244
+ :param if_source_generation_match:
3245
+ (Optional) Makes the operation conditional on whether the current generation
3246
+ of each source blob matches the corresponding generation.
3247
+ The list must match ``sources`` item-to-item.
3233
3248
3234
3249
:type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
3235
3250
:param retry:
3236
3251
(Optional) How to retry the RPC. See: :ref:`configuring_retries`
3237
3252
3238
3253
Example:
3239
- Compose blobs using generation match preconditions.
3254
+ Compose blobs using source generation match preconditions.
3240
3255
3241
3256
>>> from google.cloud import storage
3242
3257
>>> client = storage.Client()
3243
3258
>>> bucket = client.bucket("bucket-name")
3244
3259
3245
3260
>>> blobs = [bucket.blob("blob-name-1"), bucket.blob("blob-name-2")]
3246
- >>> if_generation_match = [None] * len(blobs)
3247
- >>> if_generation_match [0] = "123" # precondition for "blob-name-1"
3261
+ >>> if_source_generation_match = [None] * len(blobs)
3262
+ >>> if_source_generation_match [0] = "123" # precondition for "blob-name-1"
3248
3263
3249
3264
>>> composed_blob = bucket.blob("composed-name")
3250
- >>> composed_blob.compose(blobs, if_generation_match )
3265
+ >>> composed_blob.compose(blobs, if_source_generation_match=if_source_generation_match )
3251
3266
"""
3252
3267
sources_len = len (sources )
3253
- if if_generation_match is not None and len (if_generation_match ) != sources_len :
3254
- raise ValueError (
3255
- "'if_generation_match' length must be the same as 'sources' length"
3268
+ client = self ._require_client (client )
3269
+ query_params = {}
3270
+
3271
+ if isinstance (if_generation_match , list ):
3272
+ warnings .warn (
3273
+ "if_generation_match: type list is deprecated and supported for backwards-compatability reasons only."
3274
+ "Use if_source_generation_match instead to match source objects generations." ,
3275
+ DeprecationWarning ,
3276
+ stacklevel = 2 ,
3256
3277
)
3257
3278
3258
- if (
3259
- if_metageneration_match is not None
3260
- and len (if_metageneration_match ) != sources_len
3261
- ):
3262
- raise ValueError (
3263
- "'if_metageneration_match' length must be the same as 'sources' length"
3279
+ if if_source_generation_match is not None :
3280
+ raise ValueError (
3281
+ "Use if_generation_match to match the generation of the destination object by passing in a generation number, instead of a list."
3282
+ "Use if_source_generation_match to match source objects generations."
3283
+ )
3284
+
3285
+ # if_generation_match: type list is deprecated. Instead use if_source_generation_match.
3286
+ if_source_generation_match = if_generation_match
3287
+ if_generation_match = None
3288
+
3289
+ if isinstance (if_metageneration_match , list ):
3290
+ warnings .warn (
3291
+ "if_metageneration_match: type list is deprecated and supported for backwards-compatability reasons only."
3292
+ "Note that the metageneration to be matched is that of the destination blob."
3293
+ "Please pass in a single value (type long)." ,
3294
+ DeprecationWarning ,
3295
+ stacklevel = 2 ,
3264
3296
)
3265
3297
3266
- client = self ._require_client (client )
3267
- query_params = {}
3298
+ if_metageneration_match = None
3268
3299
3269
- if self .user_project is not None :
3270
- query_params ["userProject" ] = self .user_project
3300
+ if if_source_generation_match is None :
3301
+ if_source_generation_match = [None ] * sources_len
3302
+ if len (if_source_generation_match ) != sources_len :
3303
+ raise ValueError (
3304
+ "'if_source_generation_match' length must be the same as 'sources' length"
3305
+ )
3271
3306
3272
3307
source_objects = []
3273
- for index , source in enumerate (sources ):
3274
- source_object = {"name" : source .name }
3308
+ for source , source_generation in zip (sources , if_source_generation_match ):
3309
+ source_object = {"name" : source .name , "generation" : source . generation }
3275
3310
3276
3311
preconditions = {}
3277
- if (
3278
- if_generation_match is not None
3279
- and if_generation_match [index ] is not None
3280
- ):
3281
- preconditions ["ifGenerationMatch" ] = if_generation_match [index ]
3282
-
3283
- if (
3284
- if_metageneration_match is not None
3285
- and if_metageneration_match [index ] is not None
3286
- ):
3287
- preconditions ["ifMetagenerationMatch" ] = if_metageneration_match [index ]
3312
+ if source_generation is not None :
3313
+ preconditions ["ifGenerationMatch" ] = source_generation
3288
3314
3289
3315
if preconditions :
3290
3316
source_object ["objectPreconditions" ] = preconditions
@@ -3295,6 +3321,16 @@ def compose(
3295
3321
"sourceObjects" : source_objects ,
3296
3322
"destination" : self ._properties .copy (),
3297
3323
}
3324
+
3325
+ if self .user_project is not None :
3326
+ query_params ["userProject" ] = self .user_project
3327
+
3328
+ _add_generation_match_parameters (
3329
+ query_params ,
3330
+ if_generation_match = if_generation_match ,
3331
+ if_metageneration_match = if_metageneration_match ,
3332
+ )
3333
+
3298
3334
api_response = client ._post_resource (
3299
3335
"{}/compose" .format (self .path ),
3300
3336
request ,
0 commit comments