@@ -229,11 +229,23 @@ class BlobWriter(io.BufferedIOBase):
229229 writes must be exactly a multiple of 256KiB as with other resumable
230230 uploads. The default is the chunk_size of the blob, or 40 MiB.
231231
232- :type text_mode: boolean
232+ :type text_mode: bool
233233 :param text_mode:
234- Whether this class is wrapped in 'io.TextIOWrapper'. Toggling this
235- changes the behavior of flush() to conform to TextIOWrapper's
236- expectations.
234+ (Deprecated) A synonym for ignore_flush. For backwards-compatibility,
235+ if True, sets ignore_flush to True. Use ignore_flush instead. This
236+ parameter will be removed in a future release.
237+
238+ :type ignore_flush: bool
239+ :param ignore_flush:
240+ Makes flush() do nothing instead of raise an error. flush() without
241+ closing is not supported by the remote service and therefore calling it
242+ on this class normally results in io.UnsupportedOperation. However, that
243+ behavior is incompatible with some consumers and wrappers of file
244+ objects in Python, such as zipfile.ZipFile or io.TextIOWrapper. Setting
245+ ignore_flush will cause flush() to successfully do nothing, for
246+ compatibility with those contexts. The correct way to actually flush
247+ data to the remote server is to close() (using this object as a context
248+ manager is recommended).
237249
238250 :type retry: google.api_core.retry.Retry or google.cloud.storage.retry.ConditionalRetryPolicy
239251 :param retry:
@@ -278,6 +290,7 @@ def __init__(
278290 blob ,
279291 chunk_size = None ,
280292 text_mode = False ,
293+ ignore_flush = False ,
281294 retry = DEFAULT_RETRY_IF_GENERATION_SPECIFIED ,
282295 ** upload_kwargs
283296 ):
@@ -292,9 +305,8 @@ def __init__(
292305 # Resumable uploads require a chunk size of a multiple of 256KiB.
293306 # self._chunk_size must not be changed after the upload is initiated.
294307 self ._chunk_size = chunk_size or blob .chunk_size or DEFAULT_CHUNK_SIZE
295- # In text mode this class will be wrapped and TextIOWrapper requires a
296- # different behavior of flush().
297- self ._text_mode = text_mode
308+ # text_mode is a deprecated synonym for ignore_flush
309+ self ._ignore_flush = ignore_flush or text_mode
298310 self ._retry = retry
299311 self ._upload_kwargs = upload_kwargs
300312
@@ -394,13 +406,14 @@ def tell(self):
394406 return self ._buffer .tell () + len (self ._buffer )
395407
396408 def flush (self ):
397- if self ._text_mode :
398- # TextIOWrapper expects this method to succeed before calling close().
399- return
400-
401- raise io .UnsupportedOperation (
402- "Cannot flush without finalizing upload. Use close() instead."
403- )
409+ # flush() is not fully supported by the remote service, so raise an
410+ # error here, unless self._ignore_flush is set.
411+ if not self ._ignore_flush :
412+ raise io .UnsupportedOperation (
413+ "Cannot flush without finalizing upload. Use close() instead, "
414+ "or set ignore_flush=True when constructing this class (see "
415+ "docstring)."
416+ )
404417
405418 def close (self ):
406419 self ._checkClosed () # Raises ValueError if closed.
0 commit comments