-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
new__cp_function #10888
new__cp_function #10888
Conversation
|
||
# issue #10506 | ||
@non_windowsxp_only begin | ||
# Do: absulte and realtive directory links |
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.
absolute and relative
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.
Fixed
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.
absolute and relative are still spelled wrong in a few of the comments
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.
sorry will fix that
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.
not too big a deal, but may as well fix before merging
Updated the PR. Added NEWS.md entry inclusive the missing one for |
I think a |
I can add a force keyword: at the moment it raises an error like the one of the current implementation: something like: ERROR: SystemError: mkdir: File exists. Can't say exactley as I'm working on somthing else. Anyway: I add a force keyword: it does not remove any existing dirs but just write into such. what I mean: I have dirs:
The final "test2" will be:
|
I guess the merging into an existing destination is consistent with what |
I have to check it through but had something like this in mind. but you still want the additional karg |
I think it's easy enough to manually do "safe" no-force behavior via |
In this case maybe it would be a good point to add your suggestion to the docs.
|
I nearly finished implementing the
This is not enough for a number of reasons: e.g. if the The problem is not so much of implementing it (which I nearly finished) but of defining which result one wants in combination with EXAMPLE: IS CLEAR
EXAMPLE: NOT SO CLEAR
There are more combinations if the To avoid confusion or the need to write a long doc just to explain exceptions I would propose 2 options for now: 1.Because this addresses a current bug let's fix first the problem and merge it. I still will update the inconsistency with sendfile if the destination is a link to a file. 2.Use example:
The final "test2" will be: the same as the
|
Yeah this is a bit messy. I'd say try not to make things too complicated to preserve merging semantics in all combinations of links and keepsym. Since this is a bit ambiguous, maybe we go the python route, error if dst already exists and force the user to decide what to do about it? I'd like if it weren't just you and me making these decisions though. |
I will update the PR now. I think the clearest and internally most consistend implementation would be like this.
Having Default
|
We could bikeshed the keyword argument names a little (except |
Updated PR.. |
Any progress on the merge for this? |
I'd like other people to comment on the names (bikeshed please) of the |
hi tkelman,
Most of the others use multiple functions like copy_file, copy_tree ect.. and musch longer descriptive kwargs. python shutil.copyinstead of my
Copies the file src to the file or directory dst. src and dst should be strings. If dst specifies a directory, the file will be copied into dst using the base filename from src. Returns the path to the newly created file. If ruby copy_entryuses instead of my
Copies a file system entry src to dest. If src is a directory, this method copies its contents recursively. This method preserves file types, c.f. symlink, directory… (FIFO, device files and etc. are not supported yet) Both of src and dest must be a path name. src must exist, dest must not exist. If preserve is true, this method preserves owner, group, and modified time. Permissions are copied regardless preserve. If |
I'm in favor of longer, descriptively-named kwargs. |
what would you suggest? |
|
@tkelman should I go ahead and rename them to And like python default |
|
So, I will change both and the docs and update the PR.
Would you prefer to export the helperfunction: |
Those would be fine. I'm not too picky, though (which is why I didn't offer a concrete recommendation). |
I don't like the asymmetry that would introduce with |
Ok - this could be simple exported at a later time if wanted. Send you later the update - Thanks for your help. |
Seems this went well: |
|
||
* Added function `readlink` which returns the value of a symbolic link "path" ([#10714]). | ||
|
||
* The `cp` function now accepts keyword arguments `recursive`, `remove_destination` and `follow_symlinks` ([#10506]). |
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.
Small nitpick, I think this should refer to the PR in which it was implemented (here) rather than the issue it closes?
The lack of a verb is a problem, though--since this is a file copy operation, that option sounds like "copy symlinks" vs. "don't copy symlinks", which is not what this option controls. |
The "follow" verb doesn't actually make it much clearer to me. What does that option control? |
Whether copy...follows symlinks? Which is what it does. I thought that was the common nomenclature for moving through a symlink to where it points--I guess you could call it "dereference" by analogy to pointers but I don't know that I've seen anyone call it that. UPDATE: the
UPDATE 2: and |
So it's the difference between copying the content of the symlink versus copying the symlink as though it actually were the thing it points to? |
(I'm sort of playing dumb here because explaining what things do often reveals good names.) |
No problem (please note I've updated the above comment with excerpts from Yes; taking many liberties with the analogy and in pseudo-C (not bothering with dirents, etc.): FileContents* ptrFile; // is a symlink
// Results in a new pointer, but only one copy of the file
FileContents* newPtrFile = ptrFile; // cp --no-dereference; cp(..., follow_symlinks=false);
// Results in a new copy of the file
newPtrFile = malloc(fileSize);
memcpy(newPtrFile, ptrFile, fileSize); //cp --dereference; cp(..., follow_symlinks=true); |
Eventhough I prefered the short initial version My personal preference would be:
Other languages approach like python to offer 2 different function is also ok: so helper function It is true that: With the above discussion of more describtive kwargs this would be my prefered proposal.
|
I feel pretty strongly that |
I'm happier about these somewhat shorter versions. An important difference between recursive copy and recursive remove is that in the remove case, it's pretty bad if you meant to call it on a single file and accidentally call it on a directory. In the case of copy, it's not so bad since the original will be left intact. |
I suppose we'll just have to agree to disagree--the rarer something is used or encountered, the more descriptive its name should be. kwargs are the ultimate in "rarely used" since the whole point is to have a sane default. Shortening "destination" to "dst" and "symlink" to "sym"(bol? oh crap, I'm a Windows user, lemme look that up on Google...SanYang Motor Company?) just seems like clipping characters for the sake of it. |
As this is first of all a fix for issue: #10506 we need to come to some conclusion. cp(src::AbstractString, dst::AbstractString; recursive::Bool=true, remove_destination::Bool=false, follow_symlinks::Bool=true)
Copy the file, link, or directory from *src* to *dest*.
\"recursive=true\" is required to copy directories or links to directories.
\"remove_destination=true\" will first remove an existing `dst`.
If `follow_symlinks=false`, and src is a symbolic link, dst will be created as a symbolic link.
If `follow_symlinks=true` and src is a symbolic link, dst will be a copy of the file or directory
`src` refers to. I only use Unix and in such case I personally would prefer a default of: Cheers |
I think I support removing the recursive option and just making it always recursive. The default should be not to delete or overwrite anything, however. |
throw(ArgumentError(string("'$src' is a directory. `recursive=true` is required to ", | ||
"copy directories or links to directories."))) | ||
elseif ispath(dst) | ||
remove_destination ? |
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.
This would also make more sense with an if-else I think.
For |
I just can't think of a reason not to just do recursive all the time. As @peter1000 said, if you want to make sure you're copying a file, just check that it's a file first. Now |
Actually, no, that's totally wrong – |
I'm more than supportive for this. What is your opinions about default: |
Another API option would be using symbol values, e.g. cp(src, dst, symlinks=:follow, destination=:replace)
cp(src, dst, destination=:merge)
cp(src, dst, destination=:noreplace, symlinks=:nofollow) I'm not sure that's better, but I thought I'd throw it out there. |
And what about other combination: I think in the end the approach with the kwargs might be prefered one.
|
Just a hypothetical third option besides replace and don't replace: it would merge the two directory structures. Of course, it's not a great example, since there's a further two options which is whether to favor versions in the source or destination. |
Don't you think instead of packing all of it into |
Based on the last common discussion points I updated the PR to:
It seems to me that this is the best compromise of the 5 opinions involved in the discussion. |
Glad this got some input from a few other people. Assuming it passes CI I'm in favor of merging peter1000@514be00 |
Yes, this seems more than sufficiently bikeshedded. Thanks for your perseverance, @peter1000! |
my new implementation of the `cp` function got merged JuliaLang/julia#10888 sets `remove_destination=true` otherwise if you rerun you get an: ``` ERROR: ArgumentError: 'static/custom.css' exists. `remove_destination=true` is required to remove 'static/custom.css' before copying. ```
hi @tkelman
This is what I came up with to address issue: #10506
I took also a look at the older conversations at:
cp
does not work for directories #10434shutil.copy()
andshutil.copytree()
.recursive
kwarg to matchrm
..
My own opinion differs from @simonster and I would prefer to remove the
recursive
kwarg altogehter and just copy directories always recursively or exportcptree
.Anyway: I left it as it was:
cp
requires therecursive=true
to be set to copy directories and helper functioncptree
is not exported.To have an option to keep symlinks as symlinks I added a kwarg
keepsym=false
.follow_symlinks
is false and src is a symbolic link, a new symboliclink will be created instead of copying the file src points to. shutil.copy
On Linux (x86_64) all tests Succeeded
Thanks for your help.
PS:
I kept it like that.
Question: should we add an option:
force
to overwrite also directories.Python seems not to allow such: shutil.copytree
but that does not mean
julia can't have it
.If so - should that also apply to files or leave file to be overwritten anyway