Skip to content
7 changes: 5 additions & 2 deletions fsspec/implementations/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,10 @@ def _open(self):
self.f = compress(self.f, mode=self.mode)
else:
# TODO: check if path is writable?
i, name = tempfile.mkstemp()
i, name = tempfile.mkstemp(
dir=os.path.dirname(self.path),
prefix=os.path.basename(self.path) + "-",
)
os.close(i) # we want normal open and normal buffered file
self.temp = name
self.f = open(name, mode=self.mode)
Expand Down Expand Up @@ -434,7 +437,7 @@ def commit(self):
try:
mask = 0o666
os.chmod(self.path, mask & ~get_umask(mask))
except RuntimeError:
except (RuntimeError, PermissionError):
pass

def discard(self):
Expand Down
28 changes: 28 additions & 0 deletions fsspec/implementations/tests/test_local.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import bz2
import errno
import gzip
import os
import os.path
Expand Down Expand Up @@ -562,6 +563,33 @@ def test_multiple_filesystems_use_umask_cache(tmpdir):
assert get_umask.cache_info().hits == 1


def test_transaction_chmod_catch_permission_error(tmpdir):
fs = LocalFileSystem()
with patch("os.chmod", side_effect=PermissionError("Operation not permitted")):
with fs.transaction, fs.open(tmpdir + "/afile", "wb") as f:
f.write(b"data")


def test_transaction_cross_device_but_mock_temp_dir_on_wrong_device(tmpdir):
# If the temporary file for a transaction is not on the correct device,
# os.rename in shutil.move will raise EXDEV and lookup('chmod') will raise
# a PermissionError.
fs = LocalFileSystem()
with (
patch(
"os.rename",
side_effect=OSError(errno.EXDEV, "Invalid cross-device link"),
),
patch(
"os.chmod",
side_effect=PermissionError("Operation not permitted"),
),
pytest.raises(PermissionError, match="Operation not permitted"),
):
with fs.transaction, fs.open(tmpdir + "/afile", "wb") as f:
f.write(b"data")


def test_make_path_posix():
cwd = os.getcwd()
if WIN:
Expand Down
Loading