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: shutil.copyfile raises SpecialFileError for symlink to fifo
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: chrahunt, eryksun
Priority: normal Keywords: patch

Created on 2019-07-29 04:36 by chrahunt, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 16575 AWhetter, 2019-12-12 05:23
Messages (4)
msg348597 - (view) Author: Christopher Hunt (chrahunt) * Date: 2019-07-29 04:36
Currently shutil.copyfile raises SpecialFileError when src is a link to a fifo. To reproduce:

    import os
    import shutil
    import tempfile
    
    
    d = tempfile.mkdtemp()
    fifo = os.path.join(d, 'fifo')
    link_to_fifo = os.path.join(d, 'link-to-fifo')
    copy_of_link_to_fifo = os.path.join(d, 'copy-of-link-to-fifo')
    
    
    os.mkfifo(fifo)
    os.symlink(fifo, link_to_fifo)
    shutil.copyfile(link_to_fifo, copy_of_link_to_fifo)

Example output:

    Traceback (most recent call last):
      File "repro.py", line 14, in <module>
        shutil.copyfile(link_to_fifo, copy_of_link_to_fifo)
      File "/home/chris/.pyenv/versions/3.7.2/lib/python3.7/shutil.py", line 115, in copyfile
        raise SpecialFileError("`%s` is a named pipe" % fn)
    shutil.SpecialFileError: `/tmp/user/1000/tmpxhigll5g/link-to-fifo` is a named pipe

I would have expected this to copy the symlink without complaint. Raising a SpecialFileError would be OK if `follow_symlinks` was False.
msg348598 - (view) Author: Christopher Hunt (chrahunt) * Date: 2019-07-29 05:15
Likewise when the destination is a symlink - though in that case the value of `follow_symlinks` should probably not matter.
msg408346 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-12-11 22:17
> Raising a SpecialFileError would be OK if `follow_symlinks` was False.

I expect it to fail if follow_symlinks is True, which is the default value. I expect it to succeed with follow_symlinks=False, which should create a shallow copy of just the symlink, regardless of its target. Instead, what happens is that it calls shutil._stat(fn) on both src and dst, regardless of follow_symlinks. I think the call should be shutil._stat(fn, follow_symlinks). This requires updating shutil._stat() to pass the value to fn.stat() and os.stat().
msg408584 - (view) Author: Christopher Hunt (chrahunt) * Date: 2021-12-15 03:45
> I expect it to fail if follow_symlinks is True, which is the default value. I expect it to succeed with follow_symlinks=False, which should create a shallow copy of just the symlink, regardless of its target.

I agree, thanks for the correction.
History
Date User Action Args
2022-04-11 14:59:18adminsetgithub: 81882
2021-12-15 03:45:07chrahuntsetmessages: + msg408584
2021-12-11 22:17:08eryksunsetnosy: + eryksun
messages: + msg408346
2021-12-11 18:43:57iritkatrielsetversions: + Python 3.9, Python 3.10, Python 3.11, - Python 2.7, Python 3.5, Python 3.6, Python 3.7, Python 3.8
2019-12-12 05:23:32AWhettersetkeywords: + patch
stage: patch review
pull_requests: + pull_request17050
2019-07-29 05:15:54chrahuntsetmessages: + msg348598
2019-07-29 04:36:51chrahuntcreate