From 7f11951c2623c5ec11178f553cbcb663dbe4bcb3 Mon Sep 17 00:00:00 2001 From: August L-R Date: Tue, 18 Aug 2026 21:45:50 +0000 Subject: [PATCH] fix(search): keep mypy clean under sentence-transformers 6.0.0 --- signalwire/signalwire/search/index_builder.py | 2 +- signalwire/signalwire/search/query_processor.py | 6 +++++- signalwire/signalwire/search/search_service.py | 7 +++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/signalwire/signalwire/search/index_builder.py b/signalwire/signalwire/search/index_builder.py index 71ab1b58..7c7b6277 100644 --- a/signalwire/signalwire/search/index_builder.py +++ b/signalwire/signalwire/search/index_builder.py @@ -164,7 +164,7 @@ def _extract_metadata_from_json_content( def _load_model(self) -> None: """Load embedding model (lazy loading)""" if self.model is None: - if not SentenceTransformer: + if SentenceTransformer is None: raise ImportError( "sentence-transformers is required for embedding generation. Install with: pip install sentence-transformers" ) diff --git a/signalwire/signalwire/search/query_processor.py b/signalwire/signalwire/search/query_processor.py index 8f69d988..6a3cfe2d 100644 --- a/signalwire/signalwire/search/query_processor.py +++ b/signalwire/signalwire/search/query_processor.py @@ -283,7 +283,11 @@ def _get_cached_model(model_name: str | None = None) -> Any: from sentence_transformers import SentenceTransformer logger.info(f"Loading sentence transformer model: {model_name}") - model = SentenceTransformer(model_name) + # `Any` because the tag below is a deliberate side channel: + # torch's Module.__setattr__ overloads accept only Tensor/Module, so + # a typed local rejects a str attribute. set_global_model() reads it + # back with getattr. Matches _model_cache's own dict[str, Any]. + model: Any = SentenceTransformer(model_name) # Store the model name for identification model.model_name = model_name # Evict oldest entry if cache is full diff --git a/signalwire/signalwire/search/search_service.py b/signalwire/signalwire/search/search_service.py index c54a320e..2d76e936 100644 --- a/signalwire/signalwire/search/search_service.py +++ b/signalwire/signalwire/search/search_service.py @@ -383,7 +383,10 @@ def _load_resources(self) -> None: f"Loading model {model_name} for collection {collection_name}" ) try: - model = SentenceTransformer(model_name) + # `Any`: see query_processor._get_cached_model. + # torch's Module.__setattr__ rejects a str attr; + # set_global_model() reads this tag via getattr. + model: Any = SentenceTransformer(model_name) model.model_name = ( model_name # Store for cache comparison ) @@ -408,7 +411,7 @@ def _load_resources(self) -> None: else: # SQLite backend - original behavior # Load model (shared across all indexes) - if self.indexes and SentenceTransformer: + if self.indexes and SentenceTransformer is not None: # Get model name from first index sample_index = next(iter(self.indexes.values())) model_name = self._get_model_name(sample_index)