Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move_file() fails if source and destination are not on the same file system #71

Open
frankenjoe opened this issue Jun 30, 2022 · 7 comments
Labels
bug Something isn't working

Comments

@frankenjoe
Copy link
Collaborator

I just encountered the following error when trying to use audeer.move_file() to move a file from one file system to another:

OSError: [Errno 18] Invalid cross-device link: '/tmp/tmpvgh8upvf/audio/002.wav' -> '/media/jwagner/Data/Git/pyaudb/my/build/audio/002.wav'

We should either fix it or mention in the docstring that it's not possible.

@frankenjoe frankenjoe added the bug Something isn't working label Jun 30, 2022
@hagenw
Copy link
Member

hagenw commented Jul 4, 2022

That's unfortunate. It seems there exists no secure and fast methods to move files around under Python.
We could have another look, otherwise I would recommend to add a note to the docstring explaining what to use if you want to move files across file systems.

@frankenjoe
Copy link
Collaborator Author

I think it is expected that moving a file from one system to another will be slower as it basically requires to copy the file and then delete in the old destination. So maybe we should simply catch the error and fallback to another move function.

@hagenw
Copy link
Member

hagenw commented Jul 4, 2022

In principle, that's a good idea. But we have to make sure, that OSError is not thrown for other problems as well. Or can we maybe check the returned error message if it contains "Invalid cross-device link"? The only problem is that the error message might vary between operating systems and it might also be not possible to write tests for it.

@frankenjoe
Copy link
Collaborator Author

If there is a cheap way to find out if the two files are on different disks we could also check that first.

On the other hand - if it raises a OSError due to some other reason, it will probably raise it again when we call the other move function.

@frankenjoe
Copy link
Collaborator Author

frankenjoe commented Jan 30, 2024

Here's my current workaround (on Linux):

def safe_move(src: str, dst: str):
    try:
        audeer.move(src, dst)
    except OSError as ex:
        if 'Invalid cross-device link' in str(ex):
            shutil.move(src, dst)
        else:
            raise ex

@hagenw
Copy link
Member

hagenw commented Jan 30, 2024

One problem might be that the error messages are usually different for file system operations on different operating systems.
So it might be that this will not work under Windows and maybe under MacOS.

The ideal solution would be to be able to create a test on the runners for having different file systems, but I'm not sure if this is possible (BTW, does this mean simply different partitions, or does this mean having EXT4 on one partition and NTFS on another one?).

@frankenjoe
Copy link
Collaborator Author

In my case I have two disks, both EXT4 formatted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants