system: use linkat instead of link

`os.link` is broken across platforms when dealing with symlinks.

See https://bugs.python.org/issue41355 for more info.
This commit is contained in:
Ruslan Kuprieiev
2021-10-27 20:19:17 +03:00
committed by Ruslan Kuprieiev
parent 41aee9a3b7
commit 874aceccf8
2 changed files with 30 additions and 2 deletions
+29 -1
View File
@@ -2,14 +2,42 @@ import errno
import logging
import os
import platform
import stat
import sys
logger = logging.getLogger(__name__)
if os.name == "nt" and sys.version_info < (3, 8):
# NOTE: using backports for `os.path.realpath`
# See https://bugs.python.org/issue9949 for more info.
# pylint: disable=import-error, no-name-in-module
from jaraco.windows.filesystem.backports import realpath as _realpath
def realpath(path):
return _realpath(os.fspath(path))
else:
realpath = os.path.realpath
class System:
@staticmethod
def hardlink(source, link_name):
os.link(source, link_name)
# NOTE: we should really be using `os.link()` here with
# `follow_symlinks=True`, but unfortunately the implementation is
# buggy across platforms, so until it is fixed, we just dereference
# the symlink ourselves here.
#
# See https://bugs.python.org/issue41355 for more info.
st = os.lstat(source)
if stat.S_ISLNK(st.st_mode):
src = realpath(source)
else:
src = source
os.link(src, link_name)
@staticmethod
def symlink(source, link_name):
+1 -1
View File
@@ -75,6 +75,7 @@ install_requires =
fsspec[http]>=2021.10.1
aiohttp-retry>=2.4.5
diskcache>=5.2.1
jaraco.windows>=5.7.0; python_version < '3.8' and sys_platform == 'win32'
[options.extras_require]
# gssapi should not be included in all_remotes, because it doesn't have wheels
@@ -139,7 +140,6 @@ tests =
Pygments==2.10.0
collective.checkdocs==0.2
pydocstyle==6.1.1
jaraco.windows==5.7.0
# pylint requirements
pylint==2.11.1
# we use this to suppress pytest-related false positives in our tests.