-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Allow a file to be moved cross-device. #1877
Conversation
lgtm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the following?
- Tests actually moving across fs's, or at least mock out that
shutil.move
is called - Mention the atomicity things in the docs? Atomicity of renames are a very important thing in luigi. If it can't be maintained for some functions, the docs should say under what condition.
Other than that, LGTM
8648bb3
to
7607161
Compare
Thanks for the review, @Tarrasch, I tried to address your points. As for the docs, I didn't find a perfect place yet, so added a short section to the tasks docs. |
7607161
to
a1caedb
Compare
pretty sure cross device file moving will never be atomic |
@erikbern, closest thing to atomic would probably be: copy file to a temp location on the target device, rename it to destination, then unlink the source? But I wanted to keep the code short. Luigi allows non-atomicity, e.g. in tasks with multiple outputs:
So I thought it would be ok to drop atomicity if this special case, if the user chooses to (chooses to work with two filesystems). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erikbern Althogh the luigi docs shouldn't go into details about things a savy engineer might have already inferred. All its readers are still humans and many might benefit from a warning-bubble like the one I'm suggesting.
t = LocalTarget(self.path) | ||
f = t.open('w') | ||
f.write('test_data') | ||
f.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, can't you do the much more elegant context-manager thingie? with
-statements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, sure. Almost done.
|
||
.. code:: python | ||
|
||
luigi.LocalTarget(path=src).move(dst) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be much more easy to put this in the docs for LocalTarget.move()
docs?? You don't even need a code example. Just a warning saying to be aware of the risks when doing this across filesystems's.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're right. I addressed this the next PR.
great idea, let's do this |
With `os.rename` you get a `OSError: [Errno 18] Invalid cross-device link` if you attempt to move a file across filesystems. `shutil.move` covers the basic case: > If the destination is on the current filesystem, then os.rename() is used. and additionally handles the cross-device case. If the destination is on a different filesystem, we approximate atomicity by first copying the source to a temporary file on the target filesystem, followed by a rename. Finally the source file is removed.
a1caedb
to
93f064d
Compare
Thanks for the feedback. I implemented an almost-atomic cross-device move operation and updated the docs. (I'll be AFK for ten days, can only look into this when I'm back). |
Does this work for you in production as well? If so, let's merge. :) |
lgtm – nice! |
@Tarrasch, yes it does. Background: We have
|
Thanks! |
Description
Implementation of
luigi.File
would now allow movement of a file across filesystems.Motivation and Context
If you use
luigi.File(src).move(target)
when source and target are on different filesystems, you get an error:Also, this would align implementation of
File.move()
withFile.copy()
which already usesshutil
.Have you tested this? If so, how?
Semantic stays the same. Existing tests apply.
Important tradeoff: If you move a file across filesystems, you lose atomicity of
os.rename
.