fix: add back python 2.7 for gcloud usage only (#892)
* fix: add back python 2.7 for gcloud
* fix: fix setup and tests
* fix: add enum34 for python 2.7
* fix: add app engine app and fix noxfile
* fix: move test_app_engine.py
* fix: fix downscoped
* fix: fix downscoped
* fix: remove py2 from classifiers
diff --git a/google/auth/_cloud_sdk.py b/google/auth/_cloud_sdk.py
index 1f13ad4..40e6aec 100644
--- a/google/auth/_cloud_sdk.py
+++ b/google/auth/_cloud_sdk.py
@@ -18,6 +18,8 @@
import os
import subprocess
+import six
+
from google.auth import environment_vars
from google.auth import exceptions
@@ -154,4 +156,4 @@
new_exc = exceptions.UserAccessTokenError(
"Failed to obtain access token", caught_exc
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
diff --git a/google/auth/_credentials_async.py b/google/auth/_credentials_async.py
index 760758d..d4d4e2c 100644
--- a/google/auth/_credentials_async.py
+++ b/google/auth/_credentials_async.py
@@ -18,10 +18,13 @@
import abc
import inspect
+import six
+
from google.auth import credentials
-class Credentials(credentials.Credentials, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Credentials(credentials.Credentials):
"""Async inherited credentials class from google.auth.credentials.
The added functionality is the before_request call which requires
async/await syntax.
@@ -81,7 +84,8 @@
"""
-class ReadOnlyScoped(credentials.ReadOnlyScoped, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class ReadOnlyScoped(credentials.ReadOnlyScoped):
"""Interface for credentials whose scopes can be queried.
OAuth 2.0-based credentials allow limiting access using scopes as described
@@ -167,5 +171,6 @@
return credentials
-class Signing(credentials.Signing, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Signing(credentials.Signing):
"""Interface for credentials that can cryptographically sign messages."""
diff --git a/google/auth/_default.py b/google/auth/_default.py
index 8b0573b..4ae7c8c 100644
--- a/google/auth/_default.py
+++ b/google/auth/_default.py
@@ -23,6 +23,8 @@
import os
import warnings
+import six
+
from google.auth import environment_vars
from google.auth import exceptions
import google.auth.transport._http_client
@@ -116,7 +118,7 @@
new_exc = exceptions.DefaultCredentialsError(
"File {} is not a valid json file.".format(filename), caught_exc
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
# The type key should indicate that the file is either a service account
# credentials file or an authorized user credentials file.
@@ -132,7 +134,7 @@
except ValueError as caught_exc:
msg = "Failed to load authorized user credentials from {}".format(filename)
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
if quota_project_id:
credentials = credentials.with_quota_project(quota_project_id)
if not credentials.quota_project_id:
@@ -149,7 +151,7 @@
except ValueError as caught_exc:
msg = "Failed to load service account credentials from {}".format(filename)
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
if quota_project_id:
credentials = credentials.with_quota_project(quota_project_id)
return credentials, info.get("project_id")
diff --git a/google/auth/_default_async.py b/google/auth/_default_async.py
index 3fa125b..fb277c5 100644
--- a/google/auth/_default_async.py
+++ b/google/auth/_default_async.py
@@ -21,6 +21,8 @@
import json
import os
+import six
+
from google.auth import _default
from google.auth import environment_vars
from google.auth import exceptions
@@ -61,7 +63,7 @@
new_exc = exceptions.DefaultCredentialsError(
"File {} is not a valid json file.".format(filename), caught_exc
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
# The type key should indicate that the file is either a service account
# credentials file or an authorized user credentials file.
@@ -77,7 +79,7 @@
except ValueError as caught_exc:
msg = "Failed to load authorized user credentials from {}".format(filename)
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
if quota_project_id:
credentials = credentials.with_quota_project(quota_project_id)
if not credentials.quota_project_id:
@@ -94,7 +96,7 @@
except ValueError as caught_exc:
msg = "Failed to load service account credentials from {}".format(filename)
new_exc = exceptions.DefaultCredentialsError(msg, caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
return credentials, info.get("project_id")
else:
diff --git a/google/auth/_helpers.py b/google/auth/_helpers.py
index 55adf5b..b239fcd 100644
--- a/google/auth/_helpers.py
+++ b/google/auth/_helpers.py
@@ -17,7 +17,9 @@
import base64
import calendar
import datetime
-import urllib
+
+import six
+from six.moves import urllib
# Token server doesn't provide a new a token when doing refresh unless the
@@ -85,6 +87,9 @@
def to_bytes(value, encoding="utf-8"):
"""Converts a string value to bytes, if necessary.
+ Unfortunately, ``six.b`` is insufficient for this task since in
+ Python 2 because it does not modify ``unicode`` objects.
+
Args:
value (Union[str, bytes]): The value to be converted.
encoding (str): The encoding to use to convert unicode to bytes.
@@ -97,8 +102,8 @@
Raises:
ValueError: If the value could not be converted to bytes.
"""
- result = value.encode(encoding) if isinstance(value, str) else value
- if isinstance(result, bytes):
+ result = value.encode(encoding) if isinstance(value, six.text_type) else value
+ if isinstance(result, six.binary_type):
return result
else:
raise ValueError("{0!r} could not be converted to bytes".format(value))
@@ -117,8 +122,8 @@
Raises:
ValueError: If the value could not be converted to unicode.
"""
- result = value.decode("utf-8") if isinstance(value, bytes) else value
- if isinstance(result, str):
+ result = value.decode("utf-8") if isinstance(value, six.binary_type) else value
+ if isinstance(result, six.text_type):
return result
else:
raise ValueError("{0!r} could not be converted to unicode".format(value))
@@ -160,7 +165,7 @@
query_params.update(params)
# Remove any values specified in remove.
query_params = {
- key: value for key, value in query_params.items() if key not in remove
+ key: value for key, value in six.iteritems(query_params) if key not in remove
}
# Re-encoded the query string.
new_query = urllib.parse.urlencode(query_params, doseq=True)
diff --git a/google/auth/_oauth2client.py b/google/auth/_oauth2client.py
index 3512e1d..95a9876 100644
--- a/google/auth/_oauth2client.py
+++ b/google/auth/_oauth2client.py
@@ -21,6 +21,8 @@
from __future__ import absolute_import
+import six
+
from google.auth import _helpers
import google.auth.app_engine
import google.auth.compute_engine
@@ -32,7 +34,7 @@
import oauth2client.contrib.gce
import oauth2client.service_account
except ImportError as caught_exc:
- raise ImportError("oauth2client is not installed.") from caught_exc
+ six.raise_from(ImportError("oauth2client is not installed."), caught_exc)
try:
import oauth2client.contrib.appengine # pytype: disable=import-error
@@ -164,4 +166,4 @@
return _CLASS_CONVERSION_MAP[credentials_class](credentials)
except KeyError as caught_exc:
new_exc = ValueError(_CONVERT_ERROR_TMPL.format(credentials_class))
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
diff --git a/google/auth/_service_account_info.py b/google/auth/_service_account_info.py
index 54a40e9..3d340c7 100644
--- a/google/auth/_service_account_info.py
+++ b/google/auth/_service_account_info.py
@@ -17,6 +17,8 @@
import io
import json
+import six
+
from google.auth import crypt
@@ -41,7 +43,7 @@
"""
keys_needed = set(require if require is not None else [])
- missing = keys_needed.difference(data)
+ missing = keys_needed.difference(six.iterkeys(data))
if missing:
raise ValueError(
diff --git a/google/auth/aws.py b/google/auth/aws.py
index c8deee7..925b1dd 100644
--- a/google/auth/aws.py
+++ b/google/auth/aws.py
@@ -39,13 +39,20 @@
import hashlib
import hmac
-import http.client
import io
import json
import os
+import posixpath
import re
-import urllib
-from urllib.parse import urljoin
+
+try:
+ from urllib.parse import urljoin
+# Python 2.7 compatibility
+except ImportError: # pragma: NO COVER
+ from urlparse import urljoin
+
+from six.moves import http_client
+from six.moves import urllib
from google.auth import _helpers
from google.auth import environment_vars
@@ -116,7 +123,9 @@
# Normalize the URL path. This is needed for the canonical_uri.
# os.path.normpath can't be used since it normalizes "/" paths
# to "\\" in Windows OS.
- normalized_uri = urllib.parse.urlparse(urljoin(url, uri.path))
+ normalized_uri = urllib.parse.urlparse(
+ urljoin(url, posixpath.normpath(uri.path))
+ )
# Validate provided URL.
if not uri.hostname or uri.scheme != "https":
raise ValueError("Invalid AWS service URL")
@@ -631,7 +640,7 @@
else response.data
)
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
raise exceptions.RefreshError(
"Unable to retrieve AWS security credentials", response_body
)
@@ -670,7 +679,7 @@
else response.data
)
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
raise exceptions.RefreshError(
"Unable to retrieve AWS role name", response_body
)
diff --git a/google/auth/compute_engine/_metadata.py b/google/auth/compute_engine/_metadata.py
index af0d849..9db7bea 100644
--- a/google/auth/compute_engine/_metadata.py
+++ b/google/auth/compute_engine/_metadata.py
@@ -18,11 +18,13 @@
"""
import datetime
-import http.client
import json
import logging
import os
-from urllib import parse as urlparse
+
+import six
+from six.moves import http_client
+from six.moves.urllib import parse as urlparse
from google.auth import _helpers
from google.auth import environment_vars
@@ -89,7 +91,7 @@
metadata_flavor = response.headers.get(_METADATA_FLAVOR_HEADER)
return (
- response.status == http.client.OK
+ response.status == http_client.OK
and metadata_flavor == _METADATA_FLAVOR_VALUE
)
@@ -163,7 +165,7 @@
"metadata service. Compute Engine Metadata server unavailable".format(url)
)
- if response.status == http.client.OK:
+ if response.status == http_client.OK:
content = _helpers.from_bytes(response.data)
if response.headers["content-type"] == "application/json":
try:
@@ -173,7 +175,7 @@
"Received invalid JSON from the Google Compute Engine"
"metadata service: {:.20}".format(content)
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
else:
return content
else:
diff --git a/google/auth/compute_engine/credentials.py b/google/auth/compute_engine/credentials.py
index cb4e0f0..b39ac50 100644
--- a/google/auth/compute_engine/credentials.py
+++ b/google/auth/compute_engine/credentials.py
@@ -21,6 +21,8 @@
import datetime
+import six
+
from google.auth import _helpers
from google.auth import credentials
from google.auth import exceptions
@@ -112,7 +114,7 @@
)
except exceptions.TransportError as caught_exc:
new_exc = exceptions.RefreshError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
@property
def service_account_email(self):
@@ -350,7 +352,7 @@
id_token = _metadata.get(request, path, params=params)
except exceptions.TransportError as caught_exc:
new_exc = exceptions.RefreshError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
_, payload, _, _ = jwt._unverified_decode(id_token)
return id_token, datetime.datetime.fromtimestamp(payload["exp"])
diff --git a/google/auth/credentials.py b/google/auth/credentials.py
index 8d9974c..ec21a27 100644
--- a/google/auth/credentials.py
+++ b/google/auth/credentials.py
@@ -17,10 +17,13 @@
import abc
+import six
+
from google.auth import _helpers
-class Credentials(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Credentials(object):
"""Base class for all credentials.
All credentials have a :attr:`token` that is used for authentication and
@@ -184,7 +187,8 @@
"""Anonymous credentials do nothing to the request."""
-class ReadOnlyScoped(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class ReadOnlyScoped(object):
"""Interface for credentials whose scopes can be queried.
OAuth 2.0-based credentials allow limiting access using scopes as described
@@ -325,7 +329,8 @@
return credentials
-class Signing(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Signing(object):
"""Interface for credentials that can cryptographically sign messages."""
@abc.abstractmethod
diff --git a/google/auth/crypt/__init__.py b/google/auth/crypt/__init__.py
index 97e9d81..15ac950 100644
--- a/google/auth/crypt/__init__.py
+++ b/google/auth/crypt/__init__.py
@@ -37,6 +37,8 @@
version is at least 1.4.0.
"""
+import six
+
from google.auth.crypt import base
from google.auth.crypt import rsa
@@ -88,7 +90,7 @@
Returns:
bool: True if the signature is valid, otherwise False.
"""
- if isinstance(certs, (str, bytes)):
+ if isinstance(certs, (six.text_type, six.binary_type)):
certs = [certs]
for cert in certs:
diff --git a/google/auth/crypt/_python_rsa.py b/google/auth/crypt/_python_rsa.py
index 1c4a9da..ec30dd0 100644
--- a/google/auth/crypt/_python_rsa.py
+++ b/google/auth/crypt/_python_rsa.py
@@ -21,13 +21,12 @@
from __future__ import absolute_import
-import io
-
from pyasn1.codec.der import decoder
from pyasn1_modules import pem
from pyasn1_modules.rfc2459 import Certificate
from pyasn1_modules.rfc5208 import PrivateKeyInfo
import rsa
+import six
from google.auth import _helpers
from google.auth.crypt import base
@@ -53,9 +52,9 @@
"""
num_bits = len(bit_list)
byte_vals = bytearray()
- for start in range(0, num_bits, 8):
+ for start in six.moves.xrange(0, num_bits, 8):
curr_bits = bit_list[start : start + 8]
- char_val = sum(val * digit for val, digit in zip(_POW2, curr_bits))
+ char_val = sum(val * digit for val, digit in six.moves.zip(_POW2, curr_bits))
byte_vals.append(char_val)
return bytes(byte_vals)
@@ -153,7 +152,7 @@
"""
key = _helpers.from_bytes(key) # PEM expects str in Python 3
marker_id, key_bytes = pem.readPemBlocksFromFile(
- io.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER
+ six.StringIO(key), _PKCS1_MARKER, _PKCS8_MARKER
)
# Key is in pkcs1 format.
diff --git a/google/auth/crypt/base.py b/google/auth/crypt/base.py
index 0bda9c3..c98d5bf 100644
--- a/google/auth/crypt/base.py
+++ b/google/auth/crypt/base.py
@@ -18,12 +18,15 @@
import io
import json
+import six
+
_JSON_FILE_PRIVATE_KEY = "private_key"
_JSON_FILE_PRIVATE_KEY_ID = "private_key_id"
-class Verifier(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Verifier(object):
"""Abstract base class for crytographic signature verifiers."""
@abc.abstractmethod
@@ -43,7 +46,8 @@
raise NotImplementedError("Verify must be implemented")
-class Signer(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Signer(object):
"""Abstract base class for cryptographic signers."""
@abc.abstractproperty
@@ -66,7 +70,8 @@
raise NotImplementedError("Sign must be implemented")
-class FromServiceAccountMixin(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class FromServiceAccountMixin(object):
"""Mix-in to enable factory constructors for a Signer."""
@abc.abstractmethod
diff --git a/google/auth/crypt/es256.py b/google/auth/crypt/es256.py
index 71dcbfc..c6d6176 100644
--- a/google/auth/crypt/es256.py
+++ b/google/auth/crypt/es256.py
@@ -15,6 +15,7 @@
"""ECDSA (ES256) verifier and signer that use the ``cryptography`` library.
"""
+from cryptography import utils
import cryptography.exceptions
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import hashes
@@ -52,8 +53,8 @@
sig_bytes = _helpers.to_bytes(signature)
if len(sig_bytes) != 64:
return False
- r = int.from_bytes(sig_bytes[:32], byteorder="big")
- s = int.from_bytes(sig_bytes[32:], byteorder="big")
+ r = utils.int_from_bytes(sig_bytes[:32], byteorder="big")
+ s = utils.int_from_bytes(sig_bytes[32:], byteorder="big")
asn1_sig = encode_dss_signature(r, s)
message = _helpers.to_bytes(message)
@@ -120,7 +121,7 @@
# Convert ASN1 encoded signature to (r||s) raw signature.
(r, s) = decode_dss_signature(asn1_signature)
- return r.to_bytes(32, byteorder="big") + s.to_bytes(32, byteorder="big")
+ return utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32)
@classmethod
def from_string(cls, key, key_id=None):
diff --git a/google/auth/downscoped.py b/google/auth/downscoped.py
index 96a4e65..a1d7b6e 100644
--- a/google/auth/downscoped.py
+++ b/google/auth/downscoped.py
@@ -50,6 +50,8 @@
import datetime
+import six
+
from google.auth import _helpers
from google.auth import credentials
from google.oauth2 import sts
@@ -221,7 +223,7 @@
Raises:
TypeError: If the value is not a string.
"""
- if not isinstance(value, str):
+ if not isinstance(value, six.string_types):
raise TypeError("The provided available_resource is not a string.")
self._available_resource = value
@@ -247,7 +249,7 @@
ValueError: If the value is not valid.
"""
for available_permission in value:
- if not isinstance(available_permission, str):
+ if not isinstance(available_permission, six.string_types):
raise TypeError(
"Provided available_permissions are not a list of strings."
)
@@ -350,7 +352,7 @@
Raises:
TypeError: If the value is not of type string.
"""
- if not isinstance(value, str):
+ if not isinstance(value, six.string_types):
raise TypeError("The provided expression is not a string.")
self._expression = value
@@ -373,7 +375,7 @@
Raises:
TypeError: If the value is not of type string or None.
"""
- if not isinstance(value, str) and value is not None:
+ if not isinstance(value, six.string_types) and value is not None:
raise TypeError("The provided title is not a string or None.")
self._title = value
@@ -396,7 +398,7 @@
Raises:
TypeError: If the value is not of type string or None.
"""
- if not isinstance(value, str) and value is not None:
+ if not isinstance(value, six.string_types) and value is not None:
raise TypeError("The provided description is not a string or None.")
self._description = value
diff --git a/google/auth/external_account.py b/google/auth/external_account.py
index f588981..cbd0baf 100644
--- a/google/auth/external_account.py
+++ b/google/auth/external_account.py
@@ -33,6 +33,8 @@
import json
import re
+import six
+
from google.auth import _helpers
from google.auth import credentials
from google.auth import exceptions
@@ -50,9 +52,8 @@
_CLOUD_RESOURCE_MANAGER = "https://cloudresourcemanager.googleapis.com/v1/projects/"
-class Credentials(
- credentials.Scoped, credentials.CredentialsWithQuotaProject, metaclass=abc.ABCMeta
-):
+@six.add_metaclass(abc.ABCMeta)
+class Credentials(credentials.Scoped, credentials.CredentialsWithQuotaProject):
"""Base class for all external account credentials.
This is used to instantiate Credentials for exchanging external account
diff --git a/google/auth/iam.py b/google/auth/iam.py
index 277f4b7..5d63dc5 100644
--- a/google/auth/iam.py
+++ b/google/auth/iam.py
@@ -20,9 +20,10 @@
"""
import base64
-import http.client
import json
+from six.moves import http_client
+
from google.auth import _helpers
from google.auth import crypt
from google.auth import exceptions
@@ -76,7 +77,7 @@
self._credentials.before_request(self._request, method, url, headers)
response = self._request(url=url, method=method, body=body, headers=headers)
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
raise exceptions.TransportError(
"Error calling the IAM signBlob API: {}".format(response.data)
)
diff --git a/google/auth/identity_pool.py b/google/auth/identity_pool.py
index 901fd62..fb33d77 100644
--- a/google/auth/identity_pool.py
+++ b/google/auth/identity_pool.py
@@ -33,7 +33,11 @@
access tokens.
"""
-from collections.abc import Mapping
+try:
+ from collections.abc import Mapping
+# Python 2.7 compatibility
+except ImportError: # pragma: NO COVER
+ from collections import Mapping
import io
import json
import os
diff --git a/google/auth/impersonated_credentials.py b/google/auth/impersonated_credentials.py
index 2704bfd..b8a6c49 100644
--- a/google/auth/impersonated_credentials.py
+++ b/google/auth/impersonated_credentials.py
@@ -28,9 +28,11 @@
import base64
import copy
from datetime import datetime
-import http.client
import json
+import six
+from six.moves import http_client
+
from google.auth import _helpers
from google.auth import credentials
from google.auth import exceptions
@@ -98,7 +100,7 @@
else response.data
)
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
exceptions.RefreshError(_REFRESH_ERROR, response_body)
try:
@@ -115,7 +117,7 @@
),
response_body,
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
class Credentials(credentials.CredentialsWithQuotaProject, credentials.Signing):
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index bb9ffae..d565595 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -40,13 +40,18 @@
"""
-from collections.abc import Mapping
+try:
+ from collections.abc import Mapping
+# Python 2.7 compatibility
+except ImportError: # pragma: NO COVER
+ from collections import Mapping
import copy
import datetime
import json
-import urllib
import cachetools
+import six
+from six.moves import urllib
from google.auth import _helpers
from google.auth import _service_account_info
@@ -118,7 +123,7 @@
return json.loads(section_bytes.decode("utf-8"))
except ValueError as caught_exc:
new_exc = ValueError("Can't parse segment: {0}".format(section_bytes))
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
def _unverified_decode(token):
@@ -244,16 +249,19 @@
try:
verifier_cls = _ALGORITHM_TO_VERIFIER_CLASS[key_alg]
- except KeyError as caught_exc:
+ except KeyError as exc:
if key_alg in _CRYPTOGRAPHY_BASED_ALGORITHMS:
- msg = (
- "The key algorithm {} requires the cryptography package "
- "to be installed."
+ six.raise_from(
+ ValueError(
+ "The key algorithm {} requires the cryptography package "
+ "to be installed.".format(key_alg)
+ ),
+ exc,
)
else:
- msg = "Unsupported signature algorithm {}"
- new_exc = ValueError(msg.format(key_alg))
- raise new_exc from caught_exc
+ six.raise_from(
+ ValueError("Unsupported signature algorithm {}".format(key_alg)), exc
+ )
# If certs is specified as a dictionary of key IDs to certificates, then
# use the certificate identified by the key ID in the token header.
diff --git a/google/auth/transport/__init__.py b/google/auth/transport/__init__.py
index d1b035d..374e7b4 100644
--- a/google/auth/transport/__init__.py
+++ b/google/auth/transport/__init__.py
@@ -25,9 +25,11 @@
"""
import abc
-import http.client
-DEFAULT_REFRESH_STATUS_CODES = (http.client.UNAUTHORIZED,)
+import six
+from six.moves import http_client
+
+DEFAULT_REFRESH_STATUS_CODES = (http_client.UNAUTHORIZED,)
"""Sequence[int]: Which HTTP status code indicate that credentials should be
refreshed and a request should be retried.
"""
@@ -36,7 +38,8 @@
"""int: How many times to refresh the credentials and retry a request."""
-class Response(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Response(object):
"""HTTP Response data."""
@abc.abstractproperty
@@ -55,7 +58,8 @@
raise NotImplementedError("data must be implemented.")
-class Request(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class Request(object):
"""Interface for a callable that makes HTTP requests.
Specific transport implementations should provide an implementation of
diff --git a/google/auth/transport/_aiohttp_requests.py b/google/auth/transport/_aiohttp_requests.py
index ee94043..ab7dfef 100644
--- a/google/auth/transport/_aiohttp_requests.py
+++ b/google/auth/transport/_aiohttp_requests.py
@@ -24,6 +24,7 @@
import functools
import aiohttp
+import six
import urllib3
from google.auth import exceptions
@@ -190,11 +191,11 @@
except aiohttp.ClientError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
except asyncio.TimeoutError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
class AuthorizedSession(aiohttp.ClientSession):
diff --git a/google/auth/transport/_http_client.py b/google/auth/transport/_http_client.py
index 679087f..c153763 100644
--- a/google/auth/transport/_http_client.py
+++ b/google/auth/transport/_http_client.py
@@ -14,10 +14,12 @@
"""Transport adapter for http.client, for internal use only."""
-import http.client
import logging
import socket
-import urllib
+
+import six
+from six.moves import http_client
+from six.moves import urllib
from google.auth import exceptions
from google.auth import transport
@@ -96,7 +98,7 @@
"was specified".format(parts.scheme)
)
- connection = http.client.HTTPConnection(parts.netloc, timeout=timeout)
+ connection = http_client.HTTPConnection(parts.netloc, timeout=timeout)
try:
_LOGGER.debug("Making request: %s %s", method, url)
@@ -105,9 +107,9 @@
response = connection.getresponse()
return Response(response)
- except (http.client.HTTPException, socket.error) as caught_exc:
+ except (http_client.HTTPException, socket.error) as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
finally:
connection.close()
diff --git a/google/auth/transport/_mtls_helper.py b/google/auth/transport/_mtls_helper.py
index 1b9b9c2..4dccb10 100644
--- a/google/auth/transport/_mtls_helper.py
+++ b/google/auth/transport/_mtls_helper.py
@@ -20,6 +20,8 @@
import re
import subprocess
+import six
+
from google.auth import exceptions
CONTEXT_AWARE_METADATA_PATH = "~/.secureConnect/context_aware_metadata.json"
@@ -80,7 +82,7 @@
metadata = json.load(f)
except ValueError as caught_exc:
new_exc = exceptions.ClientCertError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
return metadata
@@ -108,7 +110,7 @@
stdout, stderr = process.communicate()
except OSError as caught_exc:
new_exc = exceptions.ClientCertError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
# Check cert provider command execution error.
if process.returncode != 0:
diff --git a/google/auth/transport/grpc.py b/google/auth/transport/grpc.py
index 160dc94..c47cb3d 100644
--- a/google/auth/transport/grpc.py
+++ b/google/auth/transport/grpc.py
@@ -19,6 +19,8 @@
import logging
import os
+import six
+
from google.auth import environment_vars
from google.auth import exceptions
from google.auth.transport import _mtls_helper
@@ -27,11 +29,13 @@
try:
import grpc
except ImportError as caught_exc: # pragma: NO COVER
- new_exc = ImportError(
- "gRPC is not installed, please install the grpcio package "
- "to use the gRPC transport."
+ six.raise_from(
+ ImportError(
+ "gRPC is not installed, please install the grpcio package "
+ "to use the gRPC transport."
+ ),
+ caught_exc,
)
- raise new_exc from caught_exc
_LOGGER = logging.getLogger(__name__)
@@ -84,7 +88,7 @@
self._request, context.method_name, context.service_url, headers
)
- return list(headers.items())
+ return list(six.iteritems(headers))
def __call__(self, context, callback):
"""Passes authorization metadata into the given callback.
@@ -333,7 +337,7 @@
)
except exceptions.ClientCertError as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
else:
self._ssl_credentials = grpc.ssl_channel_credentials()
diff --git a/google/auth/transport/mtls.py b/google/auth/transport/mtls.py
index c570761..b40bfbe 100644
--- a/google/auth/transport/mtls.py
+++ b/google/auth/transport/mtls.py
@@ -14,6 +14,8 @@
"""Utilites for mutual TLS."""
+import six
+
from google.auth import exceptions
from google.auth.transport import _mtls_helper
@@ -51,7 +53,7 @@
_, cert_bytes, key_bytes = _mtls_helper.get_client_cert_and_key()
except (OSError, RuntimeError, ValueError) as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
return cert_bytes, key_bytes
@@ -96,7 +98,7 @@
key_file.write(key_bytes)
except (exceptions.ClientCertError, OSError) as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
return cert_path, key_path, passphrase_bytes
diff --git a/google/auth/transport/requests.py b/google/auth/transport/requests.py
index 2cb6942..817176b 100644
--- a/google/auth/transport/requests.py
+++ b/google/auth/transport/requests.py
@@ -25,16 +25,21 @@
try:
import requests
except ImportError as caught_exc: # pragma: NO COVER
- new_exc = ImportError(
- "The requests library is not installed, please install the "
- "requests package to use the requests transport."
+ import six
+
+ six.raise_from(
+ ImportError(
+ "The requests library is not installed, please install the "
+ "requests package to use the requests transport."
+ ),
+ caught_exc,
)
- raise new_exc from caught_exc
import requests.adapters # pylint: disable=ungrouped-imports
import requests.exceptions # pylint: disable=ungrouped-imports
from requests.packages.urllib3.util.ssl_ import (
create_urllib3_context,
) # pylint: disable=ungrouped-imports
+import six # pylint: disable=ungrouped-imports
from google.auth import environment_vars
from google.auth import exceptions
@@ -181,7 +186,7 @@
return _Response(response)
except requests.exceptions.RequestException as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
class _MutualTlsAdapter(requests.adapters.HTTPAdapter):
@@ -391,7 +396,7 @@
import OpenSSL
except ImportError as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
try:
(
@@ -411,7 +416,7 @@
OpenSSL.crypto.Error,
) as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
def request(
self,
diff --git a/google/auth/transport/urllib3.py b/google/auth/transport/urllib3.py
index aa7188c..6a2504d 100644
--- a/google/auth/transport/urllib3.py
+++ b/google/auth/transport/urllib3.py
@@ -34,11 +34,16 @@
try:
import urllib3
except ImportError as caught_exc: # pragma: NO COVER
- new_exc = ImportError(
- "The urllib3 library is not installed, please install the "
- "urllib3 package to use the urllib3 transport."
+ import six
+
+ six.raise_from(
+ ImportError(
+ "The urllib3 library is not installed, please install the "
+ "urllib3 package to use the urllib3 transport."
+ ),
+ caught_exc,
)
- raise new_exc from caught_exc
+import six
import urllib3.exceptions # pylint: disable=ungrouped-imports
from google.auth import environment_vars
@@ -137,7 +142,7 @@
return _Response(response)
except urllib3.exceptions.HTTPError as caught_exc:
new_exc = exceptions.TransportError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
def _make_default_http():
@@ -329,7 +334,7 @@
import OpenSSL
except ImportError as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
try:
found_cert_key, cert, key = transport._mtls_helper.get_client_cert_and_key(
@@ -346,7 +351,7 @@
OpenSSL.crypto.Error,
) as caught_exc:
new_exc = exceptions.MutualTLSChannelError(caught_exc)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
if self._has_user_provided_http:
self._has_user_provided_http = False
diff --git a/google/oauth2/_client.py b/google/oauth2/_client.py
index f819371..2f4e847 100644
--- a/google/oauth2/_client.py
+++ b/google/oauth2/_client.py
@@ -24,9 +24,11 @@
"""
import datetime
-import http.client
import json
-import urllib
+
+import six
+from six.moves import http_client
+from six.moves import urllib
from google.auth import _helpers
from google.auth import exceptions
@@ -118,7 +120,7 @@
)
response_data = json.loads(response_body)
- if response.status == http.client.OK:
+ if response.status == http_client.OK:
break
else:
error_desc = response_data.get("error_description") or ""
@@ -129,9 +131,9 @@
):
retry += 1
continue
- return response.status == http.client.OK, response_data
+ return response.status == http_client.OK, response_data
- return response.status == http.client.OK, response_data
+ return response.status == http_client.OK, response_data
def _token_endpoint_request(
@@ -194,7 +196,7 @@
access_token = response_data["access_token"]
except KeyError as caught_exc:
new_exc = exceptions.RefreshError("No access token in response.", response_data)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
expiry = _parse_expiry(response_data)
@@ -234,7 +236,7 @@
id_token = response_data["id_token"]
except KeyError as caught_exc:
new_exc = exceptions.RefreshError("No ID token in response.", response_data)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
payload = jwt.decode(id_token, verify=False)
expiry = datetime.datetime.utcfromtimestamp(payload["exp"])
@@ -263,7 +265,7 @@
access_token = response_data["access_token"]
except KeyError as caught_exc:
new_exc = exceptions.RefreshError("No access token in response.", response_data)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
refresh_token = response_data.get("refresh_token", refresh_token)
expiry = _parse_expiry(response_data)
diff --git a/google/oauth2/_client_async.py b/google/oauth2/_client_async.py
index 8849023..cf51211 100644
--- a/google/oauth2/_client_async.py
+++ b/google/oauth2/_client_async.py
@@ -24,9 +24,11 @@
"""
import datetime
-import http.client
import json
-import urllib
+
+import six
+from six.moves import http_client
+from six.moves import urllib
from google.auth import exceptions
from google.auth import jwt
@@ -83,7 +85,7 @@
response_data = json.loads(response_body)
- if response.status == http.client.OK:
+ if response.status == http_client.OK:
break
else:
error_desc = response_data.get("error_description") or ""
@@ -94,9 +96,9 @@
):
retry += 1
continue
- return response.status == http.client.OK, response_data
+ return response.status == http_client.OK, response_data
- return response.status == http.client.OK, response_data
+ return response.status == http_client.OK, response_data
async def _token_endpoint_request(
@@ -159,7 +161,7 @@
access_token = response_data["access_token"]
except KeyError as caught_exc:
new_exc = exceptions.RefreshError("No access token in response.", response_data)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
expiry = client._parse_expiry(response_data)
@@ -199,7 +201,7 @@
id_token = response_data["id_token"]
except KeyError as caught_exc:
new_exc = exceptions.RefreshError("No ID token in response.", response_data)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
payload = jwt.decode(id_token, verify=False)
expiry = datetime.datetime.utcfromtimestamp(payload["exp"])
diff --git a/google/oauth2/_id_token_async.py b/google/oauth2/_id_token_async.py
index a4a526d..31fcbc6 100644
--- a/google/oauth2/_id_token_async.py
+++ b/google/oauth2/_id_token_async.py
@@ -58,10 +58,12 @@
.. _CacheControl: https://cachecontrol.readthedocs.io
"""
-import http.client
import json
import os
+import six
+from six.moves import http_client
+
from google.auth import environment_vars
from google.auth import exceptions
from google.auth import jwt
@@ -86,7 +88,7 @@
"""
response = await request(certs_url, method="GET")
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
raise exceptions.TransportError(
"Could not fetch certificates at {}".format(certs_url)
)
@@ -241,7 +243,7 @@
"GOOGLE_APPLICATION_CREDENTIALS is not valid service account credentials.",
caught_exc,
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
# 2. Try to fetch ID token from metada server if it exists. The code works
# for GAE and Cloud Run metadata server as well.
diff --git a/google/oauth2/_reauth_async.py b/google/oauth2/_reauth_async.py
index f74f50b..0276ddd 100644
--- a/google/oauth2/_reauth_async.py
+++ b/google/oauth2/_reauth_async.py
@@ -34,6 +34,8 @@
import sys
+from six.moves import range
+
from google.auth import exceptions
from google.oauth2 import _client
from google.oauth2 import _client_async
diff --git a/google/oauth2/challenges.py b/google/oauth2/challenges.py
index 0baff62..95e76cb 100644
--- a/google/oauth2/challenges.py
+++ b/google/oauth2/challenges.py
@@ -20,6 +20,8 @@
import getpass
import sys
+import six
+
from google.auth import _helpers
from google.auth import exceptions
@@ -45,7 +47,8 @@
return getpass.getpass(text)
-class ReauthChallenge(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class ReauthChallenge(object):
"""Base class for reauth challenges."""
@property
diff --git a/google/oauth2/credentials.py b/google/oauth2/credentials.py
index 6d34edf..9b59f8c 100644
--- a/google/oauth2/credentials.py
+++ b/google/oauth2/credentials.py
@@ -35,6 +35,8 @@
import io
import json
+import six
+
from google.auth import _cloud_sdk
from google.auth import _helpers
from google.auth import credentials
@@ -262,7 +264,7 @@
if self._refresh_token is None and self.refresh_handler:
token, expiry = self.refresh_handler(request, scopes=scopes)
# Validate returned data.
- if not isinstance(token, str):
+ if not isinstance(token, six.string_types):
raise exceptions.RefreshError(
"The refresh_handler returned token is not a string."
)
@@ -344,7 +346,7 @@
ValueError: If the info is not in the expected format.
"""
keys_needed = set(("refresh_token", "client_id", "client_secret"))
- missing = keys_needed.difference(info)
+ missing = keys_needed.difference(six.iterkeys(info))
if missing:
raise ValueError(
@@ -364,7 +366,7 @@
# process scopes, which needs to be a seq
if scopes is None and "scopes" in info:
scopes = info.get("scopes")
- if isinstance(scopes, str):
+ if isinstance(scopes, six.string_types):
scopes = scopes.split(" ")
return cls(
diff --git a/google/oauth2/id_token.py b/google/oauth2/id_token.py
index 25492ca..8d0f85a 100644
--- a/google/oauth2/id_token.py
+++ b/google/oauth2/id_token.py
@@ -55,10 +55,12 @@
.. _CacheControl: https://cachecontrol.readthedocs.io
"""
-import http.client
import json
import os
+import six
+from six.moves import http_client
+
from google.auth import environment_vars
from google.auth import exceptions
from google.auth import jwt
@@ -95,7 +97,7 @@
"""
response = request(certs_url, method="GET")
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
raise exceptions.TransportError(
"Could not fetch certificates at {}".format(certs_url)
)
@@ -240,7 +242,7 @@
"GOOGLE_APPLICATION_CREDENTIALS is not valid service account credentials.",
caught_exc,
)
- raise new_exc from caught_exc
+ six.raise_from(new_exc, caught_exc)
# 2. Try to fetch ID token from metada server if it exists. The code
# works for GAE and Cloud Run metadata server as well.
diff --git a/google/oauth2/reauth.py b/google/oauth2/reauth.py
index 1e496d1..cbf1d7f 100644
--- a/google/oauth2/reauth.py
+++ b/google/oauth2/reauth.py
@@ -34,6 +34,8 @@
import sys
+from six.moves import range
+
from google.auth import exceptions
from google.oauth2 import _client
from google.oauth2 import challenges
diff --git a/google/oauth2/sts.py b/google/oauth2/sts.py
index 9f2d68a..ae3c014 100644
--- a/google/oauth2/sts.py
+++ b/google/oauth2/sts.py
@@ -31,9 +31,10 @@
.. _rfc8693 section 2.2.1: https://tools.ietf.org/html/rfc8693#section-2.2.1
"""
-import http.client
import json
-import urllib
+
+from six.moves import http_client
+from six.moves import urllib
from google.oauth2 import utils
@@ -145,7 +146,7 @@
)
# If non-200 response received, translate to OAuthError exception.
- if response.status != http.client.OK:
+ if response.status != http_client.OK:
utils.handle_error_response(response_body)
response_data = json.loads(response_body)
diff --git a/google/oauth2/utils.py b/google/oauth2/utils.py
index c57833d..593f032 100644
--- a/google/oauth2/utils.py
+++ b/google/oauth2/utils.py
@@ -45,6 +45,8 @@
import enum
import json
+import six
+
from google.auth import exceptions
@@ -75,7 +77,8 @@
self.client_secret = client_secret
-class OAuthClientAuthHandler(object, metaclass=abc.ABCMeta):
+@six.add_metaclass(abc.ABCMeta)
+class OAuthClientAuthHandler(object):
"""Abstract class for handling client authentication in OAuth-based
operations.
"""