-
Notifications
You must be signed in to change notification settings - Fork 3k
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
when uninstalling, look for the case of paths containing symlinked directories #3154
Conversation
@pfmoore any advice on backporting |
@AvdN do you mind confirming this fix works for you as well? much appreciated if you can. |
@qwcode I can confirm this works for me as well. In the end (after more than 1.5 hrs) I ended up cloning your repo, and switching to the branch issue_3011 to test this. Gathering the information from this page ( starting with the proper |
@qwcode well, all os.path.samefile does in 3.4 is compare st.ino and st.dev from the stat structure. It's os.stat that has been updated to give useful ino/dev values in Python 3.4+ From 3.2 to 3.4, os.path.samefile just checked the filename (using _getfinalpathname, which may do a few extra things like resolve symlinks, I haven't checked). But honestly, I think that testing if the (normalised absolute) pathname matches is as good as you're going to get on <3.2 (short of ctypes or C code). |
for cpath in compacted_paths] | ||
) | ||
same_file = any( | ||
[samefile(path, cpath) for cpath in compacted_paths] |
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.
on 2nd thought, a samefile check isn't right here, because hard links report true for this, but they can be deleted independently.
sorry, @AvdN , I should have pasted some quick instructions for testing it : ) |
ok, I've updated this again with new logic based on this comment #3154 (comment) see the new description. I've tested locally (in addition to the automated tests) for the known case (#3011 (comment)), but if people want to test, then here's the commands to install this branch
|
cc @takluyver since this relates to your #2552. |
@qwcode Thanks for ccing me. I'm having trouble trying to follow the logic in this PR, but from the description in #3141, I think it should be sufficient to normalise paths by resolving links in all but the last component: join(realpath(dirname(p)), basename(p)) Since #2552 was only concerned with the complete path referring to a symlink, this shouldn't break it. I think the code in this PR could fall down if you have a path where the whole path is a symlink, and a prefix of it is also a symlink:
Since |
thanks @takluyver . I think you're right about how this can break. I'll make another update. |
@takluyver , how about now? |
@@ -41,3 +41,31 @@ def test_add_symlink(self, tmpdir, monkeypatch): | |||
ups = UninstallPathSet(dist=Mock()) | |||
ups.add(l) | |||
assert ups.paths == set([l]) | |||
|
|||
def test_compact_shorter_path(self, monkeypatch): |
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 is secondary, I just added this, because we had no unit test for this
That definitely looks easier to understand. A couple of thoughts:
|
ok, as for the extra kwarg, yea, it's ok to leave IMO. might be used later. |
👍 from me |
Conflicts: CHANGES.txt
when uninstalling, look for the case of paths containing symlinked directories
Works on my end. Thanks! |
here's the fix I'd prefer for #3141 (as opposed to #3142)
It updates
UninstallPathSet.add
to deal with the case of paths containing symlinked directories.this doesn't undo #2552.
I'll admit some possible regrets on merging #2552 which caused this, but I still logically think it's the right thing.