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

Full implementation of --keep-outdated #3304

Merged
merged 43 commits into from
Mar 30, 2019
Merged

Conversation

techalchemy
Copy link
Member

Introduces both a PEEP and a fully functional implementation of most features discussed

  • Arbitrarily numbers the PEEP 005 in case of merges ahead of this one
  • Outlines --keep-outdated behavior and provides a full working implementation
  • Follows implementation discussed in the initial design discussions

@techalchemy techalchemy added the Status: Requires Approval This issue requires additional approval to move forward. label Nov 26, 2018
@jxltom
Copy link
Contributor

jxltom commented Nov 27, 2018

This is an exciting feature. If this can be merged, let's update docs reflecting the changes and we also should add tests. :D

@jxltom
Copy link
Contributor

jxltom commented Nov 28, 2018

It looks like it is full support for pipenv install --keep-outdated but not for pipenv update --keep-outdated?

Existing packages in the project Pipfile.lock should remain in place, even if they are not returned during resolution;

This does not work perfectly for update. For example, if package a has dependencies b, c in existed pipfile.lock. And newer version a only has dependency b, with pipenv update a --keep-outdated, c should be removed if c is not dependency of any other packages in pipfile even it is not returned in resolution.

I think probably it is better to add one more step for --keep-outdated which checks dependencies of specific package in existed pipfile.lock and removes them if they are the only dependencies of that certain package and they are not returned in the new resolution.

@techalchemy
Copy link
Member Author

That sounds like maybe we want it for --selective-upgrade but I didn’t implement this in this way by accident. One of the first things I mentioned in the PEEP is wanting a way to ensure we aren’t making any changes to the lockfile that aren’t directly caused by the upgrade, including removing stuff just because we think you don’t need it. In fact that’s a large motivation behind making this PR: anytime I upgrade a cross platform Pipfile, I have to manually undo all of the removals of platform specific dependencies which are ‘no longer needed’. This feature would be pointless if it doesn’t offer that.

@jxltom
Copy link
Contributor

jxltom commented Nov 28, 2018

--keep-outdated is a way to ensure only direct changes can be made to pipfile.lock for install/lock/update. This makes sense to me. It would be nice for that to be documented, explaining the basic principles behind the scenes, probably as well as the differences with --selective-upgrade.

If I understand correclty, one more thing with such kind of design is that pipenv update <dep> --keep-outdated and pipenv lock --keep-outdated may keep more and more unnecessary dependencies as above example shows since these deps are actually no longer needed but being kept via --keep-outdated. It would be nice to document the side effect of this kind of usage. The pipenv install <dep> --keep-outdated doesn't have this side-effect as it will bring new deps only.

@techalchemy
Copy link
Member Author

It's not documented because it's not implemented, the documentation is outlined in the discussion linked in the PEEP.

The only additional element I am adding in this PEEP is that --keep-outdated also keeps dependencies that pipenv deems outdated at the project level, i.e. dependencies that are not considered necessary anymore. If you want to rewrite your lockfile, pipenv lock should handle that.

It is possible we should think of another flag to use to say "I don't mind updating the dependencies I have, but don't remove anything if it's in my lockfile". I'm not totally sure what that flag would be.

pipenv/environment.py Show resolved Hide resolved
pipenv/resolver.py Outdated Show resolved Hide resolved
@ncoghlan
Copy link
Member

This looks good to me, so the main things would be test and documentation updates.

Signed-off-by: Dan Ryan <dan@danryan.co>
- Bring in changes from bugfix/3148

Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
- Lost numerous changes in the rebase, this brings them back
- Should work for both sets of fixes now

Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
@techalchemy
Copy link
Member Author

/cc @ncoghlan on the tests

@ncoghlan ncoghlan changed the title Full implemenation of --keep-outdated Full implementation of --keep-outdated Mar 17, 2019
Copy link
Member

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, those new tests look good to me - good idea to check the behaviour when the Pipfile change is to remove a pin rather than adding a new dependency.


## Necessary Changes

In order to make these changes, we will need to modify the dependency resolution process. Overall, locking will require the following implementaiton changes:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in "implementaiton"

pipenv/core.py Outdated
if dep.is_vcs or dep.editable:
c.block()
# if dep.is_vcs or dep.editable:
# c.block()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this genuinely isn't needed any more, better to just delete it than comment it out

@@ -92,6 +93,55 @@ def test_lock_keep_outdated(PipenvInstance, pypi):
assert lock['default']['pytest']['version'] == "==3.1.0"


@pytest.mark.keep_outdated
@pytest.mark.lock
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor cosmetic thing: since the order to the marks doesn't matter, shorter-first looks tidier.

Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
Signed-off-by: Dan Ryan <dan@danryan.co>
@techalchemy
Copy link
Member Author

Pin removal is one of the things I added a test for at the end: check out

p._pipfile.add("requests", "==2.18.4")
c = p.pipenv("install")
assert c.ok
p._pipfile.add("requests", "*")
assert p.pipfile["packages"]["requests"] == "*"
c = p.pipenv("lock --keep-outdated")
assert c.ok
assert "requests" in p.lockfile["default"]
assert "urllib3" in p.lockfile["default"]
# ensure this didn't update requests
assert p.lockfile["default"]["requests"]["version"] == "==2.18.4"
which essentially just --

  • Installs requests==2.18.4
  • Unpins requests and re-locks with --keep-outdated
  • Validates that the version of requests locked is still 2.18.4 since it satisfies the constraints
  • Re-locks without --keep-outdated to verify that we actually would get an updated version if we didn't hold it back

Is that what you had in mind?

@ncoghlan
Copy link
Member

@techalchemy Sorry, I was overly terse in my review summary, which made it ambiguous - it was meant to mean "that was a good idea to ..." (i.e. praising the inclusion of that particular test, since it covered a case that hadn't occurred to me), but could be read as "it would be a good idea to ..." (which would have meant that I had missed the fact that the test was already part of the PR).

@techalchemy
Copy link
Member Author

hah, no worries, thanks for the reviews!

@techalchemy
Copy link
Member Author

@uranusjr @ncoghlan my only concern here is that the command now does too much from a design standpoint -- as a user of the tool myself, I personally would want to separate the functionality because as it stands pipenv lock --keep-outdated will:

  1. Retain dependencies that are no longer part of the resolution graph; and,
  2. Hold back any satisfied pins

I'll probably merge this as is for release but I want to continue thinking about splitting this up

@techalchemy techalchemy added Category: Dependency Resolution Issue relates to dependency resolution. Type: Release Blocker Must be resolved before the next release can be cut. Status: Accepted ✔️ This item has been reviewed and accepted. Type: Bugfix This issue provides a fix for a known bug. and removed Status: Requires Approval This issue requires additional approval to move forward. labels Mar 29, 2019
@techalchemy techalchemy merged commit b03a594 into master Mar 30, 2019
@techalchemy techalchemy deleted the feature/keep-outdated-peep branch March 30, 2019 00:49
@Turbo87
Copy link

Turbo87 commented Apr 26, 2019

nice work on this @techalchemy! do you know when the next release for pipenv is planned? would love to try this feature out :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Category: Dependency Resolution Issue relates to dependency resolution. Status: Accepted ✔️ This item has been reviewed and accepted. Type: Bugfix This issue provides a fix for a known bug. Type: Release Blocker Must be resolved before the next release can be cut.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants