Skip to content

Commit b50cf1a

Browse files
authored
chore(google-auth): drop python 3.7 EOL false positives and refactor metrics telemetry (#17463)
This pull request eliminates EOL Python 3.7 false positives from the `google-auth` codebase to ensure a clean signal from version scanner compliance checks. **Why these changes are made:** - **Metrics Telemetry:** Hardcoded Python versions in telemetry headers (like `gl-python/3.7`) have been replaced with abstract version placeholders (`<python-version>`) in comments with formatting examples and in test assertions. This prevents scanner alerts while retaining the ability to verify HTTP client request formatting behavior. - **App Engine Runtime Tests:** GAE standard runtime test cases have been refactored to dynamically construct GAE runtime values from the active Python interpreter at test execution time, avoiding the need for EOL checks and manual updates when Python versions retire. - **Clean Up Transport Properties:** Replaced legacy private `_auto_decompress` internal attribute access in the `aiohttp` transport with the standard public `auto_decompress` property (supported in `aiohttp >= 3.8`), allowing the removal of old TODOs from the source code that referenced 3.7. - **Readme Cleanup**: Removed the manual, out-of-date historical "Unsupported Python Versions" list from the package documentation, relying instead on standard authoritative packaging metadata (`python_requires`) to enforce runtime compatibility. --- Supports resolution of the internal bug: #512225398
1 parent 53bcd6f commit b50cf1a

16 files changed

Lines changed: 126 additions & 129 deletions

packages/google-auth/README.rst

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,6 @@ Supported Python Versions
3737
^^^^^^^^^^^^^^^^^^^^^^^^^
3838
Python >= 3.10
3939

40-
Unsupported Python Versions
41-
^^^^^^^^^^^^^^^^^^^^^^^^^^^
42-
- Python == 2.7: The last version of this library with support for Python 2.7
43-
was `google.auth == 1.34.0`.
44-
45-
- Python 3.5: The last version of this library with support for Python 3.5
46-
was `google.auth == 1.23.0`.
47-
48-
- Python 3.6: The last version of this library with support for Python 3.6
49-
was `google.auth == 2.22.0`.
50-
51-
- Python 3.7: The last version of this library with support for Python 3.7
52-
was `google.auth == 2.45.0`.
5340

5441

5542
Documentation

packages/google-auth/google/auth/metrics.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,23 @@ def python_and_auth_lib_version():
5050

5151

5252
# x-goog-api-client header value for access token request via metadata server.
53-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds"
53+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/mds"
5454
def token_request_access_token_mds():
5555
return "{} {} {}".format(
5656
python_and_auth_lib_version(), REQUEST_TYPE_ACCESS_TOKEN, CRED_TYPE_SA_MDS
5757
)
5858

5959

6060
# x-goog-api-client header value for ID token request via metadata server.
61-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds"
61+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/it cred-type/mds"
6262
def token_request_id_token_mds():
6363
return "{} {} {}".format(
6464
python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_MDS
6565
)
6666

6767

6868
# x-goog-api-client header value for impersonated credentials access token request.
69-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp"
69+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/imp"
7070
def token_request_access_token_impersonate():
7171
return "{} {} {}".format(
7272
python_and_auth_lib_version(),
@@ -76,7 +76,7 @@ def token_request_access_token_impersonate():
7676

7777

7878
# x-goog-api-client header value for impersonated credentials ID token request.
79-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/imp"
79+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/it cred-type/imp"
8080
def token_request_id_token_impersonate():
8181
return "{} {} {}".format(
8282
python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_IMPERSONATE
@@ -85,7 +85,7 @@ def token_request_id_token_impersonate():
8585

8686
# x-goog-api-client header value for service account credentials access token
8787
# request (assertion flow).
88-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa"
88+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/sa"
8989
def token_request_access_token_sa_assertion():
9090
return "{} {} {}".format(
9191
python_and_auth_lib_version(), REQUEST_TYPE_ACCESS_TOKEN, CRED_TYPE_SA_ASSERTION
@@ -94,15 +94,15 @@ def token_request_access_token_sa_assertion():
9494

9595
# x-goog-api-client header value for service account credentials ID token
9696
# request (assertion flow).
97-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa"
97+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/it cred-type/sa"
9898
def token_request_id_token_sa_assertion():
9999
return "{} {} {}".format(
100100
python_and_auth_lib_version(), REQUEST_TYPE_ID_TOKEN, CRED_TYPE_SA_ASSERTION
101101
)
102102

103103

104104
# x-goog-api-client header value for user credentials token request.
105-
# Example: "gl-python/3.7 auth/1.1 cred-type/u"
105+
# Example: "gl-python/<python-version> auth/<library-version> cred-type/u"
106106
def token_request_user():
107107
return "{} {}".format(python_and_auth_lib_version(), CRED_TYPE_USER)
108108

@@ -111,25 +111,25 @@ def token_request_user():
111111

112112

113113
# x-goog-api-client header value for metadata server ping.
114-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/mds"
114+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/mds"
115115
def mds_ping():
116116
return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_MDS_PING)
117117

118118

119119
# x-goog-api-client header value for reauth start endpoint calls.
120-
# Example: "gl-python/3.7 auth/1.1 auth-request-type/re-start"
120+
# Example: "gl-python/<python-version> auth/<library-version> auth-request-type/re-start"
121121
def reauth_start():
122122
return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_REAUTH_START)
123123

124124

125125
# x-goog-api-client header value for reauth continue endpoint calls.
126-
# Example: "gl-python/3.7 auth/1.1 cred-type/re-cont"
126+
# Example: "gl-python/<python-version> auth/<library-version> cred-type/re-cont"
127127
def reauth_continue():
128128
return "{} {}".format(python_and_auth_lib_version(), REQUEST_TYPE_REAUTH_CONTINUE)
129129

130130

131131
# x-goog-api-client header value for BYOID calls to the Security Token Service exchange token endpoint.
132-
# Example: "gl-python/3.7 auth/1.1 google-byoid-sdk source/aws sa-impersonation/true sa-impersonation/true"
132+
# Example: "gl-python/<python-version> auth/<library-version> google-byoid-sdk source/aws sa-impersonation/true sa-impersonation/true"
133133
def byoid_metrics_header(metrics_options):
134134
header = "{} {}".format(python_and_auth_lib_version(), BYOID_HEADER_SECTION)
135135
for key, value in metrics_options.items():

packages/google-auth/google/auth/transport/_aiohttp_requests.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,7 @@ class Request(transport.Request):
143143
"""
144144

145145
def __init__(self, session=None):
146-
# TODO: Use auto_decompress property for aiohttp 3.7+
147-
if session is not None and session._auto_decompress:
146+
if session is not None and getattr(session, "auto_decompress", None) is True:
148147
raise exceptions.InvalidOperation(
149148
"Client sessions with auto_decompress=True are not supported."
150149
)

packages/google-auth/google/oauth2/credentials.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def __init__(
167167
def __getstate__(self):
168168
"""A __getstate__ method must exist for the __setstate__ to be called
169169
This is identical to the default implementation.
170-
See https://docs.python.org/3.7/library/pickle.html#object.__setstate__
170+
See https://docs.python.org/3/library/pickle.html#object.__setstate__
171171
"""
172172
state_dict = self.__dict__.copy()
173173
# Remove _refresh_handler function as there are limitations pickling and

packages/google-auth/tests/compute_engine/test__metadata.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@
6363
b"-----END CERTIFICATE-----\n"
6464
)
6565

66-
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
67-
"gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds"
66+
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/mds"
67+
MDS_PING_METRICS_HEADER_VALUE = (
68+
"gl-python/<python-version> auth/<library-version> auth-request-type/mds"
6869
)
69-
MDS_PING_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 auth-request-type/mds"
7070
MDS_PING_REQUEST_HEADER = {
7171
"metadata-flavor": "Google",
7272
"x-goog-api-client": MDS_PING_METRICS_HEADER_VALUE,

packages/google-auth/tests/compute_engine/test_credentials.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,8 @@
4343
b"bsxbLa6Fp0SYeYwO8ifEnkRvasVpc1WTQqfRB2JCj5pTBDzJpIpFCMmnQ"
4444
)
4545

46-
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
47-
"gl-python/3.7 auth/1.1 auth-request-type/at cred-type/mds"
48-
)
49-
ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
50-
"gl-python/3.7 auth/1.1 auth-request-type/it cred-type/mds"
51-
)
46+
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/mds"
47+
ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/it cred-type/mds"
5248
FAKE_SERVICE_ACCOUNT_EMAIL = "foo@bar.com"
5349
FAKE_QUOTA_PROJECT_ID = "fake-quota-project"
5450
FAKE_SCOPES = ["scope1", "scope2"]

packages/google-auth/tests/oauth2/test__client.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,8 @@
4646
" https://www.googleapis.com/auth/logging.write"
4747
)
4848

49-
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
50-
"gl-python/3.7 auth/1.1 auth-request-type/at cred-type/sa"
51-
)
52-
ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
53-
"gl-python/3.7 auth/1.1 auth-request-type/it cred-type/sa"
54-
)
49+
ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/sa"
50+
ID_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/it cred-type/sa"
5551

5652

5753
@pytest.mark.parametrize("retryable", [True, False])

packages/google-auth/tests/oauth2/test_reauth.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,15 @@
4040
"encodedProofOfReauthToken": "new_rapt_token",
4141
}
4242

43-
REAUTH_START_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 auth-request-type/re-start"
43+
REAUTH_START_METRICS_HEADER_VALUE = (
44+
"gl-python/<python-version> auth/<library-version> auth-request-type/re-start"
45+
)
4446
REAUTH_CONTINUE_METRICS_HEADER_VALUE = (
45-
"gl-python/3.7 auth/1.1 auth-request-type/re-cont"
47+
"gl-python/<python-version> auth/<library-version> auth-request-type/re-cont"
48+
)
49+
TOKEN_REQUEST_METRICS_HEADER_VALUE = (
50+
"gl-python/<python-version> auth/<library-version> cred-type/u"
4651
)
47-
TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1 cred-type/u"
4852

4953

5054
class MockChallenge(object):

packages/google-auth/tests/test__default.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import json
1616
import os
17+
import sys
1718
from unittest import mock
1819
import warnings
1920

@@ -773,7 +774,9 @@ def test__get_gae_credentials_gen1(app_identity):
773774

774775
@mock.patch.dict(os.environ)
775776
def test__get_gae_credentials_gen2():
776-
os.environ["GAE_RUNTIME"] = "python37"
777+
os.environ[
778+
"GAE_RUNTIME"
779+
] = f"python{sys.version_info.major}{sys.version_info.minor}"
777780
credentials, project_id = _default._get_gae_credentials()
778781
assert credentials is None
779782
assert project_id is None
@@ -783,8 +786,9 @@ def test__get_gae_credentials_gen2():
783786
def test__get_gae_credentials_gen2_backwards_compat():
784787
# compat helpers may copy GAE_RUNTIME to APPENGINE_RUNTIME
785788
# for backwards compatibility with code that relies on it
786-
os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = "python37"
787-
os.environ["GAE_RUNTIME"] = "python37"
789+
current_runtime = f"python{sys.version_info.major}{sys.version_info.minor}"
790+
os.environ[environment_vars.LEGACY_APPENGINE_RUNTIME] = current_runtime
791+
os.environ["GAE_RUNTIME"] = current_runtime
788792
credentials, project_id = _default._get_gae_credentials()
789793
assert credentials is None
790794
assert project_id is None

packages/google-auth/tests/test_aws.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@
2828
from google.auth import transport
2929
from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN
3030

31-
IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = (
32-
"gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp"
33-
)
31+
IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version> auth-request-type/at cred-type/imp"
3432

35-
LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/3.7 auth/1.1"
33+
LANG_LIBRARY_METRICS_HEADER_VALUE = "gl-python/<python-version> auth/<library-version>"
3634

3735
CLIENT_ID = "username"
3836
CLIENT_SECRET = "password"
@@ -1913,7 +1911,7 @@ def test_refresh_success_without_impersonation_ignore_default_scopes(
19131911
token_headers = {
19141912
"Content-Type": "application/x-www-form-urlencoded",
19151913
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
1916-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws",
1914+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws",
19171915
}
19181916
token_request_data = {
19191917
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
@@ -1972,7 +1970,7 @@ def test_refresh_success_without_impersonation_use_default_scopes(
19721970
token_headers = {
19731971
"Content-Type": "application/x-www-form-urlencoded",
19741972
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
1975-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws",
1973+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/false config-lifetime/false source/aws",
19761974
}
19771975
token_request_data = {
19781976
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
@@ -2038,7 +2036,7 @@ def test_refresh_success_with_impersonation_ignore_default_scopes(
20382036
token_headers = {
20392037
"Content-Type": "application/x-www-form-urlencoded",
20402038
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
2041-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws",
2039+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws",
20422040
}
20432041
token_request_data = {
20442042
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
@@ -2133,7 +2131,7 @@ def test_refresh_success_with_impersonation_use_default_scopes(
21332131
token_headers = {
21342132
"Content-Type": "application/x-www-form-urlencoded",
21352133
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
2136-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws",
2134+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/true config-lifetime/false source/aws",
21372135
}
21382136
token_request_data = {
21392137
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
@@ -2328,7 +2326,7 @@ def test_refresh_success_with_supplier_with_impersonation(
23282326
token_headers = {
23292327
"Content-Type": "application/x-www-form-urlencoded",
23302328
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
2331-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/true config-lifetime/false source/programmatic",
2329+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/true config-lifetime/false source/programmatic",
23322330
}
23332331
token_request_data = {
23342332
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
@@ -2414,7 +2412,7 @@ def test_refresh_success_with_supplier(self, utcnow, mock_auth_lib_value):
24142412
token_headers = {
24152413
"Content-Type": "application/x-www-form-urlencoded",
24162414
"Authorization": "Basic " + BASIC_AUTH_ENCODING,
2417-
"x-goog-api-client": "gl-python/3.7 auth/1.1 google-byoid-sdk sa-impersonation/false config-lifetime/false source/programmatic",
2415+
"x-goog-api-client": "gl-python/<python-version> auth/<library-version> google-byoid-sdk sa-impersonation/false config-lifetime/false source/programmatic",
24182416
}
24192417
token_request_data = {
24202418
"grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",

0 commit comments

Comments
 (0)