Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e646bcd
feat(auth): Implement PEP 0810 lazy loading in transport
hebaalazzeh Jul 8, 2026
bfc403f
fix: use hardcoded module names instead of __name__
hebaalazzeh Jul 8, 2026
8e528e9
Update packages/google-auth/google/auth/transport/__init__.py
hebaalazzeh Jul 9, 2026
af31035
test: add lazy imports fallback and tests for PEP 810
hebaalazzeh Jul 9, 2026
72548f9
fix: resolve linting errors and add license header
hebaalazzeh Jul 9, 2026
e982bc7
chore: fix test_lazy_imports.py to properly trigger module re-initial…
hebaalazzeh Jul 9, 2026
bc4ae32
chore: fix flake8 lint errors related to import ordering
hebaalazzeh Jul 10, 2026
f398718
chore: fix lint and formatting issues
hebaalazzeh Jul 10, 2026
bb5c39c
fix: update __lazy_modules__ targets to match import statements
hebaalazzeh Jul 10, 2026
a3a85a0
fix: typo aiohttp_requests to _aiohttp_requests
hebaalazzeh Jul 10, 2026
68eca51
fix: add type hint to __lazy_modules__
hebaalazzeh Jul 10, 2026
24ac419
chore: remove accidentally committed scratch files
hebaalazzeh Jul 10, 2026
eef11dc
chore: fix import order in __init__.py to satisfy flake8
hebaalazzeh Jul 10, 2026
73ac7e8
test: rewrite lazy imports test using subprocess to prevent test poll…
hebaalazzeh Jul 10, 2026
b528945
chore: run black on test_lazy_imports.py
hebaalazzeh Jul 10, 2026
cfde494
refactor: apply PEP 810 directly to transport modules instead of __in…
hebaalazzeh Jul 10, 2026
bcb18a4
chore: run black on transport modules
hebaalazzeh Jul 10, 2026
3eb6523
fix: flake8 import order errors for typing.Set
hebaalazzeh Jul 10, 2026
35e8bdc
fix: remaining flake8 errors in urllib3.py
hebaalazzeh Jul 10, 2026
5503252
chore: revert DEFAULT_PYTHON_VERSION to 3.14 in noxfile.py
hebaalazzeh Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/google-auth/google/auth/transport/grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from __future__ import absolute_import

import logging
from typing import Set

from google.auth import exceptions
from google.auth.transport import _mtls_helper
Expand All @@ -32,6 +33,8 @@

_LOGGER = logging.getLogger(__name__)

__lazy_modules__: Set[str] = {"grpc"}


class AuthMetadataPlugin(grpc.AuthMetadataPlugin):
"""A `gRPC AuthMetadataPlugin`_ that inserts the credentials into each
Expand Down
4 changes: 3 additions & 1 deletion packages/google-auth/google/auth/transport/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import logging
import numbers
import time
from typing import Optional
from typing import Optional, Set

try:
import requests
Expand All @@ -42,6 +42,8 @@
import google.auth.transport._mtls_helper
from google.oauth2 import service_account

__lazy_modules__: Set[str] = {"requests", "requests.adapters", "requests.exceptions"}

_LOGGER = logging.getLogger(__name__)

_DEFAULT_TIMEOUT = 120 # in seconds
Expand Down
10 changes: 10 additions & 0 deletions packages/google-auth/google/auth/transport/urllib3.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

from __future__ import absolute_import


import http.client as http_client
import logging
from typing import Set
import warnings

# Certifi is Mozilla's certificate bundle. Urllib3 needs a certificate bundle
Expand Down Expand Up @@ -56,6 +58,14 @@
from google.auth.transport import _mtls_helper
from google.oauth2 import service_account

__lazy_modules__: Set[str] = {
"urllib3",
"urllib3.exceptions",
"certifi",
"packaging",
"packaging.version",
}

if version.parse(urllib3.__version__) >= version.parse("2.0.0"): # pragma: NO COVER
RequestMethods = urllib3._request_methods.RequestMethods # type: ignore
else: # pragma: NO COVER
Expand Down
77 changes: 77 additions & 0 deletions packages/google-auth/tests/transport/test_lazy_imports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Copyright 2026 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 subprocess
import sys

import pytest

SCRIPT_PYTHON_315 = """
import sys
import google.auth.transport.requests
import google.auth.transport.urllib3
import google.auth.transport.grpc

# The heavy underlying modules should NOT be loaded yet
HEAVY_MODULES = ["requests", "urllib3", "grpc"]

for mod in HEAVY_MODULES:
if mod in sys.modules:
print(f"FAILED: {mod} was eagerly loaded into sys.modules")
sys.exit(1)

# Trigger reification
import requests
_ = requests.__name__

if "requests" not in sys.modules:
print("FAILED: requests was not lazily loaded upon access")
sys.exit(2)

sys.exit(0)
"""

SCRIPT_PRE_315 = """
import sys
import google.auth.transport.requests
import google.auth.transport.urllib3
import google.auth.transport.grpc

HEAVY_MODULES = ["requests", "urllib3", "grpc"]

for mod in HEAVY_MODULES:
if mod not in sys.modules:
print(f"FAILED: {mod} was not eagerly loaded into sys.modules")
sys.exit(1)

sys.exit(0)
"""


@pytest.mark.skipif(sys.version_info < (3, 15), reason="PEP 810 requires Python 3.15+")
def test_lazy_imports_on_python_315():
result = subprocess.run(
[sys.executable, "-c", SCRIPT_PYTHON_315], capture_output=True, text=True
)
assert result.returncode == 0, f"Subprocess failed: {result.stdout}"


@pytest.mark.skipif(
sys.version_info >= (3, 15), reason="Testing fallback behavior on < 3.15"
)
def test_fallback_eager_imports_pre_315():
result = subprocess.run(
[sys.executable, "-c", SCRIPT_PRE_315], capture_output=True, text=True
)
assert result.returncode == 0, f"Subprocess failed: {result.stdout}"
Loading