perf(api): avoid lazy module lookups in Redis test fixtures

This commit is contained in:
Stephen Zhou authored and GitHub committed 2026-09-29 07:54:22 +00:00
1 parent af7f6abb95
commit 0d1bd869ad
2 files changed
+57 -8

No files matched your search

+14 -8
View File
@@ -2,9 +2,11 @@ from __future__ import annotations
import os
import shutil
import sys
from collections.abc import Callable, Iterator
from pathlib import Path
from tempfile import TemporaryDirectory
from types import ModuleType
from typing import TYPE_CHECKING
from unittest.mock import MagicMock, patch
@@ -53,16 +55,20 @@ if TYPE_CHECKING:
def _patch_redis_clients_on_loaded_modules() -> None:
"""Ensure any module-level redis_client references point to the shared redis_mock."""
"""Rebind concrete module globals without invoking module-level ``__getattr__``.
import sys
for module in list(sys.modules.values()):
if module is None:
Inspect each time so late imports, reloads, and newly added globals are still
covered. Attribute lookup on thousands of unrelated lazy modules is costly
and can itself trigger imports; only stored references need rebinding.
"""
for module in sys.modules.copy().values():
if not isinstance(module, ModuleType):
continue
for client_attribute in ("redis_client", "_pubsub_redis_client"):
if hasattr(module, client_attribute):
setattr(module, client_attribute, redis_mock)
namespace = module.__dict__
if "redis_client" in namespace:
namespace["redis_client"] = redis_mock
if "_pubsub_redis_client" in namespace:
namespace["_pubsub_redis_client"] = redis_mock
@pytest.fixture
@@ -0,0 +1,43 @@
import sys
from types import ModuleType
import pytest
from tests.unit_tests.conftest import _patch_redis_clients_on_loaded_modules, redis_mock
@pytest.mark.parametrize("attribute", ["redis_client", "_pubsub_redis_client"])
def test_redis_rebinding_covers_new_globals_and_replaced_modules(
monkeypatch: pytest.MonkeyPatch, attribute: str
) -> None:
name = "_redis_fixture_probe"
module = ModuleType(name)
monkeypatch.setitem(sys.modules, name, module)
_patch_redis_clients_on_loaded_modules()
# A module can gain a reference after it was already seen by another test.
setattr(module, attribute, object())
_patch_redis_clients_on_loaded_modules()
assert vars(module)[attribute] is redis_mock
# Rebind on every test, even when the set of imported modules is unchanged.
setattr(module, attribute, object())
_patch_redis_clients_on_loaded_modules()
assert vars(module)[attribute] is redis_mock
replacement = ModuleType(name)
setattr(replacement, attribute, object())
monkeypatch.setitem(sys.modules, name, replacement)
_patch_redis_clients_on_loaded_modules()
assert vars(replacement)[attribute] is redis_mock
def test_redis_rebinding_does_not_resolve_lazy_module_attributes(monkeypatch: pytest.MonkeyPatch) -> None:
module = ModuleType("_lazy_redis_fixture_probe")
def resolve(name: str) -> object:
pytest.fail(f"Redis rebinding must not import unrelated lazy attributes: {name}")
vars(module)["__getattr__"] = resolve
monkeypatch.setitem(sys.modules, module.__name__, module)
_patch_redis_clients_on_loaded_modules()