diff --git a/fsspec/implementations/local.py b/fsspec/implementations/local.py index e2131ec8f..216c83f63 100644 --- a/fsspec/implementations/local.py +++ b/fsspec/implementations/local.py @@ -59,21 +59,23 @@ def glob(self, path, **kwargs): def info(self, path, **kwargs): path = self._strip_protocol(path) out = os.stat(path, follow_symlinks=False) - dest = False - if os.path.islink(path): - t = "link" - dest = os.readlink(path) - elif os.path.isdir(path): + if os.path.isdir(path): t = "directory" elif os.path.isfile(path): t = "file" else: t = "other" - result = {"name": path, "size": out.st_size, "type": t, "created": out.st_ctime} + result = { + "name": path, + "size": out.st_size, + "type": t, + "created": out.st_ctime, + "islink": os.path.islink(path), + } for field in ["mode", "uid", "gid", "mtime"]: result[field] = getattr(out, "st_" + field) - if dest: - result["destination"] = dest + if result["islink"]: + result["destination"] = os.readlink(path) try: out2 = os.stat(path, follow_symlinks=True) result["size"] = out2.st_size diff --git a/fsspec/implementations/tests/test_local.py b/fsspec/implementations/tests/test_local.py index 7e576657d..981205996 100644 --- a/fsspec/implementations/tests/test_local.py +++ b/fsspec/implementations/tests/test_local.py @@ -450,7 +450,7 @@ def test_make_path_posix(): assert "/" in make_path_posix("rel\\path", sep="\\") -def test_links(tmpdir): +def test_linked_files(tmpdir): tmpdir = str(tmpdir) fn0 = os.path.join(tmpdir, "target") fn1 = os.path.join(tmpdir, "link1") @@ -469,8 +469,12 @@ def test_links(tmpdir): fs = LocalFileSystem() assert fs.info(fn0)["type"] == "file" - assert fs.info(fn1)["type"] == "link" - assert fs.info(fn2)["type"] == "link" + assert fs.info(fn1)["type"] == "file" + assert fs.info(fn2)["type"] == "file" + + assert not fs.info(fn0)["islink"] + assert fs.info(fn1)["islink"] + assert fs.info(fn2)["islink"] assert fs.info(fn0)["size"] == len(data) assert fs.info(fn1)["size"] == len(data) @@ -485,6 +489,34 @@ def test_links(tmpdir): assert f.read() == data +def test_linked_directories(tmpdir): + tmpdir = str(tmpdir) + + subdir0 = os.path.join(tmpdir, "target") + subdir1 = os.path.join(tmpdir, "link1") + subdir2 = os.path.join(tmpdir, "link2") + + os.makedirs(subdir0) + + try: + os.symlink(subdir0, subdir1) + os.symlink(subdir0, subdir2) + except OSError: + if WIN: + pytest.xfail("Ran on win without admin permissions") + else: + raise + + fs = LocalFileSystem() + assert fs.info(subdir0)["type"] == "directory" + assert fs.info(subdir1)["type"] == "directory" + assert fs.info(subdir2)["type"] == "directory" + + assert not fs.info(subdir0)["islink"] + assert fs.info(subdir1)["islink"] + assert fs.info(subdir2)["islink"] + + def test_isfilestore(): fs = LocalFileSystem(auto_mkdir=False) assert fs._isfilestore()