Skip to content
8 changes: 5 additions & 3 deletions fs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import six

from . import copy, errors, fsencode, iotools, move, tools, walk, wildcard
from .enums import ResourceType
from .glob import BoundGlobber
from .mode import validate_open_mode
from .path import abspath, join, normpath
Expand Down Expand Up @@ -49,7 +50,6 @@
Union,
)
from types import TracebackType
from .enums import ResourceType
from .info import Info, RawInfo
from .subfs import SubFS
from .permissions import Permissions
Expand Down Expand Up @@ -981,8 +981,10 @@ def islink(self, path):
bool: `True` if ``path`` maps to a symlink.

"""
self.getinfo(path)
return False
try:
return self.gettype(path) == ResourceType.symlink
except errors.ResourceNotFound:
return False

def lock(self):
# type: () -> RLock
Expand Down
4 changes: 1 addition & 3 deletions fs/osfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ def gettype(self, path):
self.check()
sys_path = self._to_sys_path(path)
with convert_os_errors("gettype", path):
stat = os.stat(sys_path)
stat = os.lstat(sys_path)
resource_type = self._get_type_from_stat(stat)
return resource_type

Expand All @@ -608,8 +608,6 @@ def islink(self, path):
self.check()
_path = self.validatepath(path)
sys_path = self._to_sys_path(_path)
if not self.exists(path):
raise errors.ResourceNotFound(path)
with convert_os_errors("islink", path):
return os.path.islink(sys_path)

Expand Down
3 changes: 1 addition & 2 deletions fs/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,7 @@ def test_isdir(self):
def test_islink(self):
self.fs.touch("foo")
self.assertFalse(self.fs.islink("foo"))
with self.assertRaises(errors.ResourceNotFound):
self.fs.islink("bar")
self.assertFalse(self.fs.islink("bar"))

def test_getsize(self):
self.fs.writebytes("empty", b"")
Expand Down
17 changes: 17 additions & 0 deletions tests/test_osfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import pytest

from fs import osfs, open_fs
from fs.enums import ResourceType
from fs.path import relpath, dirname
from fs import errors
from fs.test import FSTestCases
Expand Down Expand Up @@ -203,3 +204,19 @@ def test_complex_geturl(self):

def test_geturl_return_no_url(self):
self.assertRaises(errors.NoURL, self.fs.geturl, "test/path", "upload")

@pytest.mark.skipif(not hasattr(os, "symlink"), reason="No symlink support")
def test_symlinks_dangling(self):
self.fs.create("a")
os.symlink(self.fs.getsyspath("a"), self.fs.getsyspath("b"))

self.assertTrue(self.fs.exists("a"))
self.assertFalse(self.fs.islink("a"))
self.assertEqual(self.fs.gettype("a"), ResourceType.file)
self.assertTrue(self.fs.exists("b"))
self.assertTrue(self.fs.islink("b"))
self.assertEqual(self.fs.gettype("b"), ResourceType.symlink)

self.fs.remove("a")
self.assertTrue(self.fs.islink("b"))
self.assertEqual(self.fs.gettype("b"), ResourceType.symlink)