@@ -248,3 +248,58 @@ def test_is_read_only_mode_conflict(self):
248248 is_read_only_mode ()
249249 self .assertIn ("PYTHAINLP_READ_ONLY" , str (ctx .exception ))
250250 self .assertIn ("PYTHAINLP_READ_MODE" , str (ctx .exception ))
251+
252+ def test_get_pythainlp_data_path_no_makedirs_in_read_only (self ):
253+ """Test that get_pythainlp_data_path skips makedirs in read-only mode."""
254+ with tempfile .TemporaryDirectory () as tmpdir :
255+ new_dir = os .path .join (tmpdir , "new-pythainlp-data" )
256+ with patch .dict (
257+ os .environ ,
258+ {"PYTHAINLP_DATA" : new_dir , "PYTHAINLP_READ_ONLY" : "1" },
259+ clear = False ,
260+ ):
261+ os .environ .pop ("PYTHAINLP_DATA_DIR" , None )
262+ os .environ .pop ("PYTHAINLP_READ_MODE" , None )
263+ path = get_pythainlp_data_path ()
264+ self .assertEqual (path , new_dir )
265+ # Directory must NOT be created in read-only mode
266+ self .assertFalse (
267+ os .path .exists (new_dir ),
268+ "Data directory should not be created in read-only mode" ,
269+ )
270+
271+ def test_param_free_save_blocked_in_read_only (self ):
272+ """Test that GzipModel.save raises PermissionError in read-only mode."""
273+ from pythainlp .classify .param_free import GzipModel
274+
275+ # Bypass __init__ (which needs numpy) — only the guard is under test
276+ model = object .__new__ (GzipModel )
277+ with patch .dict (
278+ os .environ ,
279+ {"PYTHAINLP_READ_ONLY" : "1" },
280+ clear = False ,
281+ ):
282+ os .environ .pop ("PYTHAINLP_READ_MODE" , None )
283+ with tempfile .TemporaryDirectory () as tmpdir :
284+ with self .assertRaises (PermissionError ):
285+ model .save (os .path .join (tmpdir , "model.json" ))
286+
287+ def test_perceptron_train_save_blocked_in_read_only (self ):
288+ """Test that PerceptronTagger.train raises PermissionError when saving in read-only mode."""
289+ from pythainlp .tag ._tag_perceptron import PerceptronTagger
290+
291+ tagger = PerceptronTagger ()
292+ sentences = [[("กิน" , "VV" ), ("ข้าว" , "NN" )]]
293+ with patch .dict (
294+ os .environ ,
295+ {"PYTHAINLP_READ_ONLY" : "1" },
296+ clear = False ,
297+ ):
298+ os .environ .pop ("PYTHAINLP_READ_MODE" , None )
299+ with tempfile .TemporaryDirectory () as tmpdir :
300+ with self .assertRaises (PermissionError ):
301+ tagger .train (
302+ sentences ,
303+ save_loc = os .path .join (tmpdir , "tagger.json" ),
304+ nr_iter = 1 ,
305+ )
0 commit comments