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
Improve os.rename documentation and tests #60482
Comments
This is somewhat of a nitpick. os.rename's documentation says "If dst is a directory, OSError will be raised". On Unix, this isn't completely true. If the source is a directory and the destination is an empty directory, it'll overwrite the former with the latter. (Actually if the source is a directory the inverse is true; if dst is a file, OSError will be raised.) In [1]: import os In [2]: os.mkdir("aaa") In [3]: open("aaa/blah", "w").close() In [4]: os.mkdir("bbb") In [5]: os.rename("aaa", "bbb") In [6]: os.listdir("bbb") |
David, For Python 3.4 here is the fix I came up with: I have attached a Python 3.4 patch for consideration. This might not be the best phrasing so please feel free to offer alternatives. |
Chris, maybe you can guess better wording? |
Before we discuss wording, it's not clear to me whether all possibilities have been checked. I count 2*3*2=12 possibilities to check (excluding src and dst being on different filesystems): src: file or directory Also, do we have tests for all of these scenarios before we document it? |
Thanks for the feedback! Over the weekend I will make sure the documentation and test cases cover all possibilities. I have not worked with test suite but I will do my best. |
Over the weekend I verified the test cases are incomplete for Python 3.4. Inside of Lib/test/test_os.py is a class FileTests that contains a single function test_rename which seems to only check to make sure that the reference count for the first argument is not mis-handeled. Nothing exists for the use case destination is a directory as described in the original bug. I will attempt to create suggested test cases but as I am not the most familiar with Python's unit test framework it might take me some time, I estimate as long as 11/6/2012. If somebody comes along with more experience that can fix the bug please feel free to proceed. |
While writing test cases I discovered another conflict with the documentation. The phrase "On Unix, if dst exists and is a file, it will be replaced silently if the user has permission and src is a file." is not correct. According to the test cases I wrote in the attached patch see the method test_rename_src_file_dest_file_exists in the class FileTests the destination file is not replaced and the source file actually is removed. I will seek advice from Python Core Mentorship to see if this is a bug or normal behavior. First time writing test cases so I hope I am on the right track. |
False alarm my test case was buggy. |
Attached is a patch for 16 test cases. All 16 test cases have been tested on Windows 7, Mac OS X, and Linux they seem to function well. Before this patch there was only a single test case for rename. For each test case I used "unittest.skipUnless" to make sure the platform was one of the three that I tested for Windows 7, Mac OS X, or Linux. These test cases demonstrate that the documentation is incorrect and perhaps a little fuzzy. I plan to submit updates to the documentation in the coming days. This patch is only for Python 3.4 but I will backport to 2.7 in a few days. I wrote the following code to find all the combinations based on parameters of the function: src = ['src_file','src_directory_empty', 'src_directory_not_empty', \
'src_file_or_directory_not_exist']
dst = ['dst_file_exist','dst_not_exist','dst_directory_empty', \
'dst_directory_not_empty'] print "Make sure you have functions in test_os for all of these" |
The test cases look quite verbose (e.g. they're not DRY), but it's a good start. Thanks. For others' benefit, can you perhaps summarize your findings concisely in a table/chart of some form? |
Chris, For Unix |
Here is a draft suggestion for the documentation change, not all the formatting is worked out: .. function:: rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None) Rename the file or directory *src* to *dst*. If *src* exists as either Unix Windows If successful, the renaming will be an atomic operation (this is a POSIX This function can support specifying *src_dir_fd* and/or *dst_dir_fd* to If you want cross-platform overwriting of the destination, use Availability: Unix, Windows. .. versionadded:: 3.3 |
Attached is patch with the final formatting for the documentation updates. I fixed the :exc:`OSError` problems that I had before and used indents to denote Unix behavior VS Windows behavior. Please let me know if I can do anything else to help get this issue resolved. Thanks! |
This is a gentle ping of this issue. Can somebody please review and let me know what needs to be done to get this committed? I did test the patch on 2/12/2013 and it seems to work from the latest 3.4. Thanks! |
The doc change looks good to me. I am adding Terry and Ezio to see if they have any comments on wordings in the doc. If not, I can commit this change. I think that this is helpful. |
I commented above that the tests are not very DRY though. Shouldn't there be tests to check that the documented behavior is correct? |
Chris: The patch is for the docs. the test code I believe, is for |
Chris, I am a fairly new Python contributor and this is my first attempt at writing test cases so I could be missing something. Thanks for the mentorship and the time required for a little extra guidance. |
Senthil, in my experience, whenever documentation is added that documents new aspects of behavior (e.g. is not just a rewording of existing documentation), tests are always added simultaneously (if not already present) to ensure that the code doesn't regress against the new documentation. Todd, DRY means "don't repeat yourself." You can look it up on Wikipedia, etc. Identical chunks of code are repeated several times which make it harder for others to see how the test cases differ from each other (as well as making the code harder to maintain). |
Yes, a single patch is best. One way to make code more DRY is refactoring to use helper functions as needed (i.e. same code in multiple places -> one helper function). |
Chris, |
The number of test cases isn't the problem. Having more but finer-grained test cases is usually preferred in fact. It's just that the test cases should be sharing code where possible so that they're shorter and easy to see how they differ from one another. |
"directory name.Yet a" needs spaces after '.'. The text is decent English and clear enough sentence by sentence, but the reality and hence the text as a whole is confusing. I wonder if it would be possible to make a little table
Src file empty-dir non-empty-dir dir with the behavior for each combination indicated, 'success' or 'OSError', with two lines prefixed with Unix, Win where they differ. Then the differences would be much more obvious. (A separate issue: Patch says that Windows currently raises a different error in one situation. I think it would be better -- in a future version -- if that were caught and reraised as OSError also.) |
Thanks Terry and Chris you guys have supplied great feedback. I will work on the issue and try to get a new patch updated by end of the weekend (2/18/13). Sent from my iPhone On Feb 13, 2013, at 11:56 PM, "Terry J. Reedy" <report@bugs.python.org> wrote:
|
Over the weekend I caught this terrible cold and have not been able to work on this issue much. Hopefully I can complete by next weekend 2/25/2013 thanks for your understanding. |
Combined the test cases and document changes into a single patch. As suggested by Mr. Terry Reedy I used a table and removed the text. The table still needs some work but it is a good start. As suggested by Mr. Jerdonek I tried to make the test cases WETter by setting up the files and directories one time in the setup method then only changing that setup in the actual test case only if needed. This patch needs still needs some work but I wanted people to know I had not quit yet. It still needs to be tested on Windows, which I will do ASAP. Thanks. |
Adding more tests is good, even though there are still a few things that should be improved (see comments on rietveld). |
Ezio, |
Version 2 of the patch includes many improvements most of which were suggested by Ezio making the patch a much higher quality. The patch is very WET at this point. I still need to test on Windows which I plan to do as soon as I can get my Windows partition in order. Thanks for all the great feedback! |
V3 added which includes much shorter variable names and a cleanup of the patch. I still need to test on Windows. |
Thanks for the feedback Vitaliy Stepanov that helped alot with the version 3 patch. |
Made some very minor changes to get patch to work on Windows. Had issues with line ending differences between Unix and Windows. I fixed it so line endings won't be an issue and tested patch on Windows, Linux, and OS X. Please feel free to supply feedback or commit. Thanks. |
Ping!!! I have not heard anything about this patch so I wanted to ping it to get more feedback. Thanks! |
Retested this patch with the latest 3.4 and made one tiny change to get it to apply cleanly. Please provide feedback or commit. I would like to get this committed after more than a year since the original bug report. |
I forgot to mention this patch only works on 3.4 but if it is committed I will work on a patch for 2.7. Thanks. |
|
In the current doc all cases seem to be covered, but just not in a table format. Is that something that might still be wanted? |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
DavidBenjamin mannequin commentedOct 18, 2012
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: