@@ -130,30 +130,61 @@ def load_with_download(self, model_path: Path, proxy: Optional[str] = None) -> A
130130 return self .load_local (model_path )
131131
132132 def _load_windows_compatible (self , model_path : Path ) -> Any :
133- """Handle Windows path compatibility issues."""
134- if re .match (r'^[A-Za-z0-9_/\\:.]*$' , str (model_path )):
135- return fasttext .load_model (str (model_path ))
133+ """
134+ Handle Windows path compatibility issues when loading FastText models.
136135
137- # Create a temporary file to handle special characters in the path
138- with tempfile . NamedTemporaryFile ( delete = False ) as tmp :
139- tmp_path = tmp . name
140- shutil . copy2 ( model_path , tmp_path )
136+ Attempts multiple strategies in order:
137+ 1. Direct loading if path contains only safe characters
138+ 2. Loading via relative path if possible
139+ 3. Copying to temporary file as last resort
141140
141+ :param model_path: Path to the model file
142+ :return: Loaded FastText model
143+ :raises DetectError: If all loading strategies fail
144+ """
145+ model_path_str = str (model_path .resolve ())
146+
147+ # Try to load model directly
142148 try :
143- model = fasttext .load_model (tmp_path )
144- return model
149+ return fasttext .load_model (model_path_str )
150+ except Exception as e :
151+ logger .debug (f"fast-langdetect: Load model failed: { e } " )
152+
153+ # Try to load model using relative path
154+ try :
155+ cwd = Path .cwd ()
156+ rel_path = os .path .relpath (model_path , cwd )
157+ return fasttext .load_model (rel_path )
158+ except Exception as e :
159+ logger .debug (f"fast-langdetect: Failed to load model using relative path: { e } " )
160+
161+ # Use temporary file as last resort
162+ logger .debug (f"fast-langdetect: Using temporary file to load model: { model_path } " )
163+ tmp_path = None
164+ try :
165+ # Use NamedTemporaryFile to create a temporary file
166+ tmp_fd , tmp_path = tempfile .mkstemp (suffix = '.bin' )
167+ os .close (tmp_fd ) # Close file descriptor
168+
169+ # Copy model file to temporary location
170+ shutil .copy2 (model_path , tmp_path )
171+ return fasttext .load_model (tmp_path )
172+ except Exception as e :
173+ raise DetectError (f"Failed to load model using temporary file: { e } " )
145174 finally :
146- try :
147- os .unlink (tmp_path )
148- except (OSError , PermissionError ) as e :
149- logger .warning (f"fast-langdetect: Failed to delete temporary file { tmp_path } : { e } " )
150- # Schedule file for deletion on next reboot on Windows
151- if platform .system () == "Windows" :
152- try :
153- import _winapi
154- _winapi .MoveFileEx (tmp_path , None , _winapi .MOVEFILE_DELAY_UNTIL_REBOOT )
155- except (ImportError , AttributeError , OSError ) as we :
156- logger .warning (f"fast-langdetect: Failed to schedule file deletion: { we } " )
175+ # Clean up temporary file
176+ if tmp_path and os .path .exists (tmp_path ):
177+ try :
178+ os .unlink (tmp_path )
179+ except (OSError , PermissionError ) as e :
180+ logger .warning (f"fast-langdetect: Failed to delete temporary file { tmp_path } : { e } " )
181+ # Plan to delete on next reboot on Windows
182+ if platform .system () == "Windows" :
183+ try :
184+ import _winapi
185+ _winapi .MoveFileEx (tmp_path , None , _winapi .MOVEFILE_DELAY_UNTIL_REBOOT )
186+ except (ImportError , AttributeError , OSError ) as we :
187+ logger .warning (f"fast-langdetect: Failed to schedule file deletion: { we } " )
157188
158189 def _load_unix (self , model_path : Path ) -> Any :
159190 """Load model on Unix-like systems."""
0 commit comments