chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.abc
|
||||
import sys
|
||||
from types import ModuleType
|
||||
|
||||
import pytest
|
||||
|
||||
_PACKAGE_EXPORTS: tuple[tuple[str, str, str, str, str], ...] = (
|
||||
(
|
||||
"EncryptedSession",
|
||||
"agents.extensions.memory.encrypt_session",
|
||||
"agents.extensions.memory.encrypt_session",
|
||||
"cryptography",
|
||||
"encrypt",
|
||||
),
|
||||
("RedisSession", "agents.extensions.memory.redis_session", "redis.asyncio", "redis", "redis"),
|
||||
(
|
||||
"SQLAlchemySession",
|
||||
"agents.extensions.memory.sqlalchemy_session",
|
||||
"agents.extensions.memory.sqlalchemy_session",
|
||||
"sqlalchemy",
|
||||
"sqlalchemy",
|
||||
),
|
||||
("DaprSession", "agents.extensions.memory.dapr_session", "dapr.aio.clients", "dapr", "dapr"),
|
||||
(
|
||||
"DAPR_CONSISTENCY_EVENTUAL",
|
||||
"agents.extensions.memory.dapr_session",
|
||||
"dapr.aio.clients",
|
||||
"dapr",
|
||||
"dapr",
|
||||
),
|
||||
(
|
||||
"DAPR_CONSISTENCY_STRONG",
|
||||
"agents.extensions.memory.dapr_session",
|
||||
"dapr.aio.clients",
|
||||
"dapr",
|
||||
"dapr",
|
||||
),
|
||||
(
|
||||
"MongoDBSession",
|
||||
"agents.extensions.memory.mongodb_session",
|
||||
"pymongo.asynchronous.collection",
|
||||
"mongodb",
|
||||
"mongodb",
|
||||
),
|
||||
)
|
||||
|
||||
_DIRECT_MODULE_IMPORTS: tuple[tuple[str, str, str, str], ...] = (
|
||||
("agents.extensions.memory.redis_session", "redis.asyncio", "redis", "redis"),
|
||||
("agents.extensions.memory.dapr_session", "dapr.aio.clients", "dapr", "dapr"),
|
||||
(
|
||||
"agents.extensions.memory.mongodb_session",
|
||||
"pymongo.asynchronous.collection",
|
||||
"mongodb",
|
||||
"mongodb",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class _BrokenImportFinder(importlib.abc.MetaPathFinder):
|
||||
def __init__(self, broken_module: str, error_cls: type[ImportError]) -> None:
|
||||
self._broken_module = broken_module
|
||||
self._error_cls = error_cls
|
||||
|
||||
def find_spec(
|
||||
self,
|
||||
fullname: str,
|
||||
path: object | None,
|
||||
target: ModuleType | None = None,
|
||||
) -> None:
|
||||
if fullname == self._broken_module:
|
||||
raise self._error_cls("simulated dependency import failure")
|
||||
return None
|
||||
|
||||
|
||||
def _reset_package_imports(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
memory_module: ModuleType,
|
||||
symbol: str,
|
||||
module_name: str,
|
||||
broken_module: str,
|
||||
) -> None:
|
||||
monkeypatch.delitem(memory_module.__dict__, symbol, raising=False)
|
||||
_reset_loaded_module(monkeypatch, module_name)
|
||||
_reset_loaded_module(monkeypatch, broken_module)
|
||||
|
||||
|
||||
def _reset_loaded_module(monkeypatch: pytest.MonkeyPatch, module_name: str) -> None:
|
||||
monkeypatch.delitem(sys.modules, module_name, raising=False)
|
||||
parent_name, short_name = module_name.rsplit(".", 1)
|
||||
parent_module = sys.modules.get(parent_name)
|
||||
if parent_module is not None:
|
||||
monkeypatch.delitem(parent_module.__dict__, short_name, raising=False)
|
||||
|
||||
|
||||
def _reset_module_imports(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
module_name: str,
|
||||
broken_module: str,
|
||||
) -> None:
|
||||
_reset_loaded_module(monkeypatch, module_name)
|
||||
_reset_loaded_module(monkeypatch, broken_module)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("symbol", "module_name", "broken_module", "dependency_name", "extra_name"),
|
||||
_PACKAGE_EXPORTS,
|
||||
)
|
||||
def test_memory_package_imports_point_to_optional_extra(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
symbol: str,
|
||||
module_name: str,
|
||||
broken_module: str,
|
||||
dependency_name: str,
|
||||
extra_name: str,
|
||||
) -> None:
|
||||
import agents.extensions.memory as memory_module
|
||||
|
||||
_reset_package_imports(monkeypatch, memory_module, symbol, module_name, broken_module)
|
||||
finder = _BrokenImportFinder(broken_module, ModuleNotFoundError)
|
||||
monkeypatch.setattr(sys, "meta_path", [finder, *sys.meta_path])
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
getattr(memory_module, symbol)
|
||||
|
||||
assert f"requires the '{dependency_name}' extra" in str(exc_info.value)
|
||||
assert f"openai-agents[{extra_name}]" in str(exc_info.value)
|
||||
assert isinstance(exc_info.value.__cause__, ImportError)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("module_name", "broken_module", "dependency_name", "extra_name"),
|
||||
_DIRECT_MODULE_IMPORTS,
|
||||
)
|
||||
@pytest.mark.parametrize("error_cls", [ImportError, ModuleNotFoundError])
|
||||
def test_memory_direct_module_imports_point_to_optional_extra(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
module_name: str,
|
||||
broken_module: str,
|
||||
dependency_name: str,
|
||||
extra_name: str,
|
||||
error_cls: type[ImportError],
|
||||
) -> None:
|
||||
_reset_module_imports(monkeypatch, module_name, broken_module)
|
||||
finder = _BrokenImportFinder(broken_module, error_cls)
|
||||
monkeypatch.setattr(sys, "meta_path", [finder, *sys.meta_path])
|
||||
|
||||
with pytest.raises(ImportError) as exc_info:
|
||||
__import__(module_name)
|
||||
|
||||
assert f"requires the '{dependency_name}' extra" in str(exc_info.value)
|
||||
assert f"openai-agents[{extra_name}]" in str(exc_info.value)
|
||||
assert isinstance(exc_info.value.__cause__, ImportError)
|
||||
Reference in New Issue
Block a user