@@ -183,11 +183,13 @@ def test_gliner_import_error_on_creation(self):
183183 original_gliner = sys .modules .pop ("gliner" , None )
184184
185185 try :
186- # Mock the import to raise ImportError
187- with patch (
188- "builtins.__import__" ,
189- side_effect = ImportError ("No module named 'gliner'" ),
190- ):
186+ # Re-import the module to test import failure
187+
188+ if "datafog.processing.text_processing.gliner_annotator" in sys .modules :
189+ del sys .modules ["datafog.processing.text_processing.gliner_annotator" ]
190+
191+ # Mock only the gliner import
192+ with patch .dict ("sys.modules" , {"gliner" : None }):
191193 from datafog .processing .text_processing .gliner_annotator import (
192194 GLiNERAnnotator ,
193195 )
@@ -200,18 +202,29 @@ def test_gliner_import_error_on_creation(self):
200202 # Restore gliner module
201203 if original_gliner :
202204 sys .modules ["gliner" ] = original_gliner
205+ else :
206+ # Restore our mock
207+ mock_gliner = MagicMock ()
208+ mock_gliner_class = MagicMock ()
209+ mock_model = MagicMock ()
210+ mock_model .predict_entities .return_value = []
211+ mock_gliner_class .from_pretrained .return_value = mock_model
212+ mock_gliner .GLiNER = mock_gliner_class
213+ sys .modules ["gliner" ] = mock_gliner
203214
204215 def test_gliner_import_error_on_download (self ):
205216 """Test that ImportError is raised when trying to download without GLiNER."""
206217 # Temporarily remove gliner from sys.modules
207218 original_gliner = sys .modules .pop ("gliner" , None )
208219
209220 try :
210- # Mock the import to raise ImportError
211- with patch (
212- "builtins.__import__" ,
213- side_effect = ImportError ("No module named 'gliner'" ),
214- ):
221+ # Re-import the module to test import failure
222+
223+ if "datafog.processing.text_processing.gliner_annotator" in sys .modules :
224+ del sys .modules ["datafog.processing.text_processing.gliner_annotator" ]
225+
226+ # Mock only the gliner import
227+ with patch .dict ("sys.modules" , {"gliner" : None }):
215228 from datafog .processing .text_processing .gliner_annotator import (
216229 GLiNERAnnotator ,
217230 )
@@ -224,6 +237,15 @@ def test_gliner_import_error_on_download(self):
224237 # Restore gliner module
225238 if original_gliner :
226239 sys .modules ["gliner" ] = original_gliner
240+ else :
241+ # Restore our mock
242+ mock_gliner = MagicMock ()
243+ mock_gliner_class = MagicMock ()
244+ mock_model = MagicMock ()
245+ mock_model .predict_entities .return_value = []
246+ mock_gliner_class .from_pretrained .return_value = mock_model
247+ mock_gliner .GLiNER = mock_gliner_class
248+ sys .modules ["gliner" ] = mock_gliner
227249
228250
229251class TestTextServiceGLiNERIntegration :
@@ -254,7 +276,9 @@ def mock_gliner_annotator(self):
254276
255277 def test_text_service_gliner_engine_init (self ):
256278 """Test TextService initialization with GLiNER engine."""
257- with patch ("datafog.services.text_service.GLiNERAnnotator" ):
279+ with patch (
280+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator"
281+ ):
258282 from datafog .services .text_service import TextService
259283
260284 service = TextService (engine = "gliner" )
@@ -263,15 +287,19 @@ def test_text_service_gliner_engine_init(self):
263287
264288 def test_text_service_gliner_engine_custom_model (self ):
265289 """Test TextService with custom GLiNER model."""
266- with patch ("datafog.services.text_service.GLiNERAnnotator" ):
290+ with patch (
291+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator"
292+ ):
267293 from datafog .services .text_service import TextService
268294
269295 service = TextService (engine = "gliner" , gliner_model = "urchade/gliner_base" )
270296 assert service .gliner_model == "urchade/gliner_base"
271297
272298 def test_text_service_smart_engine_init (self ):
273299 """Test TextService initialization with smart cascading engine."""
274- with patch ("datafog.services.text_service.GLiNERAnnotator" ):
300+ with patch (
301+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator"
302+ ):
275303 from datafog .services .text_service import TextService
276304
277305 service = TextService (engine = "smart" )
@@ -280,7 +308,8 @@ def test_text_service_smart_engine_init(self):
280308 def test_text_service_gliner_engine_without_dependencies (self ):
281309 """Test TextService GLiNER engine raises ImportError when dependencies missing."""
282310 with patch (
283- "datafog.services.text_service.GLiNERAnnotator" , side_effect = ImportError ()
311+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator" ,
312+ side_effect = ImportError (),
284313 ):
285314 from datafog .services .text_service import TextService
286315
@@ -292,7 +321,8 @@ def test_text_service_gliner_engine_without_dependencies(self):
292321 def test_text_service_smart_engine_without_dependencies (self ):
293322 """Test TextService smart engine raises ImportError when GLiNER dependencies missing."""
294323 with patch (
295- "datafog.services.text_service.GLiNERAnnotator" , side_effect = ImportError ()
324+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator" ,
325+ side_effect = ImportError (),
296326 ):
297327 from datafog .services .text_service import TextService
298328
@@ -306,19 +336,26 @@ def test_text_service_valid_engines(self):
306336 valid_engines = ["regex" , "spacy" , "gliner" , "auto" , "smart" ]
307337
308338 for engine in valid_engines :
309- # Mock dependencies based on engine
339+ # Mock dependencies based on engine at the correct import paths
310340 patches = {}
311341 if engine in ["spacy" , "auto" ]:
312- patches ["SpacyPIIAnnotator" ] = Mock ()
342+ patches [
343+ "datafog.processing.text_processing.spacy_pii_annotator.SpacyPIIAnnotator"
344+ ] = Mock ()
313345 if engine in ["gliner" , "smart" ]:
314- patches ["GLiNERAnnotator" ] = Mock ()
346+ patches [
347+ "datafog.processing.text_processing.gliner_annotator.GLiNERAnnotator"
348+ ] = Mock ()
315349
316350 if patches :
317- with patch .multiple ("datafog.services.text_service" , ** patches ):
318- from datafog .services .text_service import TextService
351+ with patch .dict (
352+ "sys.modules" , {k .rsplit ("." , 1 )[0 ]: Mock () for k in patches .keys ()}
353+ ):
354+ with patch .multiple (patches ):
355+ from datafog .services .text_service import TextService
319356
320- service = TextService (engine = engine )
321- assert service .engine == engine
357+ service = TextService (engine = engine )
358+ assert service .engine == engine
322359 else :
323360 from datafog .services .text_service import TextService
324361
@@ -360,12 +397,14 @@ def test_cascade_should_stop_logic(self, engine, expected_count):
360397
361398 def test_smart_cascade_flow (self , mock_gliner_annotator ):
362399 """Test the smart cascading flow."""
363- with patch ("datafog.services.text_service.RegexAnnotator" ) as mock_regex_cls :
400+ with patch (
401+ "datafog.processing.text_processing.regex_annotator.regex_annotator.RegexAnnotator"
402+ ) as mock_regex_cls :
364403 with patch (
365- "datafog.services.text_service .GLiNERAnnotator"
404+ "datafog.processing.text_processing.gliner_annotator .GLiNERAnnotator"
366405 ) as mock_gliner_cls :
367406 with patch (
368- "datafog.services.text_service .SpacyPIIAnnotator"
407+ "datafog.processing.text_processing.spacy_pii_annotator .SpacyPIIAnnotator"
369408 ) as mock_spacy_cls :
370409
371410 # Configure mocks
0 commit comments