1+ import sys
2+ import types
3+
14import pytest
25
36from rs_embed .core import registry
7+ from rs_embed .embedders import catalog
48
59# ── fixture to isolate registry between tests ──────────────────────
610
@@ -17,6 +21,26 @@ def clean_registry():
1721 registry ._REGISTRY_IMPORT_ERRORS .clear ()
1822
1923
24+ def _install_fake_lazy_model (
25+ monkeypatch ,
26+ * ,
27+ model_id : str ,
28+ module_name : str ,
29+ class_name : str ,
30+ alias : str | None = None ,
31+ ):
32+ monkeypatch .setitem (catalog .MODEL_SPECS , model_id , (module_name , class_name ))
33+ if alias is not None :
34+ monkeypatch .setitem (catalog .MODEL_ALIASES , alias , model_id )
35+
36+ fqmn = f"rs_embed.embedders.{ module_name } "
37+ mod = types .ModuleType (fqmn )
38+ cls = type (class_name , (), {})
39+ setattr (mod , class_name , cls )
40+ monkeypatch .setitem (sys .modules , fqmn , mod )
41+ return fqmn , cls
42+
43+
2044# ══════════════════════════════════════════════════════════════════════
2145# register + get_embedder_cls
2246# ══════════════════════════════════════════════════════════════════════
@@ -112,6 +136,12 @@ def test_get_embedder_cls_includes_last_import_error(monkeypatch):
112136
113137
114138def test_get_embedder_cls_lazy_imports_builtin_without_bulk_package_import (monkeypatch ):
139+ fqmn , cls_expected = _install_fake_lazy_model (
140+ monkeypatch ,
141+ model_id = "fake_lazy" ,
142+ module_name = "onthefly_test_lazy" ,
143+ class_name = "FakeLazyEmbedder" ,
144+ )
115145 calls = []
116146 orig_import_module = registry .importlib .import_module
117147
@@ -121,17 +151,52 @@ def _spy(name, *args, **kwargs):
121151
122152 monkeypatch .setattr (registry .importlib , "import_module" , _spy )
123153
124- cls = registry .get_embedder_cls ("remoteclip" )
125- assert cls .__name__ == "RemoteCLIPS2RGBEmbedder"
126- assert "remoteclip" in registry .list_models ()
127- assert "remoteclip_s2rgb" not in registry .list_models ()
154+ cls = registry .get_embedder_cls ("fake_lazy" )
155+ assert cls is cls_expected
156+ assert "fake_lazy" in registry .list_models ()
128157 assert "rs_embed.embedders" not in calls
129- assert "rs_embed.embedders.onthefly_remoteclip" in calls
158+ assert fqmn in calls
159+
160+
161+ def test_get_embedder_cls_cleans_failed_lazy_import_modules (monkeypatch ):
162+ from rs_embed .core .errors import ModelError
163+
164+ model_id = "fake_lazy_fail"
165+ module_name = "onthefly_test_lazy_fail"
166+ class_name = "FakeLazyFailEmbedder"
167+ monkeypatch .setitem (catalog .MODEL_SPECS , model_id , (module_name , class_name ))
168+ fqmn = f"rs_embed.embedders.{ module_name } "
169+ vendor_name = "rs_embed.embedders._vendor.fake_test_lazy_fail"
170+ orig_import_module = registry .importlib .import_module
171+
172+ def _boom (name , * args , ** kwargs ):
173+ if name == fqmn :
174+ sys .modules [fqmn ] = types .ModuleType (fqmn )
175+ sys .modules [vendor_name ] = types .ModuleType (vendor_name )
176+ raise RuntimeError ("boom" )
177+ return orig_import_module (name , * args , ** kwargs )
178+
179+ monkeypatch .setattr (registry .importlib , "import_module" , _boom )
130180
181+ with pytest .raises (ModelError , match = "RuntimeError: boom" ):
182+ registry .get_embedder_cls (model_id )
131183
132- def test_get_embedder_cls_accepts_legacy_alias ():
133- cls_new = registry .get_embedder_cls ("remoteclip" )
134- cls_old = registry .get_embedder_cls ("remoteclip_s2rgb" )
184+ assert fqmn not in sys .modules
185+ assert vendor_name not in sys .modules
186+
187+
188+ def test_get_embedder_cls_accepts_legacy_alias (monkeypatch ):
189+ _ , cls_expected = _install_fake_lazy_model (
190+ monkeypatch ,
191+ model_id = "fake_alias_target" ,
192+ module_name = "onthefly_test_lazy_alias" ,
193+ class_name = "FakeAliasEmbedder" ,
194+ alias = "fake_alias_old" ,
195+ )
196+
197+ cls_new = registry .get_embedder_cls ("fake_alias_target" )
198+ cls_old = registry .get_embedder_cls ("fake_alias_old" )
199+ assert cls_new is cls_expected
135200 assert cls_old is cls_new
136201
137202
@@ -151,9 +216,18 @@ def test_get_embedder_cls_accepts_satmaepp_s2_aliases():
151216 assert cls_alt is cls_new
152217
153218
154- def test_get_embedder_cls_can_reregister_when_registry_was_cleared ():
155- cls1 = registry .get_embedder_cls ("remoteclip" )
219+ def test_get_embedder_cls_can_reregister_when_registry_was_cleared (monkeypatch ):
220+ _ , cls_expected = _install_fake_lazy_model (
221+ monkeypatch ,
222+ model_id = "fake_reregister" ,
223+ module_name = "onthefly_test_lazy_reregister" ,
224+ class_name = "FakeReregisterEmbedder" ,
225+ alias = "fake_reregister_old" ,
226+ )
227+
228+ cls1 = registry .get_embedder_cls ("fake_reregister" )
156229 registry ._REGISTRY .clear ()
157- cls2 = registry .get_embedder_cls ("remoteclip_s2rgb" )
230+ cls2 = registry .get_embedder_cls ("fake_reregister_old" )
231+ assert cls1 is cls_expected
158232 assert cls2 is cls1
159- assert registry .get_embedder_cls ("remoteclip " ) is cls1
233+ assert registry .get_embedder_cls ("fake_reregister " ) is cls1
0 commit comments