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

when uninstalling, look for the case of paths containing symlinked directories #3154

Merged
merged 4 commits into from
Oct 3, 2015
Merged

Conversation

qwcode
Copy link
Contributor

@qwcode qwcode commented Sep 30, 2015

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.

@qwcode
Copy link
Contributor Author

qwcode commented Sep 30, 2015

@pfmoore any advice on backporting os.path.samefile for windows <3.2 (see the description)

@qwcode
Copy link
Contributor Author

qwcode commented Oct 2, 2015

@AvdN do you mind confirming this fix works for you as well? much appreciated if you can.

@AvdN
Copy link

AvdN commented Oct 3, 2015

@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 git remote add, seems impossible for someone with a limited VCS/DVCS experience (30/10y respectively))

@pfmoore
Copy link
Member

pfmoore commented Oct 3, 2015

@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]
Copy link
Contributor Author

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.

@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

sorry, @AvdN , I should have pasted some quick instructions for testing it : )

@qwcode qwcode changed the title when compacting the uninstall set, detect when 2 paths are the same file when compacting the uninstall set, look for the case of paths containing symlinked directories Oct 3, 2015
@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

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

virtualenv  mytestVE
source mytestVE/bin/activate
pip install -e git+https://github.com/qwcode/pip@issue_3011#egg=pip

@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

cc @takluyver since this relates to your #2552.

@takluyver
Copy link
Member

@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:

/blah/blah/symlink_to_dir/blah/blah/symlink_to_file

Since islink() will be True on the whole path, you'll never normalise the earlier symlink. But I may be missing something.

@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

thanks @takluyver . I think you're right about how this can break. I'll make another update.

@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

@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):
Copy link
Contributor Author

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

@qwcode qwcode changed the title when compacting the uninstall set, look for the case of paths containing symlinked directories when uninstalling, look for the case of paths containing symlinked directories Oct 3, 2015
@takluyver
Copy link
Member

That definitely looks easier to understand. A couple of thoughts:

  • You probably want to pass tail through normcase(), since it's now bypassing normalize_path(), to ensure equivalent filenames on case-insensitive filesystems match.
  • I added the resolve_symlinks parameter to normalize_path in Don't follow symlinks when uninstalling files #2552. If no other uses have been added, you may want to remove it again now that it's not called here. On the other hand, it's not much extra complexity, and it's conceivable that it may one day be useful again.

@qwcode
Copy link
Contributor Author

qwcode commented Oct 3, 2015

ok, normcase added. good point.

as for the extra kwarg, yea, it's ok to leave IMO. might be used later.

@takluyver
Copy link
Member

👍 from me

qwcode added a commit that referenced this pull request Oct 3, 2015
when uninstalling, look for the case of paths containing symlinked directories
@qwcode qwcode merged commit 55a3ea8 into pypa:develop Oct 3, 2015
@mathieulongtin
Copy link

Works on my end. Thanks!

@lock lock bot added the auto-locked Outdated issues that have been locked by automation label Jun 3, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jun 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
auto-locked Outdated issues that have been locked by automation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants