@@ -130,30 +130,67 @@ 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
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+ # 策略1: 直接加载安全路径
148+ if re .match (r'^[A-Za-z0-9_/\\:.\-]*$' , model_path_str ):
149+ try :
150+ return fasttext .load_model (model_path_str )
151+ except Exception as e :
152+ logger .debug (f"fast-langdetect: Direct loading failed: { e } " )
141153
154+ # 策略2: 尝试使用相对路径
142155 try :
143- model = fasttext .load_model (tmp_path )
144- return model
156+ cwd = Path .cwd ().resolve ()
157+ # 检查模型路径是否在当前工作目录下
158+ if str (model_path ).startswith (str (cwd )) or model_path_str .upper ().startswith (str (cwd ).upper ()):
159+ rel_path = os .path .relpath (model_path , cwd )
160+ if re .match (r'^[A-Za-z0-9_/\\:.\-]*$' , rel_path ):
161+ return fasttext .load_model (rel_path )
162+ except Exception as e :
163+ logger .debug (f"fast-langdetect: Relative path loading failed: { e } " )
164+
165+ # 策略3: 使用临时文件作为最后手段
166+ logger .debug (f"fast-langdetect: Using temporary file for model: { model_path } " )
167+ tmp_path = None
168+ try :
169+ with tempfile .NamedTemporaryFile (delete = False ) as tmp :
170+ tmp_path = tmp .name
171+
172+ shutil .copy2 (model_path , tmp_path )
173+ return fasttext .load_model (tmp_path )
174+ except Exception as e :
175+ if tmp_path and os .path .exists (tmp_path ):
176+ try :
177+ os .unlink (tmp_path )
178+ except :
179+ pass
180+ raise DetectError (f"Failed to load model via temporary file: { e } " )
145181 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 } " )
182+ if tmp_path and os .path .exists (tmp_path ):
183+ try :
184+ os .unlink (tmp_path )
185+ except (OSError , PermissionError ) as e :
186+ logger .warning (f"fast-langdetect: Failed to delete temporary file { tmp_path } : { e } " )
187+ # 在Windows上计划在下次重启时删除
188+ if platform .system () == "Windows" :
189+ try :
190+ import _winapi
191+ _winapi .MoveFileEx (tmp_path , None , _winapi .MOVEFILE_DELAY_UNTIL_REBOOT )
192+ except (ImportError , AttributeError , OSError ) as we :
193+ logger .warning (f"fast-langdetect: Failed to schedule file deletion: { we } " )
157194
158195 def _load_unix (self , model_path : Path ) -> Any :
159196 """Load model on Unix-like systems."""
0 commit comments