refactor: 简化 __getattr__ 和测试 helper (ce-simplify-code)
core/exceptions.py: - __getattr__ 用循环 + getattr 替代三处显式列举异常名 - 异常名只在 _LLM_EXCEPTION_NAMES 中定义一次,新增异常只改元组 test_memory_models.py: - 提取 _assert_uuid_default/_assert_utc_default/_assert_unique_ids helper - 消除 TestEpisodeModel 与 TestExperienceModel 间 3 个方法的复制粘贴 行为保持不变:52 tests passed,ruff clean,import 兼容性验证通过。
This commit is contained in:
parent
e0a22e0447
commit
a4d3f227a6
|
|
@ -146,15 +146,10 @@ _LLM_EXCEPTION_NAMES = ("LLMError", "LLMProviderError", "ModelNotFoundError")
|
|||
|
||||
def __getattr__(name: str): # PEP 562
|
||||
if name in _LLM_EXCEPTION_NAMES:
|
||||
from agentkit.llm.exceptions import ( # noqa: PLC0415
|
||||
LLMError,
|
||||
LLMProviderError,
|
||||
ModelNotFoundError,
|
||||
)
|
||||
import agentkit.llm.exceptions as _llm_exc # noqa: PLC0415
|
||||
|
||||
globals()["LLMError"] = LLMError
|
||||
globals()["LLMProviderError"] = LLMProviderError
|
||||
globals()["ModelNotFoundError"] = ModelNotFoundError
|
||||
for n in _LLM_EXCEPTION_NAMES:
|
||||
globals()[n] = getattr(_llm_exc, n)
|
||||
return globals()[name]
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,26 @@ from sqlalchemy.dialects.postgresql import JSONB
|
|||
from agentkit.memory.models import EpisodeModel, ExperienceModel
|
||||
|
||||
|
||||
def _assert_uuid_default(id_default) -> None:
|
||||
"""SQLAlchemy wraps Python-side default callables to receive an execution
|
||||
context; pass None for callables that don't inspect it."""
|
||||
val = id_default(None)
|
||||
assert isinstance(val, str)
|
||||
uuid.UUID(val) # raises ValueError if not a valid uuid4 string
|
||||
|
||||
|
||||
def _assert_utc_default(ts_default) -> None:
|
||||
ts = ts_default(None)
|
||||
assert isinstance(ts, datetime)
|
||||
assert ts.tzinfo is not None
|
||||
assert ts.utcoffset() == timezone.utc.utcoffset(None)
|
||||
|
||||
|
||||
def _assert_unique_ids(id_default, n: int = 100) -> None:
|
||||
ids = {id_default(None) for _ in range(n)}
|
||||
assert len(ids) == n
|
||||
|
||||
|
||||
class TestEpisodeModel:
|
||||
def test_tablename(self):
|
||||
assert EpisodeModel.__tablename__ == "episodic_memories"
|
||||
|
|
@ -70,24 +90,13 @@ class TestEpisodeModel:
|
|||
assert cols.quality_score.default.arg == 0.5
|
||||
|
||||
def test_callable_default_id_is_uuid_string(self):
|
||||
# SQLAlchemy wraps Python-side default callables to receive an execution
|
||||
# context; pass None for callables that don't inspect it.
|
||||
id_default = EpisodeModel.__table__.c.id.default.arg
|
||||
val = id_default(None)
|
||||
assert isinstance(val, str)
|
||||
uuid.UUID(val) # raises ValueError if not a valid uuid4 string
|
||||
_assert_uuid_default(EpisodeModel.__table__.c.id.default.arg)
|
||||
|
||||
def test_callable_default_created_at_is_utc(self):
|
||||
ts_default = EpisodeModel.__table__.c.created_at.default.arg
|
||||
ts = ts_default(None)
|
||||
assert isinstance(ts, datetime)
|
||||
assert ts.tzinfo is not None
|
||||
assert ts.utcoffset() == timezone.utc.utcoffset(None)
|
||||
_assert_utc_default(EpisodeModel.__table__.c.created_at.default.arg)
|
||||
|
||||
def test_default_id_is_unique_across_calls(self):
|
||||
id_default = EpisodeModel.__table__.c.id.default.arg
|
||||
ids = {id_default(None) for _ in range(100)}
|
||||
assert len(ids) == 100
|
||||
_assert_unique_ids(EpisodeModel.__table__.c.id.default.arg)
|
||||
|
||||
def test_construct_with_explicit_values(self):
|
||||
ts = datetime(2025, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
||||
|
|
@ -202,22 +211,13 @@ class TestExperienceModel:
|
|||
assert cols.optimization_tips.default.arg(None) == []
|
||||
|
||||
def test_callable_default_id_is_uuid_string(self):
|
||||
id_default = ExperienceModel.__table__.c.id.default.arg
|
||||
val = id_default(None)
|
||||
assert isinstance(val, str)
|
||||
uuid.UUID(val)
|
||||
_assert_uuid_default(ExperienceModel.__table__.c.id.default.arg)
|
||||
|
||||
def test_callable_default_created_at_is_utc(self):
|
||||
ts_default = ExperienceModel.__table__.c.created_at.default.arg
|
||||
ts = ts_default(None)
|
||||
assert isinstance(ts, datetime)
|
||||
assert ts.tzinfo is not None
|
||||
assert ts.utcoffset() == timezone.utc.utcoffset(None)
|
||||
_assert_utc_default(ExperienceModel.__table__.c.created_at.default.arg)
|
||||
|
||||
def test_default_id_is_unique_across_calls(self):
|
||||
id_default = ExperienceModel.__table__.c.id.default.arg
|
||||
ids = {id_default(None) for _ in range(100)}
|
||||
assert len(ids) == 100
|
||||
_assert_unique_ids(ExperienceModel.__table__.c.id.default.arg)
|
||||
|
||||
def test_construct_with_explicit_values(self):
|
||||
ts = datetime(2025, 6, 7, 8, 9, 10, tzinfo=timezone.utc)
|
||||
|
|
|
|||
Loading…
Reference in New Issue