Skip to content

Commit

Permalink
fix!: drop Python 2.7 support (#229)
Browse files Browse the repository at this point in the history
Drop use of 'six' wrapper

Drop 'u"' prefixes

Release-As: 2.0.0b1

Closes #228.
  • Loading branch information
tseaver committed Aug 2, 2021
1 parent 289a0c6 commit af10d4b
Show file tree
Hide file tree
Showing 40 changed files with 1,643 additions and 1,644 deletions.
14 changes: 9 additions & 5 deletions README.rst
Expand Up @@ -16,15 +16,19 @@ support at `google._async_resumable_media`.

Supported Python Versions
-------------------------
Python >= 3.5
Python >= 3.6

Deprecated Python Versions
--------------------------
Python == 2.7. Python 2.7 support will be removed on January 1, 2020.
Unsupported Python Versions
---------------------------

Python == 2.7, Python == 3.5.

The last version of this library compatible with Python 2.7 and 3.5 is
`google-resumable-media==1.3.3`.

License
-------

Apache 2.0 - See `the LICENSE`_ for more information.

.. _the LICENSE: https://github.com/googleapis/google-resumable-media-python/blob/master/LICENSE
.. _the LICENSE: https://github.com/googleapis/google-resumable-media-python/blob/master/LICENSE
12 changes: 6 additions & 6 deletions google/_async_resumable_media/__init__.py
Expand Up @@ -52,10 +52,10 @@


__all__ = [
u"DataCorruption",
u"InvalidResponse",
u"PERMANENT_REDIRECT",
u"RetryStrategy",
u"TOO_MANY_REQUESTS",
u"UPLOAD_CHUNK_SIZE",
"DataCorruption",
"InvalidResponse",
"PERMANENT_REDIRECT",
"RetryStrategy",
"TOO_MANY_REQUESTS",
"UPLOAD_CHUNK_SIZE",
]
61 changes: 29 additions & 32 deletions google/_async_resumable_media/_download.py
Expand Up @@ -14,12 +14,9 @@

"""Virtual bases classes for downloading media from Google APIs."""


import http.client
import re

from six.moves import http_client


from google._async_resumable_media import _helpers
from google.resumable_media import common

Expand All @@ -28,9 +25,9 @@
r"bytes (?P<start_byte>\d+)-(?P<end_byte>\d+)/(?P<total_bytes>\d+)",
flags=re.IGNORECASE,
)
_ACCEPTABLE_STATUS_CODES = (http_client.OK, http_client.PARTIAL_CONTENT)
_GET = u"GET"
_ZERO_CONTENT_RANGE_HEADER = u"bytes */0"
_ACCEPTABLE_STATUS_CODES = (http.client.OK, http.client.PARTIAL_CONTENT)
_GET = "GET"
_ZERO_CONTENT_RANGE_HEADER = "bytes */0"


class DownloadBase(object):
Expand Down Expand Up @@ -79,7 +76,7 @@ def _get_status_code(response):
Raises:
NotImplementedError: Always, since virtual.
"""
raise NotImplementedError(u"This implementation is virtual.")
raise NotImplementedError("This implementation is virtual.")

@staticmethod
def _get_headers(response):
Expand All @@ -91,7 +88,7 @@ def _get_headers(response):
Raises:
NotImplementedError: Always, since virtual.
"""
raise NotImplementedError(u"This implementation is virtual.")
raise NotImplementedError("This implementation is virtual.")

@staticmethod
def _get_body(response):
Expand All @@ -103,7 +100,7 @@ def _get_body(response):
Raises:
NotImplementedError: Always, since virtual.
"""
raise NotImplementedError(u"This implementation is virtual.")
raise NotImplementedError("This implementation is virtual.")


class Download(DownloadBase):
Expand Down Expand Up @@ -164,7 +161,7 @@ def _prepare_request(self):
.. _sans-I/O: https://sans-io.readthedocs.io/
"""
if self.finished:
raise ValueError(u"A download can only be used once.")
raise ValueError("A download can only be used once.")

add_bytes_range(self.start, self.end, self._headers)
return _GET, self.media_url, None, self._headers
Expand Down Expand Up @@ -205,7 +202,7 @@ def consume(self, transport, timeout=None):
Raises:
NotImplementedError: Always, since virtual.
"""
raise NotImplementedError(u"This implementation is virtual.")
raise NotImplementedError("This implementation is virtual.")


class ChunkedDownload(DownloadBase):
Expand Down Expand Up @@ -239,7 +236,7 @@ class ChunkedDownload(DownloadBase):
def __init__(self, media_url, chunk_size, stream, start=0, end=None, headers=None):
if start < 0:
raise ValueError(
u"On a chunked download the starting " u"value cannot be negative."
"On a chunked download the starting " "value cannot be negative."
)
super(ChunkedDownload, self).__init__(
media_url, stream=stream, start=start, end=end, headers=headers
Expand Down Expand Up @@ -312,9 +309,9 @@ def _prepare_request(self):
.. _sans-I/O: https://sans-io.readthedocs.io/
"""
if self.finished:
raise ValueError(u"Download has finished.")
raise ValueError("Download has finished.")
if self.invalid:
raise ValueError(u"Download is invalid and cannot be re-used.")
raise ValueError("Download is invalid and cannot be re-used.")

