@@ -130,30 +130,61 @@ def load_with_download(self, model_path: Path, proxy: Optional[str] = None) -> A
130
130
return self .load_local (model_path )
131
131
132
132
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.
136
135
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
141
140
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
142
148
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 } " )
145
174
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 } " )
157
188
158
189
def _load_unix (self , model_path : Path ) -> Any :
159
190
"""Load model on Unix-like systems."""
0 commit comments