-
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
Don't assume master branch exists when reinstalling editable package from Git #4450
Conversation
Something seems suspicious about what's being proposed because |
Are you fixing a different, but related issue? |
pip/vcs/git.py
Outdated
@@ -134,7 +134,7 @@ def obtain(self, dest): | |||
rev_options = [rev] | |||
rev_display = ' (to %s)' % rev | |||
else: | |||
rev_options = ['origin/master'] | |||
rev_options = ['refs/remotes/origin/HEAD'] |
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.
If this is a bug in vcs/git.py
, it seems like it'd be worth adding a lower-level / finer-grained test inside test_install_vcs_git.py
instead of only checking via a high-level end-to-end test. A possible example to compare to is test_obtain_should_recognize_auth_info_url()
.
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.
@cjerdonek I'm not sure I agree. I think this is perhaps close to what you're suggesting:
@patch('pip.vcs.call_subprocess')
@patch('pip.vcs.os.path.exists', lambda _: True)
@pytest.mark.network
def test_obtain_reset(call_subprocess_mock, script):
git = Git('git+file:///somewhere')
git.compare_urls = lambda *args: True
git.check_version = lambda *args: False
git.obtain(script.scratch_path / 'test')
assert call_subprocess_mock.call_args_list[4][0][0] == [
'git', 'reset', '--hard', '-q', 'refs/remotes/origin/HEAD'
]
This test is mostly just checking that rev_options
has changed, and doesn't really motivate the fix I'm proposing. Further more, it feels pretty fragile -- if we're not actually installing a package in the test, we need to do some monkeypatching to make the Git
instance think the package is already installed so that it attempts to update
it, and then there's a slew of sequential subprocess calls, only one of which we really care about.
I understand that such high-level tests are slow and expensive, but I think in this case it does make sense, although I'm open to further suggestions -- I'm relatively new to contributing to pip, so I'm not totally familiar with how we test it.
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.
It seems to me there's value in doing both (which is why I said "instead of only"): you can have the high-level test to check that the issue was fixed as reported. And you can have the lower-level, more focused test to check the function that you changed.
As far as making the lower-level test more sensible and less fragile, you'd probably know better than me what's appropriate. It seems like there'd be something worth checking about that function's behavior that makes sense. Instead of mocking the subprocess call, is there something else you can do to trigger the necessary pre-condition (e.g. call a different method on the Git
class)?
Another suggestion: would it make sense to do a real subprocess call to check the state of the repo after the method call, instead of using mocks?
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.
One more thing: my impression from digging into pip's code base and following some of the issues and conversation is that while most of the testing in the past has been focused on the end-to-end tests, there is some movement and desire to move towards finer-grained tests (one of the reasons being the slowness you mentioned).
So I think there's value in thinking about how we can better leverage finer-grained tests, even if the patterns aren't yet widely established.
@cjerdonek Contrary to the issue, the |
Okay, but the test is called There's also the issue that |
@cjerdonek Good catch, I will update the test name. I added a comment to #4448 indicating that the |
Since first commenting on this PR, I've become a lot more familiar with this area of the code. I'd like to make the following suggestion. Rather than setting if rev_options:
rev_options = self.check_rev_options(
rev_options[0], dest, rev_options,
)
else:
rev_options = ['refs/remotes/origin/HEAD']
self.run_command(['reset', '--hard', '-q'] + rev_options, cwd=dest) There are a few reasons for this. One is consistency. The other VCS classes set if rev:
rev_options = self.check_rev_options(rev, dest, rev_options) But in if rev_options:
rev_options = self.check_rev_options(
rev_options[0], dest, rev_options,
) One consequence of setting
It seems like this warning should be displayed only if a revision is explicitly provided in the URL, as in the fresh-install case. Another way of modifying this PR would be to change if rev:
rev_options = self.check_rev_options(
rev_options[0], dest, rev_options,
) |
Thanks @cjerdonek. It is indeed. I was looking for #647 since I remembered seeing it but wasn't sure where it is because there's like ~300 open issues. @di could you update the description so that it closes that issue? |
@pradyunsg Done. @cjerdonek Thanks for the review. I agree with your suggestion, I will try to make that change shortly. |
Hello! I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the |
I rebased this post-#4700. @cjerdonek I took a shot at doing what you're proposing here, but I think you missed that def check_version(self, dest, rev_options):
return self.get_revision(dest).startswith(rev_options[0]) I'm hesitant to do the refactoring necessary to make that work (although I do agree that it could be a good idea) simply because it isn't necessary to solve the problem this PR is trying to fix. I think it's a good candidate for one of your future refactoring PRs though.
Thanks for pointing this out -- I realized that this would actually happen with this PR as-is, since We don't actually have to use the full ref to solve this issue though, so I updated the test to not expect anything printed to stderr, and updated the default ref to just be Hopefully that makes this PR a little easier to merge 😉 |
Thanks for giving it some thought and for trying it out, @di. Using |
@di -- this PR is ready; right? |
@pradyunsg Yep! |
Thanks for the PR 👍 |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Fixes #4448, fixes #647.