curr_start, curr_end = self._get_byte_range()
add_bytes_range(curr_start, curr_end, self._headers)
Expand Down Expand Up @@ -382,12 +379,12 @@ async def _process_response(self, response):
response, self._get_headers, callback=self._make_invalid
)

transfer_encoding = headers.get(u"transfer-encoding")
transfer_encoding = headers.get("transfer-encoding")

if transfer_encoding is None:
content_length = _helpers.header_required(
response,
u"content-length",
"content-length",
self._get_headers,
callback=self._make_invalid,
)
Expand All @@ -397,10 +394,10 @@ async def _process_response(self, response):
self._make_invalid()
raise common.InvalidResponse(
response,
u"Response is different size than content-length",
u"Expected",
"Response is different size than content-length",
"Expected",
num_bytes,
u"Received",
"Received",
len(response_body),
)
else:
Expand Down Expand Up @@ -434,7 +431,7 @@ def consume_next_chunk(self, transport, timeout=None):
Raises:
NotImplementedError: Always, since virtual.
"""
raise NotImplementedError(u"This implementation is virtual.")
raise NotImplementedError("This implementation is virtual.")


def add_bytes_range(start, end, headers):
Expand Down Expand Up @@ -474,18 +471,18 @@ def add_bytes_range(start, end, headers):
return
else:
# NOTE: This assumes ``end`` is non-negative.
bytes_range = u"0-{:d}".format(end)
bytes_range = "0-{:d}".format(end)
else:
if end is None:
if start < 0:
bytes_range = u"{:d}".format(start)
bytes_range = "{:d}".format(start)
else:
bytes_range = u"{:d}-".format(start)
bytes_range = "{:d}-".format(start)
else:
# NOTE: This is invalid if ``start < 0``.
bytes_range = u"{:d}-{:d}".format(start, end)
bytes_range = "{:d}-{:d}".format(start, end)

headers[_helpers.RANGE_HEADER] = u"bytes=" + bytes_range
headers[_helpers.RANGE_HEADER] = "bytes=" + bytes_range


def get_range_info(response, get_headers, callback=_helpers.do_nothing):
Expand Down Expand Up @@ -514,15 +511,15 @@ def get_range_info(response, get_headers, callback=_helpers.do_nothing):
callback()
raise common.InvalidResponse(
response,
u"Unexpected content-range header",
"Unexpected content-range header",
content_range,
u'Expected to be of the form "bytes {start}-{end}/{total}"',
'Expected to be of the form "bytes {start}-{end}/{total}"',
)

return (
int(match.group(u"start_byte")),
int(match.group(u"end_byte")),
int(match.group(u"total_bytes")),
int(match.group("start_byte")),
int(match.group("end_byte")),
int(match.group("total_bytes")),
)


Expand All @@ -541,7 +538,7 @@ def _check_for_zero_content_range(response, get_status_code, get_headers):
Returns:
bool: True if content range total bytes is zero, false otherwise.
"""
if get_status_code(response) == http_client.REQUESTED_RANGE_NOT_SATISFIABLE:
if get_status_code(response) == http.client.REQUESTED_RANGE_NOT_SATISFIABLE:
content_range = _helpers.header_required(
response,
_helpers.CONTENT_RANGE_HEADER,
Expand Down
14 changes: 7 additions & 7 deletions google/_async_resumable_media/_helpers.py
Expand Up @@ -22,16 +22,16 @@
from google.resumable_media import common


RANGE_HEADER = u"range"
CONTENT_RANGE_HEADER = u"content-range"
RANGE_HEADER = "range"
CONTENT_RANGE_HEADER = "content-range"

_SLOW_CRC32C_WARNING = (
"Currently using crcmod in pure python form. This is a slow "
"implementation. Python 3 has a faster implementation, `google-crc32c`, "
"which will be used if it is installed."
)
_HASH_HEADER = u"x-goog-hash"
_MISSING_CHECKSUM = u"""\
_HASH_HEADER = "x-goog-hash"
_MISSING_CHECKSUM = """\
No {checksum_type} checksum was returned from the service while downloading {}
(which happens for composite objects), so client-side content integrity
checking is not being performed."""
Expand Down Expand Up @@ -65,7 +65,7 @@ def header_required(response, name, get_headers, callback=do_nothing):
if name not in headers:
callback()
raise common.InvalidResponse(
response, u"Response headers must contain header", name
response, "Response headers must contain header", name
)

return headers[name]
Expand Down Expand Up @@ -94,9 +94,9 @@ def require_status_code(response, status_codes, get_status_code, callback=do_not
callback()
raise common.InvalidResponse(
response,
u"Request failed with status code",
"Request failed with status code",
status_code,
u"Expected one of",
"Expected one of",
*status_codes
)
return status_code
Expand Down

0 comments on commit af10d4b

Please sign in to comment.