diff --git a/gcloud/streaming/buffered_stream.py b/gcloud/streaming/buffered_stream.py index be3eb19c3980..6ce9299e701d 100644 --- a/gcloud/streaming/buffered_stream.py +++ b/gcloud/streaming/buffered_stream.py @@ -3,8 +3,6 @@ This class reads ahead to detect if we are at the end of the stream. """ -from gcloud.streaming.exceptions import NotYetImplementedError - class BufferedStream(object): """Buffers a stream, reading ahead to determine if we're at the end. @@ -65,7 +63,7 @@ def read(self, size=None): :param size: How many bytes to read (defaults to all remaining bytes). """ if size is None or size < 0: - raise NotYetImplementedError( + raise ValueError( 'Illegal read of size %s requested on BufferedStream. ' 'Wrapped stream %s is at position %s-%s, ' '%s bytes remaining.' % diff --git a/gcloud/streaming/exceptions.py b/gcloud/streaming/exceptions.py index 42a480e654b7..1b3a4f43286a 100644 --- a/gcloud/streaming/exceptions.py +++ b/gcloud/streaming/exceptions.py @@ -5,18 +5,6 @@ class Error(Exception): """Base class for all exceptions.""" -class NotFoundError(Error): - """A specified resource could not be found.""" - - -class UserError(Error): - """Base class for errors related to user input.""" - - -class InvalidDataError(Error): - """Base class for any invalid data error.""" - - class CommunicationError(Error): """Any communication error talking to an API server.""" @@ -66,14 +54,6 @@ def from_response(cls, http_response): http_response.request_url) -class InvalidUserInputError(InvalidDataError): - """User-provided input is invalid.""" - - -class ConfigurationValueError(UserError): - """Some part of the user-specified client configuration is invalid.""" - - class TransferError(CommunicationError): """Errors related to transfers.""" @@ -124,11 +104,3 @@ def from_response(cls, http_response): class BadStatusCodeError(HttpError): """The request completed but returned a bad status code.""" - - -class NotYetImplementedError(Error): - """This functionality is not yet implemented.""" - - -class StreamExhausted(Error): - """Attempted to read more bytes from a stream than were available.""" diff --git a/gcloud/streaming/stream_slice.py b/gcloud/streaming/stream_slice.py index ae798a32b244..ada3c66e2169 100644 --- a/gcloud/streaming/stream_slice.py +++ b/gcloud/streaming/stream_slice.py @@ -1,6 +1,6 @@ """Small helper class to provide a small slice of a stream.""" -from gcloud.streaming.exceptions import StreamExhausted +from six.moves import http_client class StreamSlice(object): @@ -48,7 +48,7 @@ def read(self, size=None): unexpectedly raise an exception on read: if the underlying stream is exhausted (i.e. returns no bytes on read), and the size of this slice indicates we should still be able to read more bytes, we - raise :exc:`StreamExhausted`. + raise :exc:`IncompleteRead`. :type size: integer or None :param size: If provided, read no more than size bytes from the stream. @@ -56,7 +56,7 @@ def read(self, size=None): :rtype: bytes :returns: bytes read from this slice. - :raises: :exc:`gcloud.streaming.exceptions.StreamExhausted` + :raises: :exc:`IncompleteRead` """ if size is not None: read_size = min(size, self._remaining_bytes) @@ -64,10 +64,7 @@ def read(self, size=None): read_size = self._remaining_bytes data = self._stream.read(read_size) if read_size > 0 and not data: - raise StreamExhausted( - 'Not enough bytes in stream; expected %d, exhausted ' - 'after %d' % ( - self._max_bytes, - self._max_bytes - self._remaining_bytes)) + raise http_client.IncompleteRead( + self._max_bytes - self._remaining_bytes, self._max_bytes) self._remaining_bytes -= len(data) return data diff --git a/gcloud/streaming/test_buffered_stream.py b/gcloud/streaming/test_buffered_stream.py index 9347ca5349ef..e18a9e6698dd 100644 --- a/gcloud/streaming/test_buffered_stream.py +++ b/gcloud/streaming/test_buffered_stream.py @@ -62,24 +62,22 @@ def test__bytes_remaining_start_zero_shorter_than_buffer(self): def test_read_w_none(self): from io import BytesIO - from gcloud.streaming.exceptions import NotYetImplementedError CONTENT = b'CONTENT GOES HERE' START = 0 BUFSIZE = 4 stream = BytesIO(CONTENT) bufstream = self._makeOne(stream, START, BUFSIZE) - with self.assertRaises(NotYetImplementedError): + with self.assertRaises(ValueError): bufstream.read(None) def test_read_w_negative_size(self): from io import BytesIO - from gcloud.streaming.exceptions import NotYetImplementedError CONTENT = b'CONTENT GOES HERE' START = 0 BUFSIZE = 4 stream = BytesIO(CONTENT) bufstream = self._makeOne(stream, START, BUFSIZE) - with self.assertRaises(NotYetImplementedError): + with self.assertRaises(ValueError): bufstream.read(-2) def test_read_from_start(self): diff --git a/gcloud/streaming/test_stream_slice.py b/gcloud/streaming/test_stream_slice.py index 24776c41fb6f..52ec591d2e55 100644 --- a/gcloud/streaming/test_stream_slice.py +++ b/gcloud/streaming/test_stream_slice.py @@ -40,12 +40,12 @@ def test___nonzero___nonempty(self): def test_read_exhausted(self): from io import BytesIO - from gcloud.streaming.exceptions import StreamExhausted + from six.moves import http_client CONTENT = b'' MAXSIZE = 4 stream = BytesIO(CONTENT) stream_slice = self._makeOne(stream, MAXSIZE) - with self.assertRaises(StreamExhausted): + with self.assertRaises(http_client.IncompleteRead): stream_slice.read() def test_read_implicit_size(self): diff --git a/gcloud/streaming/test_transfer.py b/gcloud/streaming/test_transfer.py index c1e2578598bd..0c04a2347781 100644 --- a/gcloud/streaming/test_transfer.py +++ b/gcloud/streaming/test_transfer.py @@ -181,13 +181,12 @@ def test_ctor_w_total_size(self): def test_from_file_w_existing_file_no_override(self): import os - from gcloud.streaming.exceptions import InvalidUserInputError klass = self._getTargetClass() with _tempdir() as tempdir: filename = os.path.join(tempdir, 'file.out') with open(filename, 'w') as fileobj: fileobj.write('EXISTING FILE') - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): klass.from_file(filename) def test_from_file_w_existing_file_w_override_wo_auto_transfer(self): @@ -815,22 +814,20 @@ def test_ctor_w_kwds(self): self.assertEqual(upload.chunksize, CHUNK_SIZE) def test_from_file_w_nonesuch_file(self): - from gcloud.streaming.exceptions import NotFoundError klass = self._getTargetClass() filename = '~nosuchuser/file.txt' - with self.assertRaises(NotFoundError): + with self.assertRaises(OSError): klass.from_file(filename) def test_from_file_wo_mimetype_w_unguessable_filename(self): import os - from gcloud.streaming.exceptions import InvalidUserInputError klass = self._getTargetClass() CONTENT = b'EXISTING FILE W/ UNGUESSABLE MIMETYPE' with _tempdir() as tempdir: filename = os.path.join(tempdir, 'file.unguessable') with open(filename, 'wb') as fileobj: fileobj.write(CONTENT) - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): klass.from_file(filename) def test_from_file_wo_mimetype_w_guessable_filename(self): @@ -866,10 +863,9 @@ def test_from_file_w_mimetype_w_auto_transfer_w_kwds(self): self.assertEqual(upload.chunksize, CHUNK_SIZE) def test_from_stream_wo_mimetype(self): - from gcloud.streaming.exceptions import InvalidUserInputError klass = self._getTargetClass() stream = _Stream() - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): klass.from_stream(stream, mime_type=None) def test_from_stream_defaults(self): @@ -897,11 +893,10 @@ def test_from_stream_explicit(self): self.assertEqual(upload.chunksize, CHUNK_SIZE) def test_strategy_setter_invalid(self): - from gcloud.streaming.exceptions import UserError upload = self._makeOne(_Stream()) - with self.assertRaises(UserError): + with self.assertRaises(ValueError): upload.strategy = object() - with self.assertRaises(UserError): + with self.assertRaises(ValueError): upload.strategy = 'unknown' def test_strategy_setter_SIMPLE_UPLOAD(self): @@ -996,24 +991,22 @@ def test__set_default_strategy_w_body_w_multipart_w_simple_path(self): self.assertEqual(upload.strategy, SIMPLE_UPLOAD) def test_configure_request_w_total_size_gt_max_size(self): - from gcloud.streaming.exceptions import InvalidUserInputError MAX_SIZE = 1000 config = _UploadConfig() config.max_size = MAX_SIZE request = _Request() url_builder = _Dummy() upload = self._makeOne(_Stream(), total_size=MAX_SIZE + 1) - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): upload.configure_request(config, request, url_builder) def test_configure_request_w_invalid_mimetype(self): - from gcloud.streaming.exceptions import InvalidUserInputError config = _UploadConfig() config.accept = ('text/*',) request = _Request() url_builder = _Dummy() upload = self._makeOne(_Stream()) - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): upload.configure_request(config, request, url_builder) def test_configure_request_w_simple_wo_body(self): @@ -1272,10 +1265,9 @@ def test__get_range_header_w_range(self): self.assertEqual(upload._get_range_header(response), '123') def test_initialize_upload_no_strategy(self): - from gcloud.streaming.exceptions import UserError request = _Request() upload = self._makeOne(_Stream()) - with self.assertRaises(UserError): + with self.assertRaises(ValueError): upload.initialize_upload(request, http=object()) def test_initialize_upload_simple_w_http(self): @@ -1373,10 +1365,9 @@ def test__validate_chunksize_wo__server_chunk_granularity(self): upload._validate_chunksize(123) # no-op def test__validate_chunksize_w__server_chunk_granularity_miss(self): - from gcloud.streaming.exceptions import ConfigurationValueError upload = self._makeOne(_Stream()) upload._server_chunk_granularity = 100 - with self.assertRaises(ConfigurationValueError): + with self.assertRaises(ValueError): upload._validate_chunksize(123) def test__validate_chunksize_w__server_chunk_granularity_hit(self): @@ -1385,20 +1376,18 @@ def test__validate_chunksize_w__server_chunk_granularity_hit(self): upload._validate_chunksize(400) def test_stream_file_w_simple_strategy(self): - from gcloud.streaming.exceptions import InvalidUserInputError from gcloud.streaming.transfer import SIMPLE_UPLOAD upload = self._makeOne(_Stream()) upload.strategy = SIMPLE_UPLOAD - with self.assertRaises(InvalidUserInputError): + with self.assertRaises(ValueError): upload.stream_file() def test_stream_file_w_use_chunks_invalid_chunk_size(self): - from gcloud.streaming.exceptions import ConfigurationValueError from gcloud.streaming.transfer import RESUMABLE_UPLOAD upload = self._makeOne(_Stream(), chunksize=1024) upload.strategy = RESUMABLE_UPLOAD upload._server_chunk_granularity = 100 - with self.assertRaises(ConfigurationValueError): + with self.assertRaises(ValueError): upload.stream_file(use_chunks=True) def test_stream_file_not_initialized(self): diff --git a/gcloud/streaming/test_util.py b/gcloud/streaming/test_util.py index a2cfef48ed99..ea80146ad4cc 100644 --- a/gcloud/streaming/test_util.py +++ b/gcloud/streaming/test_util.py @@ -27,16 +27,14 @@ def _callFUT(self, *args, **kw): return acceptable_mime_type(*args, **kw) def test_pattern_wo_slash(self): - from gcloud.streaming.exceptions import InvalidUserInputError - with self.assertRaises(InvalidUserInputError) as err: + with self.assertRaises(ValueError) as err: self._callFUT(['text/*'], 'BOGUS') self.assertEqual( err.exception.args, ('Invalid MIME type: "BOGUS"',)) def test_accept_pattern_w_semicolon(self): - from gcloud.streaming.exceptions import ConfigurationValueError - with self.assertRaises(ConfigurationValueError) as err: + with self.assertRaises(ValueError) as err: self._callFUT(['text/*;charset=utf-8'], 'text/plain') self.assertEqual( err.exception.args, diff --git a/gcloud/streaming/transfer.py b/gcloud/streaming/transfer.py index 7069d82e458b..2157ad99617f 100644 --- a/gcloud/streaming/transfer.py +++ b/gcloud/streaming/transfer.py @@ -11,13 +11,9 @@ from gcloud.streaming.buffered_stream import BufferedStream from gcloud.streaming.exceptions import CommunicationError -from gcloud.streaming.exceptions import ConfigurationValueError from gcloud.streaming.exceptions import HttpError -from gcloud.streaming.exceptions import InvalidUserInputError -from gcloud.streaming.exceptions import NotFoundError from gcloud.streaming.exceptions import TransferInvalidError from gcloud.streaming.exceptions import TransferRetryError -from gcloud.streaming.exceptions import UserError from gcloud.streaming.http_wrapper import get_http from gcloud.streaming.http_wrapper import handle_http_exceptions from gcloud.streaming.http_wrapper import make_api_request @@ -244,7 +240,7 @@ def from_file(cls, filename, overwrite=False, auto_transfer=True, **kwds): """ path = os.path.expanduser(filename) if os.path.exists(path) and not overwrite: - raise InvalidUserInputError( + raise ValueError( 'File %s exists and overwrite not specified' % path) return cls(open(path, 'wb'), close_stream=True, auto_transfer=auto_transfer, **kwds) @@ -646,12 +642,10 @@ def from_file(cls, filename, mime_type=None, auto_transfer=True, **kwds): through to :meth:`_Transfer.__init__()`. """ path = os.path.expanduser(filename) - if not os.path.exists(path): - raise NotFoundError('Could not find file %s' % path) if not mime_type: mime_type, _ = mimetypes.guess_type(path) if mime_type is None: - raise InvalidUserInputError( + raise ValueError( 'Could not guess mime type for %s' % path) size = os.stat(path).st_size return cls(open(path, 'rb'), mime_type, total_size=size, @@ -679,7 +673,7 @@ def from_stream(cls, stream, mime_type, through to :meth:`_Transfer.__init__()`. """ if mime_type is None: - raise InvalidUserInputError( + raise ValueError( 'No mime_type specified for stream') return cls(stream, mime_type, total_size=total_size, close_stream=False, auto_transfer=auto_transfer, **kwds) @@ -723,11 +717,11 @@ def strategy(self, value): :type value: string (one of :data:`SIMPLE_UPLOAD` or :data:`RESUMABLE_UPLOAD`) - :raises: :exc:`gcloud.streaming.exceptions.UserError` - if value is not one of the two allowed strings. + :raises: :exc:`ValueError` if value is not one of the two allowed + strings. """ if value not in (SIMPLE_UPLOAD, RESUMABLE_UPLOAD): - raise UserError(( + raise ValueError(( 'Invalid value "%s" for upload strategy, must be one of ' '"simple" or "resumable".') % value) self._strategy = value @@ -800,19 +794,18 @@ def configure_request(self, upload_config, http_request, url_builder): 'query_params' attributes. :param url_builder: transfer policy object to be updated - :raises: :exc:`gcloud.streaming.exceptions.InvalidUserInputError` - if the requested upload is too big, or does not have an - acceptable MIME type. + :raises: :exc:`ValueError` if the requested upload is too big, + or does not have an acceptable MIME type. """ # Validate total_size vs. max_size if (self.total_size and upload_config.max_size and self.total_size > upload_config.max_size): - raise InvalidUserInputError( + raise ValueError( 'Upload too big: %s larger than max size %s' % ( self.total_size, upload_config.max_size)) # Validate mime type if not acceptable_mime_type(upload_config.accept, self.mime_type): - raise InvalidUserInputError( + raise ValueError( 'MIME type %s does not match any accepted MIME ranges %s' % ( self.mime_type, upload_config.accept)) @@ -957,11 +950,11 @@ def initialize_upload(self, http_request, http): :type http: :class:`httplib2.Http` (or workalike) :param http: Http instance for this request. - :raises: :exc:`gcloud.streaming.exceptions.UserError` if the instance - has not been configured with a strategy. + :raises: :exc:`ValueError` if the instance has not been configured + with a strategy. """ if self.strategy is None: - raise UserError( + raise ValueError( 'No upload strategy set; did you call configure_request?') if self.strategy != RESUMABLE_UPLOAD: return @@ -1002,15 +995,14 @@ def _validate_chunksize(self, chunksize=None): :type chunksize: integer or None :param chunksize: the chunk size to be tested. - :raises: :exc:`gcloud.streaming.exceptions.ConfigurationValueError` - if ``chunksize`` is not a multiple of the server-specified - granulariy. + :raises: :exc:`ValueError` if ``chunksize`` is not a multiple + of the server-specified granulariy. """ if self._server_chunk_granularity is None: return chunksize = chunksize or self.chunksize if chunksize % self._server_chunk_granularity: - raise ConfigurationValueError( + raise ValueError( 'Server requires chunksize to be a multiple of %d', self._server_chunk_granularity) @@ -1022,7 +1014,7 @@ def stream_file(self, use_chunks=True): Otherwise, send it in chunks. """ if self.strategy != RESUMABLE_UPLOAD: - raise InvalidUserInputError( + raise ValueError( 'Cannot stream non-resumable upload') # final_response is set if we resumed an already-completed upload. response = self._final_response diff --git a/gcloud/streaming/util.py b/gcloud/streaming/util.py index b3d5b979dc4f..18f8c9d5a349 100644 --- a/gcloud/streaming/util.py +++ b/gcloud/streaming/util.py @@ -2,9 +2,6 @@ import random -from gcloud.streaming.exceptions import ConfigurationValueError -from gcloud.streaming.exceptions import InvalidUserInputError - def calculate_wait_for_retry(retry_attempt, max_wait=60): """Calculate the amount of time to wait before a retry attempt. @@ -48,11 +45,11 @@ def acceptable_mime_type(accept_patterns, mime_type): patterns, else False. """ if '/' not in mime_type: - raise InvalidUserInputError( + raise ValueError( 'Invalid MIME type: "%s"' % mime_type) unsupported_patterns = [p for p in accept_patterns if ';' in p] if unsupported_patterns: - raise ConfigurationValueError( + raise ValueError( 'MIME patterns with parameter unsupported: "%s"' % ', '.join( unsupported_patterns))