File tree 2 files changed +35
-5
lines changed
2 files changed +35
-5
lines changed Original file line number Diff line number Diff line change @@ -430,12 +430,22 @@ def __getstate__(self):
430
430
def commit (self ):
431
431
if self .autocommit :
432
432
raise RuntimeError ("Can only commit if not already set to autocommit" )
433
- shutil .move (self .temp , self .path )
434
433
try :
435
- mask = 0o666
436
- os .chmod (self .path , mask & ~ get_umask (mask ))
437
- except RuntimeError :
438
- pass
434
+ shutil .move (self .temp , self .path )
435
+ except PermissionError as e :
436
+ # shutil.move raises PermissionError if os.rename
437
+ # and the default copy2 fallback with shutil.copystats fail.
438
+ # The file should be there nonetheless, but without copied permissions.
439
+ # If it doesn't exist, there was no permission to create the file.
440
+ if not os .path .exists (self .path ):
441
+ raise e
442
+ else :
443
+ # If PermissionError is not raised, permissions can be set.
444
+ try :
445
+ mask = 0o666
446
+ os .chmod (self .path , mask & ~ get_umask (mask ))
447
+ except RuntimeError :
448
+ pass
439
449
440
450
def discard (self ):
441
451
if self .autocommit :
Original file line number Diff line number Diff line change 1
1
import bz2
2
+ import errno
2
3
import gzip
3
4
import os
4
5
import os .path
@@ -562,6 +563,25 @@ def test_multiple_filesystems_use_umask_cache(tmpdir):
562
563
assert get_umask .cache_info ().hits == 1
563
564
564
565
566
+ def test_transaction_cross_device_but_mock_temp_dir_on_wrong_device (tmpdir ):
567
+ # If the temporary file for a transaction is not on the correct device,
568
+ # os.rename in shutil.move will raise EXDEV and lookup('chmod') will raise
569
+ # a PermissionError.
570
+ fs = LocalFileSystem ()
571
+ with (
572
+ patch (
573
+ "os.rename" ,
574
+ side_effect = OSError (errno .EXDEV , "Invalid cross-device link" ),
575
+ ),
576
+ patch (
577
+ "os.chmod" ,
578
+ side_effect = PermissionError ("Operation not permitted" ),
579
+ ),
580
+ ):
581
+ with fs .transaction , fs .open (tmpdir + "/afile" , "wb" ) as f :
582
+ f .write (b"data" )
583
+
584
+
565
585
def test_make_path_posix ():
566
586
cwd = os .getcwd ()
567
587
if WIN :
You can’t perform that action at this time.
0 commit comments