fix(services/earnings): resolve google.cloud.storage via importlib so sys.modules stubs hold#111
Merged
Merged
Conversation
… sys.modules stubs hold
The jobs' lazy `from google.cloud import storage` sites were fragile against
namespace-package attribute binding: google.cloud is a PEP-420 namespace
package, and once the REAL google.cloud.storage submodule is imported anywhere
in the process (e.g. transitively via gcsfs under the [satellite] extra),
Python binds it as an attribute on the google.cloud package object. From then
on `from google.cloud import storage` reads that bound attribute and never
consults sys.modules — silently bypassing the tests'
`monkeypatch.setitem(sys.modules, "google.cloud.storage", fake)` and reaching
the real storage.Client() (12 failures in test_jobs_entrypoints.py +
test_stt_handoff_delete.py in any venv where gcsfs & co. are installed;
green in CI / fresh no-extras venvs where nothing pre-imports the real
submodule).
Fix: resolve the module through importlib.import_module("google.cloud.storage")
(a documented _load_gcs_storage helper in stt.py and capture.py), which
consults sys.modules FIRST — the injected fake wins regardless of import
order, and runtime behavior is byte-identical when no stub is present (same
real module object). google.cloud.pubsub_v1 sites are untouched: no installed
dep pre-imports the real pubsub submodule, so they are not affected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Parity ticket gate: PASSED See |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
google.cloudis a PEP-420 namespace package. The first real import ofgoogle.cloud.storageanywhere in a process (in dev venvs:gcsfs, pulled by the[satellite]extra, imports it transitively) binds it as an attribute on the parent package. From then on,from google.cloud import storagereads that bound attribute and never consultssys.modules— silently bypassing the test fakes installed viamonkeypatch.setitem(sys.modules, "google.cloud.storage", ...). Result: 12 tests inservices/earnings/tests/fail in any venv with the satellite deps installed (pass in isolation; CI green only because its minimal env never imports the real module).Fix
_load_gcs_storage()helper inservices/earnings/jobs/{stt,capture}.pyresolving viaimportlib.import_module("google.cloud.storage"), which consultssys.modulesfirst — injected fakes win regardless of import order; byte-identical behavior in production (same real module object). 3 import sites converted; +47/−4,services/earnings/jobs/only.Evidence
pytest -m "not live" -q→ 12 FAILED; same tests pass in isolation. Deterministic repro: pre-importgcsfs, run the 12.gcsfspre-imported.uv sync+pytest services/earnings/tests -m "not live"→ 170 passed, 9 skipped.Pre-existing on main (reproducible at 1ce7aab) — unrelated to the Phase 30 branch.
🤖 Generated with Claude Code