This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: [alpine] shutil.copytree fail to copy a direcotry with broken symlinks
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: duplicate
Dependencies: Superseder: copystat on symlinks fails for alpine -- faulty lchmod implementation?
View: 31940
Assigned To: Nosy List: fruch, martin.panter, sroracle
Priority: normal Keywords: patch

Created on 2016-11-06 22:34 by fruch, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
musl-eopnotsupp.patch sroracle, 2018-04-19 02:54
Messages (4)
msg280178 - (view) Author: Israel Fruchter (fruch) Date: 2016-11-06 22:34
this fails on python3.5-alpine and python3.6-alpine
(works as fine in python2.7-alpine)

cd /bug && ln -s /broken_path/to_nowhere broken
python -c "import shutil; shutil.copytree('/bug', '/temp', symlinks=True)"

Dockerfile example here:
https://github.com/docker-library/python/issues/155

https://github.com/python/cpython/blob/c30098c8c6014f3340a369a31df9c74bdbacc269/Lib/shutil.py#L198

seem like its suppressing NotImplementedError, and in our case OsError with ENOSUP was raised
msg280179 - (view) Author: Israel Fruchter (fruch) Date: 2016-11-06 22:36
the failure looks like that:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.5/shutil.py", line 359, in copytree
    raise Error(errors)
shutil.Error: [('/bug/broken', '/temp/broken', "[Errno 95] Not supported: '/temp/broken'")]
msg315472 - (view) Author: Max Rees (sroracle) * Date: 2018-04-19 02:54
Actually the symlinks don't need to be broken. It fails for any kind of symlink
on musl.

$ ls -l /tmp/symtest
lrwxrwxrwx 1 mcrees mcrees 10 Apr 18 21:16 empty -> /var/empty
-rw-r--r-- 1 mcrees mcrees  0 Apr 18 21:16 regular
lrwxrwxrwx 1 mcrees mcrees 16 Apr 18 21:16 resolv.conf -> /etc/resolv.conf

$ python3
>>> import shutil; shutil.copytree('/tmp/symtest', '/tmp/symtest2', symlinks=True)
shutil.Error: [('/tmp/symtest/resolv.conf', '/tmp/symtest2/resolv.conf', "[Errno
95] Not supported: '/tmp/symtest2/resolv.conf'"), ('/tmp/symtest/empty',
'/tmp/symtest2/empty', "[Errno 95] Not supported: '/tmp/symtest2/empty'")]

$ ls -l /tmp/symtest2
total 0
lrwxrwxrwx 1 mcrees mcrees 10 Apr 18 21:16 empty -> /var/empty
-rw-r--r-- 1 mcrees mcrees  0 Apr 18 21:16 regular
lrwxrwxrwx 1 mcrees mcrees 16 Apr 18 21:16 resolv.conf -> /etc/resolv.conf

The implication of these bugs mean that things like pip may fail if it calls
shutil.copytree(..., symlinks=True) on a directory that contains symlinks(!)

Attached is a patch that works around the issue but does not address why chmod
is returning OSError instead of NotImplementedError.
msg315540 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2018-04-20 21:23
This looks like it may be covered by Issue 31940, about the “shutil.copystat” API. See Anthony’s initial proposal at <https://bugs.python.org/issue31940#msg305528>.

Max: I think you need the “else” branch to reraise the exception if “errno” doesn’t match. Perhaps a test case would have picked this up.
History
Date User Action Args
2022-04-11 14:58:39adminsetgithub: 72813
2019-02-11 01:53:13benjamin.petersonsetstatus: open -> closed
resolution: duplicate
stage: resolved
2018-04-20 21:23:16martin.pantersetsuperseder: copystat on symlinks fails for alpine -- faulty lchmod implementation?

messages: + msg315540
nosy: + martin.panter
2018-04-19 02:54:31sroraclesetfiles: + musl-eopnotsupp.patch

nosy: + sroracle
messages: + msg315472

keywords: + patch
2016-11-06 22:36:28fruchsetmessages: + msg280179
2016-11-06 22:34:31fruchcreate