Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-google-auth for 
openSUSE:Factory checked in at 2022-10-15 16:34:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-google-auth (Old)
 and      /work/SRC/openSUSE:Factory/.python-google-auth.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-google-auth"

Sat Oct 15 16:34:57 2022 rev:22 rq:1010915 version:2.12.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-google-auth/python-google-auth.changes    
2022-09-09 18:22:53.680155641 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-google-auth.new.2275/python-google-auth.changes
  2022-10-15 16:36:12.933974355 +0200
@@ -1,0 +2,10 @@
+Fri Oct 14 09:30:55 UTC 2022 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 2.12.0
+  * Retry behavior (#1113)
+  * Modify RefreshError exception to use gcloud ADC command. (#1149)
+  * Revert "Update token refresh threshold from 20 seconds to 5 minutes". 
(186464b)
+- Refresh patches for new version
+  * python-google-auth-no-mock.patch
+
+-------------------------------------------------------------------

Old:
----
  google-auth-2.11.0.tar.gz

New:
----
  google-auth-2.12.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-google-auth.spec ++++++
--- /var/tmp/diff_new_pack.eu8sbx/_old  2022-10-15 16:36:14.629978431 +0200
+++ /var/tmp/diff_new_pack.eu8sbx/_new  2022-10-15 16:36:14.637978450 +0200
@@ -19,7 +19,7 @@
 %define skip_python2 1
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-google-auth
-Version:        2.11.0
+Version:        2.12.0
 Release:        0
 Summary:        Google Authentication Library
 License:        Apache-2.0

++++++ google-auth-2.11.0.tar.gz -> google-auth-2.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/PKG-INFO 
new/google-auth-2.12.0/PKG-INFO
--- old/google-auth-2.11.0/PKG-INFO     2022-08-20 01:29:58.960029000 +0200
+++ new/google-auth-2.12.0/PKG-INFO     2022-09-27 22:42:06.128310700 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-auth
-Version: 2.11.0
+Version: 2.12.0
 Summary: Google Authentication Library
 Home-page: https://github.com/googleapis/google-auth-library-python
 Author: Google Cloud Platform
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/google/auth/_exponential_backoff.py 
new/google-auth-2.12.0/google/auth/_exponential_backoff.py
--- old/google-auth-2.11.0/google/auth/_exponential_backoff.py  1970-01-01 
01:00:00.000000000 +0100
+++ new/google-auth-2.12.0/google/auth/_exponential_backoff.py  2022-09-27 
22:38:30.000000000 +0200
@@ -0,0 +1,111 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import random
+import time
+
+import six
+
+# The default amount of retry attempts
+_DEFAULT_RETRY_TOTAL_ATTEMPTS = 3
+
+# The default initial backoff period (1.0 second).
+_DEFAULT_INITIAL_INTERVAL_SECONDS = 1.0
+
+# The default randomization factor (0.1 which results in a random period 
ranging
+# between 10% below and 10% above the retry interval).
+_DEFAULT_RANDOMIZATION_FACTOR = 0.1
+
+# The default multiplier value (2 which is 100% increase per back off).
+_DEFAULT_MULTIPLIER = 2.0
+
+"""Exponential Backoff Utility
+
+This is a private module that implements the exponential back off algorithm.
+It can be used as a utility for code that needs to retry on failure, for 
example
+an HTTP request.
+"""
+
+
+class ExponentialBackoff(six.Iterator):
+    """An exponential backoff iterator. This can be used in a for loop to
+    perform requests with exponential backoff.
+
+    Args:
+        total_attempts Optional[int]:
+            The maximum amount of retries that should happen.
+            The default value is 3 attempts.
+        initial_wait_seconds Optional[int]:
+            The amount of time to sleep in the first backoff. This parameter
+            should be in seconds.
+            The default value is 1 second.
+        randomization_factor Optional[float]:
+            The amount of jitter that should be in each backoff. For example,
+            a value of 0.1 will introduce a jitter range of 10% to the
+            current backoff period.
+            The default value is 0.1.
+        multiplier Optional[float]:
+            The backoff multipler. This adjusts how much each backoff will
+            increase. For example a value of 2.0 leads to a 200% backoff
+            on each attempt. If the initial_wait is 1.0 it would look like
+            this sequence [1.0, 2.0, 4.0, 8.0].
+            The default value is 2.0.
+    """
+
+    def __init__(
+        self,
+        total_attempts=_DEFAULT_RETRY_TOTAL_ATTEMPTS,
+        initial_wait_seconds=_DEFAULT_INITIAL_INTERVAL_SECONDS,
+        randomization_factor=_DEFAULT_RANDOMIZATION_FACTOR,
+        multiplier=_DEFAULT_MULTIPLIER,
+    ):
+        self._total_attempts = total_attempts
+        self._initial_wait_seconds = initial_wait_seconds
+
+        self._current_wait_in_seconds = self._initial_wait_seconds
+
+        self._randomization_factor = randomization_factor
+        self._multiplier = multiplier
+        self._backoff_count = 0
+
+    def __iter__(self):
+        self._backoff_count = 0
+        self._current_wait_in_seconds = self._initial_wait_seconds
+        return self
+
+    def __next__(self):
+        if self._backoff_count >= self._total_attempts:
+            raise StopIteration
+        self._backoff_count += 1
+
+        jitter_variance = self._current_wait_in_seconds * 
self._randomization_factor
+        jitter = random.uniform(
+            self._current_wait_in_seconds - jitter_variance,
+            self._current_wait_in_seconds + jitter_variance,
+        )
+
+        time.sleep(jitter)
+
+        self._current_wait_in_seconds *= self._multiplier
+        return self._backoff_count
+
+    @property
+    def total_attempts(self):
+        """The total amount of backoff attempts that will be made."""
+        return self._total_attempts
+
+    @property
+    def backoff_count(self):
+        """The current amount of backoff attempts that have been made."""
+        return self._backoff_count
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/auth/exceptions.py 
new/google-auth-2.12.0/google/auth/exceptions.py
--- old/google-auth-2.11.0/google/auth/exceptions.py    2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/exceptions.py    2022-09-27 
22:38:30.000000000 +0200
@@ -18,6 +18,15 @@
 class GoogleAuthError(Exception):
     """Base class for all google.auth errors."""
 
+    def __init__(self, *args, **kwargs):
+        super(GoogleAuthError, self).__init__(*args)
+        retryable = kwargs.get("retryable", False)
+        self._retryable = retryable
+
+    @property
+    def retryable(self):
+        return self._retryable
+
 
 class TransportError(GoogleAuthError):
     """Used to indicate an error occurred during an HTTP request."""
@@ -44,6 +53,10 @@
 class ClientCertError(GoogleAuthError):
     """Used to indicate that client certificate is missing or invalid."""
 
+    @property
+    def retryable(self):
+        return False
+
 
 class OAuthError(GoogleAuthError):
     """Used to indicate an error occurred during an OAuth related HTTP
@@ -53,9 +66,9 @@
 class ReauthFailError(RefreshError):
     """An exception for when reauth failed."""
 
-    def __init__(self, message=None):
+    def __init__(self, message=None, **kwargs):
         super(ReauthFailError, self).__init__(
-            "Reauthentication failed. {0}".format(message)
+            "Reauthentication failed. {0}".format(message), **kwargs
         )
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/google/auth/impersonated_credentials.py 
new/google-auth-2.12.0/google/auth/impersonated_credentials.py
--- old/google-auth-2.11.0/google/auth/impersonated_credentials.py      
2022-08-20 01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/impersonated_credentials.py      
2022-09-27 22:38:30.000000000 +0200
@@ -288,9 +288,12 @@
 
         authed_session = AuthorizedSession(self._source_credentials)
 
-        response = authed_session.post(
-            url=iam_sign_endpoint, headers=headers, json=body
-        )
+        try:
+            response = authed_session.post(
+                url=iam_sign_endpoint, headers=headers, json=body
+            )
+        finally:
+            authed_session.close()
 
         if response.status_code != http_client.OK:
             raise exceptions.TransportError(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/auth/transport/__init__.py 
new/google-auth-2.12.0/google/auth/transport/__init__.py
--- old/google-auth-2.11.0/google/auth/transport/__init__.py    2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/transport/__init__.py    2022-09-27 
22:38:30.000000000 +0200
@@ -29,9 +29,21 @@
 import six
 from six.moves import http_client
 
+TOO_MANY_REQUESTS = 429  # Python 2.7 six is missing this status code.
+
+DEFAULT_RETRYABLE_STATUS_CODES = (
+    http_client.INTERNAL_SERVER_ERROR,
+    http_client.SERVICE_UNAVAILABLE,
+    http_client.REQUEST_TIMEOUT,
+    TOO_MANY_REQUESTS,
+)
+"""Sequence[int]:  HTTP status codes indicating a request can be retried.
+"""
+
+
 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.
+refreshed.
 """
 
 DEFAULT_MAX_REFRESH_ATTEMPTS = 2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/google/auth/transport/_aiohttp_requests.py 
new/google-auth-2.12.0/google/auth/transport/_aiohttp_requests.py
--- old/google-auth-2.11.0/google/auth/transport/_aiohttp_requests.py   
2022-08-20 01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/transport/_aiohttp_requests.py   
2022-09-27 22:38:30.000000000 +0200
@@ -233,6 +233,8 @@
             refreshing credentials. If not passed,
             an instance of 
:class:`~google.auth.transport.aiohttp_requests.Request`
             is created.
+        kwargs: Additional arguments passed through to the underlying
+            ClientSession :meth:`aiohttp.ClientSession` object.
     """
 
     def __init__(
@@ -243,8 +245,9 @@
         refresh_timeout=None,
         auth_request=None,
         auto_decompress=False,
+        **kwargs,
     ):
-        super(AuthorizedSession, self).__init__()
+        super(AuthorizedSession, self).__init__(**kwargs)
         self.credentials = credentials
         self._refresh_status_codes = refresh_status_codes
         self._max_refresh_attempts = max_refresh_attempts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/google/auth/transport/_custom_tls_signer.py 
new/google-auth-2.12.0/google/auth/transport/_custom_tls_signer.py
--- old/google-auth-2.11.0/google/auth/transport/_custom_tls_signer.py  
2022-08-20 01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/transport/_custom_tls_signer.py  
2022-09-27 22:38:30.000000000 +0200
@@ -192,8 +192,8 @@
 
                     {
                         "libs": {
-                            "signer_library": "...",
-                            "offload_library": "..."
+                            "ecp_client": "...",
+                            "tls_offload": "..."
                         }
                     }
         """
@@ -206,8 +206,8 @@
             with open(self._enterprise_cert_file_path, "r") as f:
                 enterprise_cert_json = json.load(f)
                 libs = enterprise_cert_json["libs"]
-                signer_library = libs["signer_library"]
-                offload_library = libs["offload_library"]
+                signer_library = libs["ecp_client"]
+                offload_library = libs["tls_offload"]
         except (KeyError, ValueError) as caught_exc:
             new_exc = exceptions.MutualTLSChannelError(
                 "enterprise cert file is invalid", caught_exc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/auth/version.py 
new/google-auth-2.12.0/google/auth/version.py
--- old/google-auth-2.11.0/google/auth/version.py       2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/auth/version.py       2022-09-27 
22:38:30.000000000 +0200
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "2.11.0"
+__version__ = "2.12.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/oauth2/_client.py 
new/google-auth-2.12.0/google/oauth2/_client.py
--- old/google-auth-2.11.0/google/oauth2/_client.py     2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/oauth2/_client.py     2022-09-27 
22:38:30.000000000 +0200
@@ -30,9 +30,11 @@
 from six.moves import http_client
 from six.moves import urllib
 
+from google.auth import _exponential_backoff
 from google.auth import _helpers
 from google.auth import exceptions
 from google.auth import jwt
+from google.auth import transport
 
 _URLENCODED_CONTENT_TYPE = "application/x-www-form-urlencoded"
 _JSON_CONTENT_TYPE = "application/json"
@@ -40,17 +42,22 @@
 _REFRESH_GRANT_TYPE = "refresh_token"
 
 
-def _handle_error_response(response_data):
+def _handle_error_response(response_data, retryable_error):
     """Translates an error response into an exception.
 
     Args:
         response_data (Mapping | str): The decoded response data.
+        retryable_error Optional[bool]: A boolean indicating if an error is 
retryable.
+            Defaults to False.
 
     Raises:
         google.auth.exceptions.RefreshError: The errors contained in 
response_data.
     """
+
+    retryable_error = retryable_error if retryable_error else False
+
     if isinstance(response_data, six.string_types):
-        raise exceptions.RefreshError(response_data)
+        raise exceptions.RefreshError(response_data, retryable=retryable_error)
     try:
         error_details = "{}: {}".format(
             response_data["error"], response_data.get("error_description")
@@ -59,7 +66,45 @@
     except (KeyError, ValueError):
         error_details = json.dumps(response_data)
 
-    raise exceptions.RefreshError(error_details, response_data)
+    raise exceptions.RefreshError(
+        error_details, response_data, retryable=retryable_error
+    )
+
+
+def _can_retry(status_code, response_data):
+    """Checks if a request can be retried by inspecting the status code
+    and response body of the request.
+
+    Args:
+        status_code (int): The response status code.
+        response_data (Mapping | str): The decoded response data.
+
+    Returns:
+      bool: True if the response is retryable. False otherwise.
+    """
+    if status_code in transport.DEFAULT_RETRYABLE_STATUS_CODES:
+        return True
+
+    try:
+        # For a failed response, response_body could be a string
+        error_desc = response_data.get("error_description") or ""
+        error_code = response_data.get("error") or ""
+
+        # Per Oauth 2.0 RFC 
https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.2.1
+        # This is needed because a redirect will not return a 500 status code.
+        retryable_error_descriptions = {
+            "internal_failure",
+            "server_error",
+            "temporarily_unavailable",
+        }
+
+        if any(e in retryable_error_descriptions for e in (error_code, 
error_desc)):
+            return True
+
+    except AttributeError:
+        pass
+
+    return False
 
 
 def _parse_expiry(response_data):
@@ -81,7 +126,13 @@
 
 
 def _token_endpoint_request_no_throw(
-    request, token_uri, body, access_token=None, use_json=False, **kwargs
+    request,
+    token_uri,
+    body,
+    access_token=None,
+    use_json=False,
+    can_retry=True,
+    **kwargs
 ):
     """Makes a request to the OAuth 2.0 authorization server's token endpoint.
     This function doesn't throw on response errors.
@@ -95,6 +146,7 @@
         access_token (Optional(str)): The access token needed to make the 
request.
         use_json (Optional(bool)): Use urlencoded format or json format for the
             content type. The default value is False.
+        can_retry (bool): Enable or disable request retry behavior.
         kwargs: Additional arguments passed on to the request method. The
             kwargs will be passed to `requests.request` method, see:
             https://docs.python-requests.org/en/latest/api/#requests.request.
@@ -104,8 +156,10 @@
             side SSL certificate verification.
 
     Returns:
-        Tuple(bool, Mapping[str, str]): A boolean indicating if the request is
-            successful, and a mapping for the JSON-decoded response data.
+        Tuple(bool, Mapping[str, str], Optional[bool]): A boolean indicating
+          if the request is successful, a mapping for the JSON-decoded response
+          data and in the case of an error a boolean indicating if the error
+          is retryable.
     """
     if use_json:
         headers = {"Content-Type": _JSON_CONTENT_TYPE}
@@ -117,10 +171,7 @@
     if access_token:
         headers["Authorization"] = "Bearer {}".format(access_token)
 
-    retry = 0
-    # retry to fetch token for maximum of two times if any internal failure
-    # occurs.
-    while True:
+    def _perform_request():
         response = request(
             method="POST", url=token_uri, headers=headers, body=body, **kwargs
         )
@@ -129,32 +180,44 @@
             if hasattr(response.data, "decode")
             else response.data
         )
-
-        if response.status == http_client.OK:
+        response_data = ""
+        try:
             # response_body should be a JSON
             response_data = json.loads(response_body)
-            break
-        else:
-            # For a failed response, response_body could be a string
-            try:
-                response_data = json.loads(response_body)
-                error_desc = response_data.get("error_description") or ""
-                error_code = response_data.get("error") or ""
-                if (
-                    any(e == "internal_failure" for e in (error_code, 
error_desc))
-                    and retry < 1
-                ):
-                    retry += 1
-                    continue
-            except ValueError:
-                response_data = response_body
-            return False, response_data
+        except ValueError:
+            response_data = response_body
+
+        if response.status == http_client.OK:
+            return True, response_data, None
+
+        retryable_error = _can_retry(
+            status_code=response.status, response_data=response_data
+        )
+
+        return False, response_data, retryable_error
+
+    request_succeeded, response_data, retryable_error = _perform_request()
+
+    if request_succeeded or not retryable_error or not can_retry:
+        return request_succeeded, response_data, retryable_error
+
+    retries = _exponential_backoff.ExponentialBackoff()
+    for _ in retries:
+        request_succeeded, response_data, retryable_error = _perform_request()
+        if request_succeeded or not retryable_error:
+            return request_succeeded, response_data, retryable_error
 
-    return True, response_data
+    return False, response_data, retryable_error
 
 
 def _token_endpoint_request(
-    request, token_uri, body, access_token=None, use_json=False, **kwargs
+    request,
+    token_uri,
+    body,
+    access_token=None,
+    use_json=False,
+    can_retry=True,
+    **kwargs
 ):
     """Makes a request to the OAuth 2.0 authorization server's token endpoint.
 
@@ -167,6 +230,7 @@
         access_token (Optional(str)): The access token needed to make the 
request.
         use_json (Optional(bool)): Use urlencoded format or json format for the
             content type. The default value is False.
+        can_retry (bool): Enable or disable request retry behavior.
         kwargs: Additional arguments passed on to the request method. The
             kwargs will be passed to `requests.request` method, see:
             https://docs.python-requests.org/en/latest/api/#requests.request.
@@ -182,15 +246,22 @@
         google.auth.exceptions.RefreshError: If the token endpoint returned
             an error.
     """
-    response_status_ok, response_data = _token_endpoint_request_no_throw(
-        request, token_uri, body, access_token=access_token, 
use_json=use_json, **kwargs
+
+    response_status_ok, response_data, retryable_error = 
_token_endpoint_request_no_throw(
+        request,
+        token_uri,
+        body,
+        access_token=access_token,
+        use_json=use_json,
+        can_retry=can_retry,
+        **kwargs
     )
     if not response_status_ok:
-        _handle_error_response(response_data)
+        _handle_error_response(response_data, retryable_error)
     return response_data
 
 
-def jwt_grant(request, token_uri, assertion):
+def jwt_grant(request, token_uri, assertion, can_retry=True):
     """Implements the JWT Profile for OAuth 2.0 Authorization Grants.
 
     For more details, see `rfc7523 section 4`_.
@@ -201,6 +272,7 @@
         token_uri (str): The OAuth 2.0 authorizations server's token endpoint
             URI.
         assertion (str): The OAuth 2.0 assertion.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, Optional[datetime], Mapping[str, str]]: The access token,
@@ -214,12 +286,16 @@
     """
     body = {"assertion": assertion, "grant_type": _JWT_GRANT_TYPE}
 
-    response_data = _token_endpoint_request(request, token_uri, body)
+    response_data = _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
 
     try:
         access_token = response_data["access_token"]
     except KeyError as caught_exc:
-        new_exc = exceptions.RefreshError("No access token in response.", 
response_data)
+        new_exc = exceptions.RefreshError(
+            "No access token in response.", response_data, retryable=False
+        )
         six.raise_from(new_exc, caught_exc)
 
     expiry = _parse_expiry(response_data)
@@ -227,7 +303,7 @@
     return access_token, expiry, response_data
 
 
-def id_token_jwt_grant(request, token_uri, assertion):
+def id_token_jwt_grant(request, token_uri, assertion, can_retry=True):
     """Implements the JWT Profile for OAuth 2.0 Authorization Grants, but
     requests an OpenID Connect ID Token instead of an access token.
 
@@ -242,6 +318,7 @@
             URI.
         assertion (str): JWT token signed by a service account. The token's
             payload must include a ``target_audience`` claim.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, Optional[datetime], Mapping[str, str]]:
@@ -254,12 +331,16 @@
     """
     body = {"assertion": assertion, "grant_type": _JWT_GRANT_TYPE}
 
-    response_data = _token_endpoint_request(request, token_uri, body)
+    response_data = _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
 
     try:
         id_token = response_data["id_token"]
     except KeyError as caught_exc:
-        new_exc = exceptions.RefreshError("No ID token in response.", 
response_data)
+        new_exc = exceptions.RefreshError(
+            "No ID token in response.", response_data, retryable=False
+        )
         six.raise_from(new_exc, caught_exc)
 
     payload = jwt.decode(id_token, verify=False)
@@ -288,7 +369,9 @@
     try:
         access_token = response_data["access_token"]
     except KeyError as caught_exc:
-        new_exc = exceptions.RefreshError("No access token in response.", 
response_data)
+        new_exc = exceptions.RefreshError(
+            "No access token in response.", response_data, retryable=False
+        )
         six.raise_from(new_exc, caught_exc)
 
     refresh_token = response_data.get("refresh_token", refresh_token)
@@ -305,6 +388,7 @@
     client_secret,
     scopes=None,
     rapt_token=None,
+    can_retry=True,
 ):
     """Implements the OAuth 2.0 refresh token grant.
 
@@ -324,6 +408,7 @@
             token has a wild card scope (e.g.
             'https://www.googleapis.com/auth/any-api').
         rapt_token (Optional(str)): The reauth Proof Token.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, str, Optional[datetime], Mapping[str, str]]: The access
@@ -347,5 +432,7 @@
     if rapt_token:
         body["rapt"] = rapt_token
 
-    response_data = _token_endpoint_request(request, token_uri, body)
+    response_data = _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
     return _handle_refresh_grant_response(response_data, refresh_token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/oauth2/_client_async.py 
new/google-auth-2.12.0/google/oauth2/_client_async.py
--- old/google-auth-2.11.0/google/oauth2/_client_async.py       2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/oauth2/_client_async.py       2022-09-27 
22:38:30.000000000 +0200
@@ -30,13 +30,14 @@
 from six.moves import http_client
 from six.moves import urllib
 
+from google.auth import _exponential_backoff
 from google.auth import exceptions
 from google.auth import jwt
 from google.oauth2 import _client as client
 
 
 async def _token_endpoint_request_no_throw(
-    request, token_uri, body, access_token=None, use_json=False
+    request, token_uri, body, access_token=None, use_json=False, can_retry=True
 ):
     """Makes a request to the OAuth 2.0 authorization server's token endpoint.
     This function doesn't throw on response errors.
@@ -50,10 +51,13 @@
         access_token (Optional(str)): The access token needed to make the 
request.
         use_json (Optional(bool)): Use urlencoded format or json format for the
             content type. The default value is False.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
-        Tuple(bool, Mapping[str, str]): A boolean indicating if the request is
-            successful, and a mapping for the JSON-decoded response data.
+        Tuple(bool, Mapping[str, str], Optional[bool]): A boolean indicating
+          if the request is successful, a mapping for the JSON-decoded response
+          data and in the case of an error a boolean indicating if the error
+          is retryable.
     """
     if use_json:
         headers = {"Content-Type": client._JSON_CONTENT_TYPE}
@@ -65,11 +69,7 @@
     if access_token:
         headers["Authorization"] = "Bearer {}".format(access_token)
 
-    retry = 0
-    # retry to fetch token for maximum of two times if any internal failure
-    # occurs.
-    while True:
-
+    async def _perform_request():
         response = await request(
             method="POST", url=token_uri, headers=headers, body=body
         )
@@ -83,26 +83,36 @@
             else response_body1
         )
 
-        response_data = json.loads(response_body)
+        try:
+            response_data = json.loads(response_body)
+        except ValueError:
+            response_data = response_body
 
         if response.status == http_client.OK:
-            break
-        else:
-            error_desc = response_data.get("error_description") or ""
-            error_code = response_data.get("error") or ""
-            if (
-                any(e == "internal_failure" for e in (error_code, error_desc))
-                and retry < 1
-            ):
-                retry += 1
-                continue
-            return response.status == http_client.OK, response_data
+            return True, response_data, None
+
+        retryable_error = client._can_retry(
+            status_code=response.status, response_data=response_data
+        )
+
+        return False, response_data, retryable_error
+
+    request_succeeded, response_data, retryable_error = await 
_perform_request()
+
+    if request_succeeded or not retryable_error or not can_retry:
+        return request_succeeded, response_data, retryable_error
+
+    retries = _exponential_backoff.ExponentialBackoff()
+    for _ in retries:
+        request_succeeded, response_data, retryable_error = await 
_perform_request()
+        if request_succeeded or not retryable_error:
+            return request_succeeded, response_data, retryable_error
 
-    return response.status == http_client.OK, response_data
+    return False, response_data, retryable_error
 
 
 async def _token_endpoint_request(
-    request, token_uri, body, access_token=None, use_json=False
+    request, token_uri, body, access_token=None, use_json=False, can_retry=True
 ):
     """Makes a request to the OAuth 2.0 authorization server's token endpoint.
 
@@ -115,6 +125,7 @@
         access_token (Optional(str)): The access token needed to make the 
request.
         use_json (Optional(bool)): Use urlencoded format or json format for the
             content type. The default value is False.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Mapping[str, str]: The JSON-decoded response data.
@@ -123,15 +134,21 @@
         google.auth.exceptions.RefreshError: If the token endpoint returned
             an error.
     """
-    response_status_ok, response_data = await _token_endpoint_request_no_throw(
-        request, token_uri, body, access_token=access_token, use_json=use_json
+
+    response_status_ok, response_data, retryable_error = await 
_token_endpoint_request_no_throw(
+        request,
+        token_uri,
+        body,
+        access_token=access_token,
+        use_json=use_json,
+        can_retry=can_retry,
     )
     if not response_status_ok:
-        client._handle_error_response(response_data)
+        client._handle_error_response(response_data, retryable_error)
     return response_data
 
 
-async def jwt_grant(request, token_uri, assertion):
+async def jwt_grant(request, token_uri, assertion, can_retry=True):
     """Implements the JWT Profile for OAuth 2.0 Authorization Grants.
 
     For more details, see `rfc7523 section 4`_.
@@ -142,6 +159,7 @@
         token_uri (str): The OAuth 2.0 authorizations server's token endpoint
             URI.
         assertion (str): The OAuth 2.0 assertion.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, Optional[datetime], Mapping[str, str]]: The access token,
@@ -155,12 +173,16 @@
     """
     body = {"assertion": assertion, "grant_type": client._JWT_GRANT_TYPE}
 
-    response_data = await _token_endpoint_request(request, token_uri, body)
+    response_data = await _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
 
     try:
         access_token = response_data["access_token"]
     except KeyError as caught_exc:
-        new_exc = exceptions.RefreshError("No access token in response.", 
response_data)
+        new_exc = exceptions.RefreshError(
+            "No access token in response.", response_data, retryable=False
+        )
         six.raise_from(new_exc, caught_exc)
 
     expiry = client._parse_expiry(response_data)
@@ -168,7 +190,7 @@
     return access_token, expiry, response_data
 
 
-async def id_token_jwt_grant(request, token_uri, assertion):
+async def id_token_jwt_grant(request, token_uri, assertion, can_retry=True):
     """Implements the JWT Profile for OAuth 2.0 Authorization Grants, but
     requests an OpenID Connect ID Token instead of an access token.
 
@@ -183,6 +205,7 @@
             URI.
         assertion (str): JWT token signed by a service account. The token's
             payload must include a ``target_audience`` claim.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, Optional[datetime], Mapping[str, str]]:
@@ -195,12 +218,16 @@
     """
     body = {"assertion": assertion, "grant_type": client._JWT_GRANT_TYPE}
 
-    response_data = await _token_endpoint_request(request, token_uri, body)
+    response_data = await _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
 
     try:
         id_token = response_data["id_token"]
     except KeyError as caught_exc:
-        new_exc = exceptions.RefreshError("No ID token in response.", 
response_data)
+        new_exc = exceptions.RefreshError(
+            "No ID token in response.", response_data, retryable=False
+        )
         six.raise_from(new_exc, caught_exc)
 
     payload = jwt.decode(id_token, verify=False)
@@ -217,6 +244,7 @@
     client_secret,
     scopes=None,
     rapt_token=None,
+    can_retry=True,
 ):
     """Implements the OAuth 2.0 refresh token grant.
 
@@ -236,6 +264,7 @@
             token has a wild card scope (e.g.
             'https://www.googleapis.com/auth/any-api').
         rapt_token (Optional(str)): The reauth Proof Token.
+        can_retry (bool): Enable or disable request retry behavior.
 
     Returns:
         Tuple[str, Optional[str], Optional[datetime], Mapping[str, str]]: The
@@ -259,5 +288,7 @@
     if rapt_token:
         body["rapt"] = rapt_token
 
-    response_data = await _token_endpoint_request(request, token_uri, body)
+    response_data = await _token_endpoint_request(
+        request, token_uri, body, can_retry=can_retry
+    )
     return client._handle_refresh_grant_response(response_data, refresh_token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/oauth2/_reauth_async.py 
new/google-auth-2.12.0/google/oauth2/_reauth_async.py
--- old/google-auth-2.11.0/google/oauth2/_reauth_async.py       2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/oauth2/_reauth_async.py       2022-09-27 
22:38:30.000000000 +0200
@@ -292,7 +292,7 @@
     if rapt_token:
         body["rapt"] = rapt_token
 
-    response_status_ok, response_data = await 
_client_async._token_endpoint_request_no_throw(
+    response_status_ok, response_data, retryable_error = await 
_client_async._token_endpoint_request_no_throw(
         request, token_uri, body
     )
     if (
@@ -307,7 +307,7 @@
     ):
         if not enable_reauth_refresh:
             raise exceptions.RefreshError(
-                "Reauthentication is needed. Please run `gcloud auth login 
--update-adc` to reauthenticate."
+                "Reauthentication is needed. Please run `gcloud auth 
application-default login` to reauthenticate."
             )
 
         rapt_token = await get_rapt_token(
@@ -317,12 +317,13 @@
         (
             response_status_ok,
             response_data,
+            retryable_error,
         ) = await _client_async._token_endpoint_request_no_throw(
             request, token_uri, body
         )
 
     if not response_status_ok:
-        _client._handle_error_response(response_data)
+        _client._handle_error_response(response_data, retryable_error)
     refresh_response = _client._handle_refresh_grant_response(
         response_data, refresh_token
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google/oauth2/reauth.py 
new/google-auth-2.12.0/google/oauth2/reauth.py
--- old/google-auth-2.11.0/google/oauth2/reauth.py      2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/google/oauth2/reauth.py      2022-09-27 
22:38:30.000000000 +0200
@@ -319,7 +319,7 @@
     if rapt_token:
         body["rapt"] = rapt_token
 
-    response_status_ok, response_data = 
_client._token_endpoint_request_no_throw(
+    response_status_ok, response_data, retryable_error = 
_client._token_endpoint_request_no_throw(
         request, token_uri, body
     )
     if (
@@ -332,19 +332,21 @@
     ):
         if not enable_reauth_refresh:
             raise exceptions.RefreshError(
-                "Reauthentication is needed. Please run `gcloud auth login 
--update-adc` to reauthenticate."
+                "Reauthentication is needed. Please run `gcloud auth 
application-default login` to reauthenticate."
             )
 
         rapt_token = get_rapt_token(
             request, client_id, client_secret, refresh_token, token_uri, 
scopes=scopes
         )
         body["rapt"] = rapt_token
-        (response_status_ok, response_data) = 
_client._token_endpoint_request_no_throw(
-            request, token_uri, body
-        )
+        (
+            response_status_ok,
+            response_data,
+            retryable_error,
+        ) = _client._token_endpoint_request_no_throw(request, token_uri, body)
 
     if not response_status_ok:
-        _client._handle_error_response(response_data)
+        _client._handle_error_response(response_data, retryable_error)
     return _client._handle_refresh_grant_response(response_data, 
refresh_token) + (
         rapt_token,
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google_auth.egg-info/PKG-INFO 
new/google-auth-2.12.0/google_auth.egg-info/PKG-INFO
--- old/google-auth-2.11.0/google_auth.egg-info/PKG-INFO        2022-08-20 
01:29:58.000000000 +0200
+++ new/google-auth-2.12.0/google_auth.egg-info/PKG-INFO        2022-09-27 
22:42:05.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: google-auth
-Version: 2.11.0
+Version: 2.12.0
 Summary: Google Authentication Library
 Home-page: https://github.com/googleapis/google-auth-library-python
 Author: Google Cloud Platform
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/google_auth.egg-info/SOURCES.txt 
new/google-auth-2.12.0/google_auth.egg-info/SOURCES.txt
--- old/google-auth-2.11.0/google_auth.egg-info/SOURCES.txt     2022-08-20 
01:29:58.000000000 +0200
+++ new/google-auth-2.12.0/google_auth.egg-info/SOURCES.txt     2022-09-27 
22:42:05.000000000 +0200
@@ -9,6 +9,7 @@
 google/auth/_credentials_async.py
 google/auth/_default.py
 google/auth/_default_async.py
+google/auth/_exponential_backoff.py
 google/auth/_helpers.py
 google/auth/_jwt_async.py
 google/auth/_oauth2client.py
@@ -70,6 +71,7 @@
 tests/conftest.py
 tests/test__cloud_sdk.py
 tests/test__default.py
+tests/test__exponential_backoff.py
 tests/test__helpers.py
 tests/test__oauth2client.py
 tests/test__service_account_info.py
@@ -77,6 +79,7 @@
 tests/test_aws.py
 tests/test_credentials.py
 tests/test_downscoped.py
+tests/test_exceptions.py
 tests/test_external_account.py
 tests/test_iam.py
 tests/test_identity_pool.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/tests/compute_engine/test_credentials.py 
new/google-auth-2.12.0/tests/compute_engine/test_credentials.py
--- old/google-auth-2.11.0/tests/compute_engine/test_credentials.py     
2022-08-20 01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/compute_engine/test_credentials.py     
2022-09-27 22:38:30.000000000 +0200
@@ -609,7 +609,7 @@
         request = mock.create_autospec(transport.Request, instance=True)
         response = mock.Mock()
         response.data = b'{"error": "http error"}'
-        response.status = 500
+        response.status = 404  # Throw a 404 so the request is not retried.
         request.side_effect = [response]
 
         self.credentials = credentials.IDTokenCredentials(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/tests/data/enterprise_cert_valid.json 
new/google-auth-2.12.0/tests/data/enterprise_cert_valid.json
--- old/google-auth-2.11.0/tests/data/enterprise_cert_valid.json        
2022-08-20 01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/data/enterprise_cert_valid.json        
2022-09-27 22:38:30.000000000 +0200
@@ -1,6 +1,6 @@
 {
     "libs": {
-        "signer_library": "/path/to/signer/lib",
-        "offload_library": "/path/to/offload/lib"
+        "ecp_client": "/path/to/signer/lib",
+        "tls_offload": "/path/to/offload/lib"
     }
-}
\ No newline at end of file
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/tests/oauth2/test__client.py 
new/google-auth-2.12.0/tests/oauth2/test__client.py
--- old/google-auth-2.11.0/tests/oauth2/test__client.py 2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/oauth2/test__client.py 2022-09-27 
22:38:30.000000000 +0200
@@ -47,12 +47,14 @@
 )
 
 
-def test__handle_error_response():
[email protected]("retryable", [True, False])
+def test__handle_error_response(retryable):
     response_data = {"error": "help", "error_description": "I'm alive"}
 
     with pytest.raises(exceptions.RefreshError) as excinfo:
-        _client._handle_error_response(response_data)
+        _client._handle_error_response(response_data, retryable)
 
+    assert excinfo.value.retryable == retryable
     assert excinfo.match(r"help: I\'m alive")
 
 
@@ -60,8 +62,9 @@
     response_data = {"foo": "bar"}
 
     with pytest.raises(exceptions.RefreshError) as excinfo:
-        _client._handle_error_response(response_data)
+        _client._handle_error_response(response_data, False)
 
+    assert not excinfo.value.retryable
     assert excinfo.match(r"{\"foo\": \"bar\"}")
 
 
@@ -69,11 +72,33 @@
     response_data = "this is an error message"
 
     with pytest.raises(exceptions.RefreshError) as excinfo:
-        _client._handle_error_response(response_data)
+        _client._handle_error_response(response_data, False)
 
+    assert not excinfo.value.retryable
     assert excinfo.match(response_data)
 
 
+def test__can_retry_retryable():
+    retryable_codes = transport.DEFAULT_RETRYABLE_STATUS_CODES
+    for status_code in range(100, 600):
+        if status_code in retryable_codes:
+            assert _client._can_retry(status_code, {"error": "invalid_scope"})
+        else:
+            assert not _client._can_retry(status_code, {"error": 
"invalid_scope"})
+
+
[email protected](
+    "response_data", [{"error": "internal_failure"}, {"error": "server_error"}]
+)
+def test__can_retry_message(response_data):
+    assert _client._can_retry(http_client.OK, response_data)
+
+
[email protected]("response_data", [{"error": "invalid_scope"}])
+def test__can_retry_no_retry_message(response_data):
+    assert not _client._can_retry(http_client.OK, response_data)
+
+
 @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
 def test__parse_expiry(unused_utcnow):
     result = _client._parse_expiry({"expires_in": 500})
@@ -154,8 +179,8 @@
         _client._token_endpoint_request(
             request, "http://example.com";, {"error_description": 
"internal_failure"}
         )
-    # request should be called twice due to the retry
-    assert request.call_count == 2
+    # request should be called once and then with 3 retries
+    assert request.call_count == 4
 
     request = make_request(
         {"error": "internal_failure"}, status=http_client.BAD_REQUEST
@@ -165,7 +190,55 @@
         _client._token_endpoint_request(
             request, "http://example.com";, {"error": "internal_failure"}
         )
-    # request should be called twice due to the retry
+    # request should be called once and then with 3 retries
+    assert request.call_count == 4
+
+
+def test__token_endpoint_request_internal_failure_and_retry_failure_error():
+    retryable_error = mock.create_autospec(transport.Response, instance=True)
+    retryable_error.status = http_client.BAD_REQUEST
+    retryable_error.data = json.dumps({"error_description": 
"internal_failure"}).encode(
+        "utf-8"
+    )
+
+    unretryable_error = mock.create_autospec(transport.Response, instance=True)
+    unretryable_error.status = http_client.BAD_REQUEST
+    unretryable_error.data = json.dumps({"error_description": 
"invalid_scope"}).encode(
+        "utf-8"
+    )
+
+    request = mock.create_autospec(transport.Request)
+
+    request.side_effect = [retryable_error, retryable_error, unretryable_error]
+
+    with pytest.raises(exceptions.RefreshError):
+        _client._token_endpoint_request(
+            request, "http://example.com";, {"error_description": 
"invalid_scope"}
+        )
+    # request should be called three times. Two retryable errors and one
+    # unretryable error to break the retry loop.
+    assert request.call_count == 3
+
+
+def test__token_endpoint_request_internal_failure_and_retry_succeeds():
+    retryable_error = mock.create_autospec(transport.Response, instance=True)
+    retryable_error.status = http_client.BAD_REQUEST
+    retryable_error.data = json.dumps({"error_description": 
"internal_failure"}).encode(
+        "utf-8"
+    )
+
+    response = mock.create_autospec(transport.Response, instance=True)
+    response.status = http_client.OK
+    response.data = json.dumps({"hello": "world"}).encode("utf-8")
+
+    request = mock.create_autospec(transport.Request)
+
+    request.side_effect = [retryable_error, response]
+
+    _ = _client._token_endpoint_request(
+        request, "http://example.com";, {"test": "params"}
+    )
+
     assert request.call_count == 2
 
 
@@ -219,8 +292,9 @@
         }
     )
 
-    with pytest.raises(exceptions.RefreshError):
+    with pytest.raises(exceptions.RefreshError) as excinfo:
         _client.jwt_grant(request, "http://example.com";, "assertion_value")
+    assert not excinfo.value.retryable
 
 
 def test_id_token_jwt_grant():
@@ -255,8 +329,9 @@
         }
     )
 
-    with pytest.raises(exceptions.RefreshError):
+    with pytest.raises(exceptions.RefreshError) as excinfo:
         _client.id_token_jwt_grant(request, "http://example.com";, 
"assertion_value")
+    assert not excinfo.value.retryable
 
 
 @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
@@ -348,7 +423,104 @@
         }
     )
 
-    with pytest.raises(exceptions.RefreshError):
+    with pytest.raises(exceptions.RefreshError) as excinfo:
         _client.refresh_grant(
             request, "http://example.com";, "refresh_token", "client_id", 
"client_secret"
         )
+    assert not excinfo.value.retryable
+
+
[email protected]("google.oauth2._client._parse_expiry", return_value=None)
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_jwt_grant_retry_default(mock_token_endpoint_request, mock_expiry):
+    _client.jwt_grant(mock.Mock(), mock.Mock(), mock.Mock())
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=True
+    )
+
+
[email protected]("can_retry", [True, False])
[email protected]("google.oauth2._client._parse_expiry", return_value=None)
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_jwt_grant_retry_with_retry(
+    mock_token_endpoint_request, mock_expiry, can_retry
+):
+    _client.jwt_grant(mock.Mock(), mock.Mock(), mock.Mock(), 
can_retry=can_retry)
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=can_retry
+    )
+
+
[email protected]("google.auth.jwt.decode", return_value={"exp": 0})
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_id_token_jwt_grant_retry_default(mock_token_endpoint_request, 
mock_jwt_decode):
+    _client.id_token_jwt_grant(mock.Mock(), mock.Mock(), mock.Mock())
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=True
+    )
+
+
[email protected]("can_retry", [True, False])
[email protected]("google.auth.jwt.decode", return_value={"exp": 0})
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_id_token_jwt_grant_retry_with_retry(
+    mock_token_endpoint_request, mock_jwt_decode, can_retry
+):
+    _client.id_token_jwt_grant(
+        mock.Mock(), mock.Mock(), mock.Mock(), can_retry=can_retry
+    )
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=can_retry
+    )
+
+
[email protected]("google.oauth2._client._parse_expiry", return_value=None)
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_refresh_grant_retry_default(mock_token_endpoint_request, 
mock_parse_expiry):
+    _client.refresh_grant(
+        mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock(), mock.Mock()
+    )
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=True
+    )
+
+
[email protected]("can_retry", [True, False])
[email protected]("google.oauth2._client._parse_expiry", return_value=None)
[email protected](_client, "_token_endpoint_request", autospec=True)
+def test_refresh_grant_retry_with_retry(
+    mock_token_endpoint_request, mock_parse_expiry, can_retry
+):
+    _client.refresh_grant(
+        mock.Mock(),
+        mock.Mock(),
+        mock.Mock(),
+        mock.Mock(),
+        mock.Mock(),
+        can_retry=can_retry,
+    )
+    mock_token_endpoint_request.assert_called_with(
+        mock.ANY, mock.ANY, mock.ANY, can_retry=can_retry
+    )
+
+
[email protected]("can_retry", [True, False])
+def test__token_endpoint_request_no_throw_with_retry(can_retry):
+    response_data = {"error": "help", "error_description": "I'm alive"}
+    body = "dummy body"
+
+    mock_response = mock.create_autospec(transport.Response, instance=True)
+    mock_response.status = http_client.INTERNAL_SERVER_ERROR
+    mock_response.data = json.dumps(response_data).encode("utf-8")
+
+    mock_request = mock.create_autospec(transport.Request)
+    mock_request.return_value = mock_response
+
+    _client._token_endpoint_request_no_throw(
+        mock_request, mock.Mock(), body, mock.Mock(), mock.Mock(), 
can_retry=can_retry
+    )
+
+    if can_retry:
+        assert mock_request.call_count == 4
+    else:
+        assert mock_request.call_count == 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/tests/oauth2/test_reauth.py 
new/google-auth-2.12.0/tests/oauth2/test_reauth.py
--- old/google-auth-2.11.0/tests/oauth2/test_reauth.py  2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/oauth2/test_reauth.py  2022-09-27 
22:38:30.000000000 +0200
@@ -260,7 +260,7 @@
     with mock.patch(
         "google.oauth2._client._token_endpoint_request_no_throw"
     ) as mock_token_request:
-        mock_token_request.return_value = (False, {"error": "Bad request"})
+        mock_token_request.return_value = (False, {"error": "Bad request"}, 
False)
         with pytest.raises(exceptions.RefreshError) as excinfo:
             reauth.refresh_grant(
                 MOCK_REQUEST,
@@ -273,6 +273,7 @@
                 enable_reauth_refresh=True,
             )
         assert excinfo.match(r"Bad request")
+        assert not excinfo.value.retryable
         mock_token_request.assert_called_with(
             MOCK_REQUEST,
             "token_uri",
@@ -292,8 +293,8 @@
         "google.oauth2._client._token_endpoint_request_no_throw"
     ) as mock_token_request:
         mock_token_request.side_effect = [
-            (False, {"error": "invalid_grant", "error_subtype": 
"rapt_required"}),
-            (True, {"access_token": "access_token"}),
+            (False, {"error": "invalid_grant", "error_subtype": 
"rapt_required"}, True),
+            (True, {"access_token": "access_token"}, None),
         ]
         with mock.patch(
             "google.oauth2.reauth.get_rapt_token", 
return_value="new_rapt_token"
@@ -319,8 +320,8 @@
         "google.oauth2._client._token_endpoint_request_no_throw"
     ) as mock_token_request:
         mock_token_request.side_effect = [
-            (False, {"error": "invalid_grant", "error_subtype": 
"rapt_required"}),
-            (True, {"access_token": "access_token"}),
+            (False, {"error": "invalid_grant", "error_subtype": 
"rapt_required"}, True),
+            (True, {"access_token": "access_token"}, None),
         ]
         with pytest.raises(exceptions.RefreshError) as excinfo:
             reauth.refresh_grant(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-auth-2.11.0/tests/test__exponential_backoff.py 
new/google-auth-2.12.0/tests/test__exponential_backoff.py
--- old/google-auth-2.11.0/tests/test__exponential_backoff.py   1970-01-01 
01:00:00.000000000 +0100
+++ new/google-auth-2.12.0/tests/test__exponential_backoff.py   2022-09-27 
22:38:30.000000000 +0200
@@ -0,0 +1,41 @@
+# Copyright 2022 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import mock
+
+from google.auth import _exponential_backoff
+
+
[email protected]("time.sleep", return_value=None)
+def test_exponential_backoff(mock_time):
+    eb = _exponential_backoff.ExponentialBackoff()
+    curr_wait = eb._current_wait_in_seconds
+    iteration_count = 0
+
+    for attempt in eb:
+        backoff_interval = mock_time.call_args[0][0]
+        jitter = curr_wait * eb._randomization_factor
+
+        assert (curr_wait - jitter) <= backoff_interval <= (curr_wait + jitter)
+        assert attempt == iteration_count + 1
+        assert eb.backoff_count == iteration_count + 1
+        assert eb._current_wait_in_seconds == eb._multiplier ** 
(iteration_count + 1)
+
+        curr_wait = eb._current_wait_in_seconds
+        iteration_count += 1
+
+    assert eb.total_attempts == 
_exponential_backoff._DEFAULT_RETRY_TOTAL_ATTEMPTS
+    assert eb.backoff_count == 
_exponential_backoff._DEFAULT_RETRY_TOTAL_ATTEMPTS
+    assert iteration_count == 
_exponential_backoff._DEFAULT_RETRY_TOTAL_ATTEMPTS
+    assert mock_time.call_count == 
_exponential_backoff._DEFAULT_RETRY_TOTAL_ATTEMPTS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/tests/test__oauth2client.py 
new/google-auth-2.12.0/tests/test__oauth2client.py
--- old/google-auth-2.11.0/tests/test__oauth2client.py  2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/test__oauth2client.py  2022-09-27 
22:38:30.000000000 +0200
@@ -17,12 +17,19 @@
 import sys
 
 import mock
-import oauth2client.client  # type: ignore
-import oauth2client.contrib.gce  # type: ignore
-import oauth2client.service_account  # type: ignore
 import pytest  # type: ignore
 from six.moves import reload_module
 
+try:
+    import oauth2client.client  # type: ignore
+    import oauth2client.contrib.gce  # type: ignore
+    import oauth2client.service_account  # type: ignore
+except ImportError:  # pragma: NO COVER
+    pytest.skip(
+        "Skipping oauth2client tests since oauth2client is not installed.",
+        allow_module_level=True,
+    )
+
 from google.auth import _oauth2client
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/tests/test_exceptions.py 
new/google-auth-2.12.0/tests/test_exceptions.py
--- old/google-auth-2.11.0/tests/test_exceptions.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/google-auth-2.12.0/tests/test_exceptions.py     2022-09-27 
22:38:30.000000000 +0200
@@ -0,0 +1,55 @@
+# Copyright 2022 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest  # type: ignore
+
+from google.auth import exceptions  # type:ignore
+
+
[email protected](
+    params=[
+        exceptions.GoogleAuthError,
+        exceptions.TransportError,
+        exceptions.RefreshError,
+        exceptions.UserAccessTokenError,
+        exceptions.DefaultCredentialsError,
+        exceptions.MutualTLSChannelError,
+        exceptions.OAuthError,
+        exceptions.ReauthFailError,
+        exceptions.ReauthSamlChallengeFailError,
+    ]
+)
+def retryable_exception(request):
+    return request.param
+
+
[email protected](params=[exceptions.ClientCertError])
+def non_retryable_exception(request):
+    return request.param
+
+
+def test_default_retryable_exceptions(retryable_exception):
+    assert not retryable_exception().retryable
+
+
[email protected]("retryable", [True, False])
+def test_retryable_exceptions(retryable_exception, retryable):
+    retryable_exception = retryable_exception(retryable=retryable)
+    assert retryable_exception.retryable == retryable
+
+
[email protected]("retryable", [True, False])
+def test_non_retryable_exceptions(non_retryable_exception, retryable):
+    non_retryable_exception = non_retryable_exception(retryable=retryable)
+    assert not non_retryable_exception.retryable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-auth-2.11.0/tests/test_pluggable.py 
new/google-auth-2.12.0/tests/test_pluggable.py
--- old/google-auth-2.11.0/tests/test_pluggable.py      2022-08-20 
01:27:12.000000000 +0200
+++ new/google-auth-2.12.0/tests/test_pluggable.py      2022-09-27 
22:38:30.000000000 +0200
@@ -427,8 +427,10 @@
             assert excinfo.match(r"The token returned by the executable is 
expired.")
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
-    def test_retrieve_subject_token_file_cache(self):
-        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = "actual_output_file"
+    def test_retrieve_subject_token_file_cache(self, tmpdir):
+        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = tmpdir.join(
+            "actual_output_file"
+        )
         ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE = {
             "command": "command",
             "timeout_millis": 30000,
@@ -472,8 +474,10 @@
             assert subject_token == self.EXECUTABLE_OIDC_TOKEN
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
-    def test_retrieve_subject_token_file_cache_value_error_report(self):
-        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = "actual_output_file"
+    def test_retrieve_subject_token_file_cache_value_error_report(self, 
tmpdir):
+        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = tmpdir.join(
+            "actual_output_file"
+        )
         ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE = {
             "command": "command",
             "timeout_millis": 30000,
@@ -499,8 +503,10 @@
         os.remove(ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE)
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
-    def test_retrieve_subject_token_file_cache_refresh_error_retry(self):
-        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = "actual_output_file"
+    def test_retrieve_subject_token_file_cache_refresh_error_retry(self, 
tmpdir):
+        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = tmpdir.join(
+            "actual_output_file"
+        )
         ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE = {
             "command": "command",
             "timeout_millis": 30000,
@@ -637,7 +643,7 @@
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
     def 
test_retrieve_subject_token_without_expiration_time_should_fail_when_output_file_specified(
-        self
+        self,
     ):
         EXECUTABLE_SUCCESSFUL_OIDC_RESPONSE = {
             "version": 1,
@@ -665,9 +671,11 @@
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
     def 
test_retrieve_subject_token_without_expiration_time_should_fail_when_retrieving_from_output_file(
-        self
+        self, tmpdir
     ):
-        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = "actual_output_file"
+        ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE_OUTPUT_FILE = tmpdir.join(
+            "actual_output_file"
+        )
         ACTUAL_CREDENTIAL_SOURCE_EXECUTABLE = {
             "command": "command",
             "timeout_millis": 30000,
@@ -692,7 +700,7 @@
 
     @mock.patch.dict(os.environ, {"GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES": 
"1"})
     def 
test_retrieve_subject_token_without_expiration_time_should_pass_when_output_file_not_specified(
-        self
+        self,
     ):
         EXECUTABLE_SUCCESSFUL_OIDC_RESPONSE = {
             "version": 1,

++++++ python-google-auth-no-mock.patch ++++++
--- /var/tmp/diff_new_pack.eu8sbx/_old  2022-10-15 16:36:14.777978786 +0200
+++ /var/tmp/diff_new_pack.eu8sbx/_new  2022-10-15 16:36:14.781978796 +0200
@@ -1,6 +1,6 @@
-diff -Nru google-auth-2.11.0.orig/tests/compute_engine/test_credentials.py 
google-auth-2.11.0/tests/compute_engine/test_credentials.py
---- google-auth-2.11.0.orig/tests/compute_engine/test_credentials.py   
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/compute_engine/test_credentials.py        
2022-09-08 14:01:15.569972516 +0200
+diff -Nru google-auth-2.12.0.orig/tests/compute_engine/test_credentials.py 
google-auth-2.12.0/tests/compute_engine/test_credentials.py
+--- google-auth-2.12.0.orig/tests/compute_engine/test_credentials.py   
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/compute_engine/test_credentials.py        
2022-10-14 11:30:25.664406383 +0200
 @@ -14,7 +14,7 @@
  import base64
  import datetime
@@ -10,9 +10,9 @@
  import pytest  # type: ignore
  import responses  # type: ignore
  
-diff -Nru google-auth-2.11.0.orig/tests/compute_engine/test__metadata.py 
google-auth-2.11.0/tests/compute_engine/test__metadata.py
---- google-auth-2.11.0.orig/tests/compute_engine/test__metadata.py     
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/compute_engine/test__metadata.py  2022-09-08 
14:01:15.569972516 +0200
+diff -Nru google-auth-2.12.0.orig/tests/compute_engine/test__metadata.py 
google-auth-2.12.0/tests/compute_engine/test__metadata.py
+--- google-auth-2.12.0.orig/tests/compute_engine/test__metadata.py     
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/compute_engine/test__metadata.py  2022-10-14 
11:30:25.664406383 +0200
 @@ -16,7 +16,7 @@
  import json
  import os
@@ -22,9 +22,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import reload_module
-diff -Nru google-auth-2.11.0.orig/tests/conftest.py 
google-auth-2.11.0/tests/conftest.py
---- google-auth-2.11.0.orig/tests/conftest.py  2022-08-20 01:27:12.000000000 
+0200
-+++ google-auth-2.11.0/tests/conftest.py       2022-09-08 14:01:15.509971920 
+0200
+diff -Nru google-auth-2.12.0.orig/tests/conftest.py 
google-auth-2.12.0/tests/conftest.py
+--- google-auth-2.12.0.orig/tests/conftest.py  2022-09-27 22:38:30.000000000 
+0200
++++ google-auth-2.12.0/tests/conftest.py       2022-10-14 11:30:25.620405922 
+0200
 @@ -15,7 +15,7 @@
  import os
  import sys
@@ -34,9 +34,9 @@
  import pytest  # type: ignore
  
  
-diff -Nru google-auth-2.11.0.orig/tests/crypt/test__python_rsa.py 
google-auth-2.11.0/tests/crypt/test__python_rsa.py
---- google-auth-2.11.0.orig/tests/crypt/test__python_rsa.py    2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/crypt/test__python_rsa.py 2022-09-08 
14:01:15.589972714 +0200
+diff -Nru google-auth-2.12.0.orig/tests/crypt/test__python_rsa.py 
google-auth-2.12.0/tests/crypt/test__python_rsa.py
+--- google-auth-2.12.0.orig/tests/crypt/test__python_rsa.py    2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/crypt/test__python_rsa.py 2022-10-14 
11:30:25.676406509 +0200
 @@ -15,7 +15,7 @@
  import json
  import os
@@ -46,9 +46,9 @@
  from pyasn1_modules import pem  # type: ignore
  import pytest  # type: ignore
  import rsa  # type: ignore
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_challenges.py 
google-auth-2.11.0/tests/oauth2/test_challenges.py
---- google-auth-2.11.0.orig/tests/oauth2/test_challenges.py    2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_challenges.py 2022-09-08 
14:01:15.557972396 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_challenges.py 
google-auth-2.12.0/tests/oauth2/test_challenges.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_challenges.py    2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_challenges.py 2022-10-14 
11:30:25.656406299 +0200
 @@ -17,7 +17,7 @@
  import base64
  import sys
@@ -58,9 +58,9 @@
  import pytest  # type: ignore
  import pyu2f  # type: ignore
  
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test__client.py 
google-auth-2.11.0/tests/oauth2/test__client.py
---- google-auth-2.11.0.orig/tests/oauth2/test__client.py       2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test__client.py    2022-09-08 
14:01:15.549972317 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test__client.py 
google-auth-2.12.0/tests/oauth2/test__client.py
+--- google-auth-2.12.0.orig/tests/oauth2/test__client.py       2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test__client.py    2022-10-14 
11:30:25.648406216 +0200
 @@ -16,7 +16,7 @@
  import json
  import os
@@ -70,9 +70,9 @@
  import pytest  # type: ignore
  import six
  from six.moves import http_client
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_credentials.py 
google-auth-2.11.0/tests/oauth2/test_credentials.py
---- google-auth-2.11.0.orig/tests/oauth2/test_credentials.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_credentials.py        2022-09-08 
14:01:15.553972357 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_credentials.py 
google-auth-2.12.0/tests/oauth2/test_credentials.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_credentials.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_credentials.py        2022-10-14 
11:30:25.652406258 +0200
 @@ -18,7 +18,7 @@
  import pickle
  import sys
@@ -82,9 +82,9 @@
  import pytest  # type: ignore
  
  from google.auth import _helpers
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_gdch_credentials.py 
google-auth-2.11.0/tests/oauth2/test_gdch_credentials.py
---- google-auth-2.11.0.orig/tests/oauth2/test_gdch_credentials.py      
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_gdch_credentials.py   2022-09-08 
14:01:15.545972277 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_gdch_credentials.py 
google-auth-2.12.0/tests/oauth2/test_gdch_credentials.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_gdch_credentials.py      
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_gdch_credentials.py   2022-10-14 
11:30:25.644406174 +0200
 @@ -17,7 +17,7 @@
  import json
  import os
@@ -94,9 +94,9 @@
  import pytest  # type: ignore
  import requests
  import six
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_id_token.py 
google-auth-2.11.0/tests/oauth2/test_id_token.py
---- google-auth-2.11.0.orig/tests/oauth2/test_id_token.py      2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_id_token.py   2022-09-08 
14:01:15.545972277 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_id_token.py 
google-auth-2.12.0/tests/oauth2/test_id_token.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_id_token.py      2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_id_token.py   2022-10-14 
11:30:25.648406216 +0200
 @@ -15,7 +15,7 @@
  import json
  import os
@@ -106,9 +106,9 @@
  import pytest  # type: ignore
  
  from google.auth import environment_vars
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_reauth.py 
google-auth-2.11.0/tests/oauth2/test_reauth.py
---- google-auth-2.11.0.orig/tests/oauth2/test_reauth.py        2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_reauth.py     2022-09-08 
14:01:15.553972357 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_reauth.py 
google-auth-2.12.0/tests/oauth2/test_reauth.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_reauth.py        2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_reauth.py     2022-10-14 
11:30:25.652406258 +0200
 @@ -14,7 +14,7 @@
  
  import copy
@@ -118,9 +118,9 @@
  import pytest  # type: ignore
  
  from google.auth import exceptions
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_service_account.py 
google-auth-2.11.0/tests/oauth2/test_service_account.py
---- google-auth-2.11.0.orig/tests/oauth2/test_service_account.py       
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_service_account.py    2022-09-08 
14:01:15.549972317 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_service_account.py 
google-auth-2.12.0/tests/oauth2/test_service_account.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_service_account.py       
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_service_account.py    2022-10-14 
11:30:25.648406216 +0200
 @@ -16,7 +16,7 @@
  import json
  import os
@@ -130,9 +130,9 @@
  
  from google.auth import _helpers
  from google.auth import crypt
-diff -Nru google-auth-2.11.0.orig/tests/oauth2/test_sts.py 
google-auth-2.11.0/tests/oauth2/test_sts.py
---- google-auth-2.11.0.orig/tests/oauth2/test_sts.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/oauth2/test_sts.py        2022-09-08 
14:01:15.561972436 +0200
+diff -Nru google-auth-2.12.0.orig/tests/oauth2/test_sts.py 
google-auth-2.12.0/tests/oauth2/test_sts.py
+--- google-auth-2.12.0.orig/tests/oauth2/test_sts.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/oauth2/test_sts.py        2022-10-14 
11:30:25.656406299 +0200
 @@ -14,7 +14,7 @@
  
  import json
@@ -142,9 +142,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import urllib
-diff -Nru google-auth-2.11.0.orig/tests/test_app_engine.py 
google-auth-2.11.0/tests/test_app_engine.py
---- google-auth-2.11.0.orig/tests/test_app_engine.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_app_engine.py        2022-09-08 
14:01:15.533972159 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test_app_engine.py 
google-auth-2.12.0/tests/test_app_engine.py
+--- google-auth-2.12.0.orig/tests/test_app_engine.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_app_engine.py        2022-10-14 
11:30:25.640406132 +0200
 @@ -14,7 +14,7 @@
  
  import datetime
@@ -154,9 +154,9 @@
  import pytest  # type: ignore
  
  from google.auth import app_engine
-diff -Nru google-auth-2.11.0.orig/tests/test_aws.py 
google-auth-2.11.0/tests/test_aws.py
---- google-auth-2.11.0.orig/tests/test_aws.py  2022-08-20 01:27:12.000000000 
+0200
-+++ google-auth-2.11.0/tests/test_aws.py       2022-09-08 14:01:15.601972833 
+0200
+diff -Nru google-auth-2.12.0.orig/tests/test_aws.py 
google-auth-2.12.0/tests/test_aws.py
+--- google-auth-2.12.0.orig/tests/test_aws.py  2022-09-27 22:38:30.000000000 
+0200
++++ google-auth-2.12.0/tests/test_aws.py       2022-10-14 11:30:25.684406593 
+0200
 @@ -15,7 +15,7 @@
  import datetime
  import json
@@ -166,9 +166,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import urllib
-diff -Nru google-auth-2.11.0.orig/tests/test__cloud_sdk.py 
google-auth-2.11.0/tests/test__cloud_sdk.py
---- google-auth-2.11.0.orig/tests/test__cloud_sdk.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test__cloud_sdk.py        2022-09-08 
14:01:15.541972237 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test__cloud_sdk.py 
google-auth-2.12.0/tests/test__cloud_sdk.py
+--- google-auth-2.12.0.orig/tests/test__cloud_sdk.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test__cloud_sdk.py        2022-10-14 
11:30:25.644406174 +0200
 @@ -17,7 +17,7 @@
  import os
  import subprocess
@@ -178,9 +178,9 @@
  import pytest  # type: ignore
  
  from google.auth import _cloud_sdk
-diff -Nru google-auth-2.11.0.orig/tests/test__default.py 
google-auth-2.11.0/tests/test__default.py
---- google-auth-2.11.0.orig/tests/test__default.py     2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test__default.py  2022-09-08 14:01:15.565972476 
+0200
+diff -Nru google-auth-2.12.0.orig/tests/test__default.py 
google-auth-2.12.0/tests/test__default.py
+--- google-auth-2.12.0.orig/tests/test__default.py     2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test__default.py  2022-10-14 11:30:25.664406383 
+0200
 @@ -15,7 +15,7 @@
  import json
  import os
@@ -190,9 +190,9 @@
  import pytest  # type: ignore
  
  from google.auth import _default
-diff -Nru google-auth-2.11.0.orig/tests/test_downscoped.py 
google-auth-2.11.0/tests/test_downscoped.py
---- google-auth-2.11.0.orig/tests/test_downscoped.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_downscoped.py        2022-09-08 
14:01:15.569972516 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test_downscoped.py 
google-auth-2.12.0/tests/test_downscoped.py
+--- google-auth-2.12.0.orig/tests/test_downscoped.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_downscoped.py        2022-10-14 
11:30:25.664406383 +0200
 @@ -15,7 +15,7 @@
  import datetime
  import json
@@ -202,9 +202,21 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import urllib
-diff -Nru google-auth-2.11.0.orig/tests/test_external_account.py 
google-auth-2.11.0/tests/test_external_account.py
---- google-auth-2.11.0.orig/tests/test_external_account.py     2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_external_account.py  2022-09-08 
14:01:15.509971920 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test__exponential_backoff.py 
google-auth-2.12.0/tests/test__exponential_backoff.py
+--- google-auth-2.12.0.orig/tests/test__exponential_backoff.py 2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test__exponential_backoff.py      2022-10-14 
11:30:25.616405880 +0200
+@@ -12,7 +12,7 @@
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ 
+-import mock
++from unittest import mock
+ 
+ from google.auth import _exponential_backoff
+ 
+diff -Nru google-auth-2.12.0.orig/tests/test_external_account.py 
google-auth-2.12.0/tests/test_external_account.py
+--- google-auth-2.12.0.orig/tests/test_external_account.py     2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_external_account.py  2022-10-14 
11:30:25.620405922 +0200
 @@ -15,7 +15,7 @@
  import datetime
  import json
@@ -214,9 +226,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import urllib
-diff -Nru google-auth-2.11.0.orig/tests/test_iam.py 
google-auth-2.11.0/tests/test_iam.py
---- google-auth-2.11.0.orig/tests/test_iam.py  2022-08-20 01:27:12.000000000 
+0200
-+++ google-auth-2.11.0/tests/test_iam.py       2022-09-08 14:01:15.577972595 
+0200
+diff -Nru google-auth-2.12.0.orig/tests/test_iam.py 
google-auth-2.12.0/tests/test_iam.py
+--- google-auth-2.12.0.orig/tests/test_iam.py  2022-09-27 22:38:30.000000000 
+0200
++++ google-auth-2.12.0/tests/test_iam.py       2022-10-14 11:30:25.664406383 
+0200
 @@ -16,7 +16,7 @@
  import datetime
  import json
@@ -226,9 +238,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  
-diff -Nru google-auth-2.11.0.orig/tests/test_identity_pool.py 
google-auth-2.11.0/tests/test_identity_pool.py
---- google-auth-2.11.0.orig/tests/test_identity_pool.py        2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_identity_pool.py     2022-09-08 
14:01:15.577972595 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test_identity_pool.py 
google-auth-2.12.0/tests/test_identity_pool.py
+--- google-auth-2.12.0.orig/tests/test_identity_pool.py        2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_identity_pool.py     2022-10-14 
11:30:25.664406383 +0200
 @@ -16,7 +16,7 @@
  import json
  import os
@@ -238,9 +250,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  from six.moves import urllib
-diff -Nru google-auth-2.11.0.orig/tests/test_impersonated_credentials.py 
google-auth-2.11.0/tests/test_impersonated_credentials.py
---- google-auth-2.11.0.orig/tests/test_impersonated_credentials.py     
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_impersonated_credentials.py  2022-09-08 
14:01:15.593972754 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test_impersonated_credentials.py 
google-auth-2.12.0/tests/test_impersonated_credentials.py
+--- google-auth-2.12.0.orig/tests/test_impersonated_credentials.py     
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_impersonated_credentials.py  2022-10-14 
11:30:25.680406551 +0200
 @@ -19,7 +19,7 @@
  # Because Python 2.7
  # from typing import List
@@ -250,9 +262,9 @@
  import pytest  # type: ignore
  from six.moves import http_client
  
-diff -Nru google-auth-2.11.0.orig/tests/test_jwt.py 
google-auth-2.11.0/tests/test_jwt.py
---- google-auth-2.11.0.orig/tests/test_jwt.py  2022-08-20 01:27:12.000000000 
+0200
-+++ google-auth-2.11.0/tests/test_jwt.py       2022-09-08 14:01:15.581972634 
+0200
+diff -Nru google-auth-2.12.0.orig/tests/test_jwt.py 
google-auth-2.12.0/tests/test_jwt.py
+--- google-auth-2.12.0.orig/tests/test_jwt.py  2022-09-27 22:38:30.000000000 
+0200
++++ google-auth-2.12.0/tests/test_jwt.py       2022-10-14 11:30:25.668406425 
+0200
 @@ -17,7 +17,7 @@
  import json
  import os
@@ -262,21 +274,21 @@
  import pytest  # type: ignore
  
  from google.auth import _helpers
-diff -Nru google-auth-2.11.0.orig/tests/test__oauth2client.py 
google-auth-2.11.0/tests/test__oauth2client.py
---- google-auth-2.11.0.orig/tests/test__oauth2client.py        2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test__oauth2client.py     2022-09-08 
14:01:15.537972198 +0200
+diff -Nru google-auth-2.12.0.orig/tests/test__oauth2client.py 
google-auth-2.12.0/tests/test__oauth2client.py
+--- google-auth-2.12.0.orig/tests/test__oauth2client.py        2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test__oauth2client.py     2022-10-14 
11:30:25.640406132 +0200
 @@ -16,7 +16,7 @@
  import os
  import sys
  
 -import mock
 +from unittest import mock
- import oauth2client.client  # type: ignore
- import oauth2client.contrib.gce  # type: ignore
- import oauth2client.service_account  # type: ignore
-diff -Nru google-auth-2.11.0.orig/tests/test_pluggable.py 
google-auth-2.11.0/tests/test_pluggable.py
---- google-auth-2.11.0.orig/tests/test_pluggable.py    2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/test_pluggable.py 2022-09-08 14:01:15.597972793 
+0200
+ import pytest  # type: ignore
+ from six.moves import reload_module
+ 
+diff -Nru google-auth-2.12.0.orig/tests/test_pluggable.py 
google-auth-2.12.0/tests/test_pluggable.py
+--- google-auth-2.12.0.orig/tests/test_pluggable.py    2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/test_pluggable.py 2022-10-14 11:30:25.684406593 
+0200
 @@ -17,7 +17,7 @@
  import os
  import subprocess
@@ -286,9 +298,9 @@
  import pytest  # type: ignore
  
  # from six.moves import http_client
-diff -Nru google-auth-2.11.0.orig/tests/transport/test__custom_tls_signer.py 
google-auth-2.11.0/tests/transport/test__custom_tls_signer.py
---- google-auth-2.11.0.orig/tests/transport/test__custom_tls_signer.py 
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test__custom_tls_signer.py      
2022-09-08 14:01:15.513971960 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test__custom_tls_signer.py 
google-auth-2.12.0/tests/transport/test__custom_tls_signer.py
+--- google-auth-2.12.0.orig/tests/transport/test__custom_tls_signer.py 
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test__custom_tls_signer.py      
2022-10-14 11:30:25.624405964 +0200
 @@ -16,7 +16,7 @@
  import ctypes
  import os
@@ -298,9 +310,9 @@
  import pytest  # type: ignore
  from requests.packages.urllib3.util.ssl_ import create_urllib3_context  # 
type: ignore
  import urllib3.contrib.pyopenssl  # type: ignore
-diff -Nru google-auth-2.11.0.orig/tests/transport/test_grpc.py 
google-auth-2.11.0/tests/transport/test_grpc.py
---- google-auth-2.11.0.orig/tests/transport/test_grpc.py       2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test_grpc.py    2022-09-08 
14:01:15.517971999 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test_grpc.py 
google-auth-2.12.0/tests/transport/test_grpc.py
+--- google-auth-2.12.0.orig/tests/transport/test_grpc.py       2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test_grpc.py    2022-10-14 
11:30:25.624405964 +0200
 @@ -16,7 +16,7 @@
  import os
  import time
@@ -310,9 +322,9 @@
  import pytest  # type: ignore
  
  from google.auth import _helpers
-diff -Nru google-auth-2.11.0.orig/tests/transport/test__mtls_helper.py 
google-auth-2.11.0/tests/transport/test__mtls_helper.py
---- google-auth-2.11.0.orig/tests/transport/test__mtls_helper.py       
2022-08-20 01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test__mtls_helper.py    2022-09-08 
14:01:15.521972039 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test__mtls_helper.py 
google-auth-2.12.0/tests/transport/test__mtls_helper.py
+--- google-auth-2.12.0.orig/tests/transport/test__mtls_helper.py       
2022-09-27 22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test__mtls_helper.py    2022-10-14 
11:30:25.628406006 +0200
 @@ -15,7 +15,7 @@
  import os
  import re
@@ -322,9 +334,9 @@
  from OpenSSL import crypto
  import pytest  # type: ignore
  
-diff -Nru google-auth-2.11.0.orig/tests/transport/test_mtls.py 
google-auth-2.11.0/tests/transport/test_mtls.py
---- google-auth-2.11.0.orig/tests/transport/test_mtls.py       2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test_mtls.py    2022-09-08 
14:01:15.521972039 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test_mtls.py 
google-auth-2.12.0/tests/transport/test_mtls.py
+--- google-auth-2.12.0.orig/tests/transport/test_mtls.py       2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test_mtls.py    2022-10-14 
11:30:25.632406048 +0200
 @@ -12,7 +12,7 @@
  # See the License for the specific language governing permissions and
  # limitations under the License.
@@ -334,9 +346,9 @@
  import pytest  # type: ignore
  
  from google.auth import exceptions
-diff -Nru google-auth-2.11.0.orig/tests/transport/test_requests.py 
google-auth-2.11.0/tests/transport/test_requests.py
---- google-auth-2.11.0.orig/tests/transport/test_requests.py   2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test_requests.py        2022-09-08 
14:01:15.525972079 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test_requests.py 
google-auth-2.12.0/tests/transport/test_requests.py
+--- google-auth-2.12.0.orig/tests/transport/test_requests.py   2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test_requests.py        2022-10-14 
11:30:25.632406048 +0200
 @@ -18,7 +18,7 @@
  import sys
  
@@ -346,9 +358,9 @@
  import OpenSSL
  import pytest  # type: ignore
  import requests
-diff -Nru google-auth-2.11.0.orig/tests/transport/test_urllib3.py 
google-auth-2.11.0/tests/transport/test_urllib3.py
---- google-auth-2.11.0.orig/tests/transport/test_urllib3.py    2022-08-20 
01:27:12.000000000 +0200
-+++ google-auth-2.11.0/tests/transport/test_urllib3.py 2022-09-08 
14:01:15.513971960 +0200
+diff -Nru google-auth-2.12.0.orig/tests/transport/test_urllib3.py 
google-auth-2.12.0/tests/transport/test_urllib3.py
+--- google-auth-2.12.0.orig/tests/transport/test_urllib3.py    2022-09-27 
22:38:30.000000000 +0200
++++ google-auth-2.12.0/tests/transport/test_urllib3.py 2022-10-14 
11:30:25.620405922 +0200
 @@ -15,7 +15,7 @@
  import os
  import sys

Reply via email to