2121)
2222
2323
24+ def osp (path : str ) -> str :
25+ """Normalize path for OS."""
26+ if os .name == "nt" : # pragma: no cover
27+ return path .replace ("/" , "\\ " )
28+ return path
29+
30+
31+ def map_osp (paths ):
32+ return [osp (path ) for path in paths ]
33+
34+
2435class TestGetHasherFactory :
2536 def test_get_guaranteed (self ):
2637 algorithm_and_hasher_factory = [
@@ -142,7 +153,7 @@ def teardown_method(self):
142153 shutil .rmtree (self .dir )
143154
144155 def path_to (self , relpath ):
145- return os .path .join (self .dir , relpath )
156+ return os .path .join (self .dir , osp ( relpath ) )
146157
147158 def mkdirs (self , dirpath ):
148159 os .makedirs (self .path_to (dirpath ))
@@ -173,7 +184,7 @@ def test_basic(self):
173184 self .mkfile ("root/d1/d11/f1" )
174185 self .mkfile ("root/d2/f1" )
175186
176- expected_filepaths = ["d1/d11/f1" , "d1/f1" , "d2/f1" , "f1" ]
187+ expected_filepaths = map_osp ( ["d1/d11/f1" , "d1/f1" , "d2/f1" , "f1" ])
177188 filepaths = included_paths (self .path_to ("root" ))
178189 assert filepaths == expected_filepaths
179190
@@ -220,11 +231,11 @@ def test_symlinked_dir(self):
220231 assert filepaths == ["f1" ]
221232
222233 filepaths = included_paths (self .path_to ("root" ), linked_dirs = True )
223- assert filepaths == ["d1/f1" , "d1/f2" , "f1" ]
234+ assert filepaths == map_osp ( ["d1/f1" , "d1/f2" , "f1" ])
224235
225236 # default is 'linked_dirs': True
226237 filepaths = included_paths (self .path_to ("root" ))
227- assert filepaths == ["d1/f1" , "d1/f2" , "f1" ]
238+ assert filepaths == map_osp ( ["d1/f1" , "d1/f2" , "f1" ])
228239
229240 def test_cyclic_link (self ):
230241 self .mkdirs ("root/d1" )
@@ -237,7 +248,7 @@ def test_cyclic_link(self):
237248 assert str (exc_info .value ).startswith ("Symlink recursion:" )
238249
239250 filepaths = included_paths (self .path_to ("root" ), allow_cyclic_links = True )
240- assert filepaths == ["d1/link_back/." ]
251+ assert filepaths == map_osp ( ["d1/link_back/." ])
241252
242253 # default is 'allow_cyclic_links': False
243254 with pytest .raises (SymlinkRecursionError ):
@@ -255,11 +266,11 @@ def test_ignore_hidden(self):
255266
256267 # no ignore
257268 filepaths = included_paths (self .path_to ("root" ))
258- assert filepaths == [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ]
269+ assert filepaths == map_osp ( [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ])
259270
260271 # with ignore
261272 filepaths = included_paths (self .path_to ("root" ), match = ["*" , "!.*" ])
262- assert filepaths == ["d1/f1" , "f1" ]
273+ assert filepaths == map_osp ( ["d1/f1" , "f1" ])
263274
264275 def test_ignore_hidden_files_only (self ):
265276 self .mkdirs ("root/d1" )
@@ -273,13 +284,13 @@ def test_ignore_hidden_files_only(self):
273284
274285 # no ignore
275286 filepaths = included_paths (self .path_to ("root" ))
276- assert filepaths == [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ]
287+ assert filepaths == map_osp ( [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ])
277288
278289 # with ignore
279290 filepaths = included_paths (
280291 self .path_to ("root" ), match = ["**/*" , "!**/.*" , "**/.*/*" , "!**/.*/.*" ]
281292 )
282- assert filepaths == [".d2/f1" , "d1/f1" , "f1" ]
293+ assert filepaths == map_osp ( [".d2/f1" , "d1/f1" , "f1" ])
283294
284295 def test_ignore_hidden_explicitly_recursive (self ):
285296 self .mkdirs ("root/d1" )
@@ -293,11 +304,11 @@ def test_ignore_hidden_explicitly_recursive(self):
293304
294305 # no ignore
295306 filepaths = included_paths (self .path_to ("root" ))
296- assert filepaths == [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ]
307+ assert filepaths == map_osp ( [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ])
297308
298309 # with ignore
299310 filepaths = included_paths (self .path_to ("root" ), match = ["*" , "!**/.*" ])
300- assert filepaths == ["d1/f1" , "f1" ]
311+ assert filepaths == map_osp ( ["d1/f1" , "f1" ])
301312
302313 def test_exclude_hidden_dirs (self ):
303314 self .mkdirs ("root/d1" )
@@ -312,11 +323,13 @@ def test_exclude_hidden_dirs(self):
312323
313324 # no ignore
314325 filepaths = included_paths (self .path_to ("root" ), empty_dirs = True )
315- assert filepaths == [".d2/f1" , ".f2" , "d1/.d1/." , "d1/.f2" , "d1/f1" , "f1" ]
326+ assert filepaths == map_osp (
327+ [".d2/f1" , ".f2" , "d1/.d1/." , "d1/.f2" , "d1/f1" , "f1" ]
328+ )
316329
317330 # with ignore
318331 filepaths = included_paths (self .path_to ("root" ), match = ["*" , "!.*/" ])
319- assert filepaths == [".f2" , "d1/.f2" , "d1/f1" , "f1" ]
332+ assert filepaths == map_osp ( [".f2" , "d1/.f2" , "d1/f1" , "f1" ])
320333
321334 def test_exclude_hidden_dirs_and_files (self ):
322335 self .mkdirs ("root/d1" )
@@ -330,11 +343,11 @@ def test_exclude_hidden_dirs_and_files(self):
330343
331344 # no ignore
332345 filepaths = included_paths (self .path_to ("root" ))
333- assert filepaths == [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ]
346+ assert filepaths == map_osp ( [".d2/f1" , ".f2" , "d1/.f2" , "d1/f1" , "f1" ])
334347
335348 # using ignore
336349 filepaths = included_paths (self .path_to ("root" ), match = ["*" , "!.*/" , "!.*" ])
337- assert filepaths == ["d1/f1" , "f1" ]
350+ assert filepaths == map_osp ( ["d1/f1" , "f1" ])
338351
339352 def test_exclude_extensions (self ):
340353 self .mkdirs ("root/d1" )
@@ -353,14 +366,16 @@ def test_exclude_extensions(self):
353366 filepaths = included_paths (
354367 self .path_to ("root" ), match = ["*" , "!*.skip1" , "!*.skip2" ]
355368 )
356- assert filepaths == [
357- "d1/f.txt" ,
358- "f" ,
359- "f.skip1.txt" ,
360- "f.skip1skip2" ,
361- "f.txt" ,
362- "fskip1" ,
363- ]
369+ assert filepaths == map_osp (
370+ [
371+ "d1/f.txt" ,
372+ "f" ,
373+ "f.skip1.txt" ,
374+ "f.skip1skip2" ,
375+ "f.txt" ,
376+ "fskip1" ,
377+ ]
378+ )
364379
365380 def test_empty_dirs_include_vs_exclude (self ):
366381 self .mkdirs ("root/d1" )
@@ -372,14 +387,14 @@ def test_empty_dirs_include_vs_exclude(self):
372387 self .mkfile ("root/d3/d31/f" )
373388
374389 filepaths = included_paths (self .path_to ("root" ), empty_dirs = False )
375- assert filepaths == ["d1/f" , "d3/d31/f" ]
390+ assert filepaths == map_osp ( ["d1/f" , "d3/d31/f" ])
376391
377392 # `include_empty=False` is default
378393 filepaths = included_paths (self .path_to ("root" ))
379- assert filepaths == ["d1/f" , "d3/d31/f" ]
394+ assert filepaths == map_osp ( ["d1/f" , "d3/d31/f" ])
380395
381396 filepaths = included_paths (self .path_to ("root" ), empty_dirs = True )
382- assert filepaths == ["d1/f" , "d2/." , "d3/d31/f" , "d4/d41/." ]
397+ assert filepaths == map_osp ( ["d1/f" , "d2/." , "d3/d31/f" , "d4/d41/." ])
383398
384399 def test_empty_dirs_because_of_filter_include_vs_exclude (self ):
385400 self .mkdirs ("root/d1" )
@@ -391,19 +406,19 @@ def test_empty_dirs_because_of_filter_include_vs_exclude(self):
391406 filepaths = included_paths (
392407 self .path_to ("root" ), match = ["*" , "!.*" ], empty_dirs = False
393408 )
394- assert filepaths == ["d1/f" ]
409+ assert filepaths == map_osp ( ["d1/f" ])
395410
396411 # `include_empty=False` is default
397412 filepaths = included_paths (
398413 self .path_to ("root" ),
399414 match = ["*" , "!.*" ],
400415 )
401- assert filepaths == ["d1/f" ]
416+ assert filepaths == map_osp ( ["d1/f" ])
402417
403418 filepaths = included_paths (
404419 self .path_to ("root" ), match = ["*" , "!.*" ], empty_dirs = True
405420 )
406- assert filepaths == ["d1/f" , "d2/." ]
421+ assert filepaths == map_osp ( ["d1/f" , "d2/." ])
407422
408423 def test_empty_dir_inclusion_not_affected_by_match (self ):
409424 self .mkdirs ("root/d1" )
@@ -414,17 +429,17 @@ def test_empty_dir_inclusion_not_affected_by_match(self):
414429 filepaths = included_paths (
415430 self .path_to ("root" ), match = ["*" , "!.*" ], empty_dirs = True
416431 )
417- assert filepaths == [".d2/." , "d1/." ]
432+ assert filepaths == map_osp ( [".d2/." , "d1/." ])
418433
419434 filepaths = included_paths (
420435 self .path_to ("root" ), match = ["*" , "!.*/" ], empty_dirs = True
421436 )
422- assert filepaths == [".d2/." , "d1/." ]
437+ assert filepaths == map_osp ( [".d2/." , "d1/." ])
423438
424439 filepaths = included_paths (
425440 self .path_to ("root" ), match = ["*" , "!d1" ], empty_dirs = True
426441 )
427- assert filepaths == [".d2/." , "d1/." ]
442+ assert filepaths == map_osp ( [".d2/." , "d1/." ])
428443
429444
430445def dirhash_mp_comp (* args , ** kwargs ):
@@ -658,6 +673,11 @@ def test_raise_on_not_at_least_one_of_name_and_data(self):
658673 self .path_to ("root1" ), "sha256" , entry_properties = ["is_link" ]
659674 )
660675
676+ @pytest .mark .skipif (
677+ os .name == "nt" ,
678+ reason = "TODO: not getting expected speedup on Windows." ,
679+ # TODO: see https://github.com/andhus/scantree/issues/25
680+ )
661681 def test_multiproc_speedup (self ):
662682 self .mkdirs ("root/dir" )
663683 num_files = 10
@@ -704,7 +724,7 @@ def test_cache_by_real_path_speedup(self, tmpdir):
704724 target_file = tmpdir .join ("target_file" )
705725 target_file .ensure ()
706726 for i in range (num_links ):
707- root2 .join (f"link_{ i } " ). mksymlinkto ( target_file )
727+ os . symlink ( target_file , root2 .join (f"link_{ i } " ))
708728
709729 overhead_margin_factor = 1.5
710730 expected_max_elapsed_with_links = overhead * overhead_margin_factor + wait_time
@@ -743,7 +763,7 @@ def test_cache_together_with_multiprocess_speedup(self, tmpdir):
743763 target_file = tmpdir .join (target_file_name )
744764 target_file .write ("< one chunk content" , ensure = True )
745765 for j in range (num_links_per_file ):
746- root2 .join (f"link_{ i } _{ j } " ). mksymlinkto ( target_file )
766+ os . symlink ( target_file , root2 .join (f"link_{ i } _{ j } " ))
747767
748768 overhead_margin_factor = 1.5
749769 expected_max_elapsed_with_links = (
0 commit comments