-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
editable dependency causes wrong versions to be installed #4078
Comments
Anything I can do to assist with triage? |
ping |
The solution to this (to avoid compatibility issues in the next release anyway) will be to set Currently pipenv allows VCS dependencies to resolve on the fly unless they are installed in Sorry for the issue! |
https://github.com/bottom-text-everywhere/test-python-project/blob/master/Dockerfile#L7 Adjusting from version "2018.11.26" to "2020.5.28" ended up installing the RIGHT versions of dependencies and the Pipfile.lock file has new sha256 entries.
Is there any unit test or feature that should be added to ensure that constraints/contracts enumerated by the Pipfile are verified at the end of installing/syncing/locking dependencies? I can see this easily popping up again as people mix more flags into play ( note that adding PIPENV_RESOLVE_VCS=1 resulted in the same correct result with version 2020.5.28 so I'm not going to use it when we update our pipenv version ). My first rule when writing software is: "Don't lie to the user" I appreciate the feedback! Keep up the awesome work guys! |
This was definitely a bug in version 2018.11.26 Please let me know if you have any issue repeating it because I can 100% of the time and will modify my test for any env you need to use. I prefer linux ( and if I have to Mac ) - but I do all my real work in docker containers. |
From a user experience perspective I think we all can agree that it's definitely a bug: you're working with a dependency solver and it's not solving the dependency graph. From a tool maturity standpoint, it's a bunch of functionality that is honestly quite complicated and wasn't yet built as of the version you mentioned. From your perspective, you want to pin a version and have that take precedence no matter what -- for others, they want to install their (previously unresolveable) package and have it work. Because the nature of that problem means we don't know what that package will install along with it, it becomes a race to see what gets installed first -- your pinned package might win, (i.e. be installed last), but if it isn't, we would have no way of knowing anything ever conflicted with it as pipenv is not actually performing the installation. This is not impossible per se -- but again, the validation required was not something that we had developed. Hopefully that provides some insight about why things were the way they were -- far from perfect, for sure.
The issue is pretty well understood -- we really just were not resolving these at all in some cases because there was no tooling built around that use case. Over the last ~1 year we have built the tools to handle this a lot more robustly, which is why you can expect better / more thorough resolution now |
I actually have a different request and perspective. The Request:Please verify the end virtualenv package version contents against the set of constraints discovered when traversing a dependency tree as a lockfile is constructed/updated and possibly when installing from a lockfile's metadata view. Lets Get Technical:I understand the intricacies of resolving a tree of dependencies where each subsequent dependency can introduce another tree. If when traversing the tree of dependencies where results will be stored in a flat-way, a set of version constraints are incompatible and no resolution path is viable, then an error should be reported. I also know this is further complicated by the shear number of paths over time that pop up where constraints enumerate a minimum version but fail to set a maximum version. I am sure you have a technique for addressing these concerns and I trust they work. If I run Fail loud, fail proud, fail fast; fix and move on. 👍 The perspective:In my example, me enumerating the full set of dependencies and locking them to specific versions was a work around I chose to try. I was upgrading a project from pip to pipenv and wanted to make sure I kept all the same previously resolved dependency versions the same. Once I had a lockfile I would have gone back and made the versions in the Pipfile match the way they were declared in the legacy requirements.txt file. I was shocked to find that even when I attempted to lock the dependency to a specific version the resulting env DID NOT MATCH the explicit version I had stipulated. And that's my main issue I feel needs to be addressed in a more strict manner. This issue was a breach of expectations. This is especially bad when I see the lockfile says one version should be installed, but the reality is another version has made its way into the virtualenv that does not match the lockfile nor the Pipenv file. Pipenv can verify everything is khosher at least to the degree the various package authors and the root project importing packages stipulate in the Pipenv way, regardless of if there are legacy concerns from the way pip worked in the past. It was not a huge issue as we caught the subtly broken image had issues before it went live and a quick audit proved a version of a dependency was wrong and was causing the issue. I was just happy that we could explain some wonky behavior we've seen with Pipenv finally and offer a repeatable test back to everyone. I also can understand that this would seem pretty edgelord amongst the current community of users. Though I do have to wonder:
I would sleep much better at night knowing pipenv verifies that package versions are within the constraints discovered for the resolution path it chose. And I would sleep like a baby if I new for certain it honored the root project package constraints. In my opinion, this is behavior that needs to be looked at closer and prevented. I believed pipenv has two modalities:
The first would be used in cicd, the second in daily efforts as I import new things. Please let me know if my understanding is incorrect. This is how other tools like yarn, npm, gem, crystal shards work so I hope this holds true here. So far the latest version looks like it is miles ahead from the previous experience we had here! Thanks for your time and all the hard work! 😄 My only goal is to prevent a regression. Feel free to close this issue if you are certain a regression is no longer possible. |
Pipenv now feeds everything through the resolver -- I get that the previous behavior was not desirable, that's why we corrected it. All I'm saying is, given the situation at the time, the options were to have the previous behavior (sometimes, a VCS or file-based dependency would override something that was otherwise pinned or resolved) or to use pip which clobbers everything without regard for your environment. The previous approach handles most cases, operating under the assumption that this is surely better than just clobbering anything. Yes, the previous behavior couldn't fundamentally guarantee you a deterministic install if you didn't use editable dependencies.
This didn't work because pipenv didn't pass As a result, because this could happen in parallel, the VCS dependency will have its own dependencies installed at some arbitrary time -- and if done in serial, this happens as the last step. In old versions of pipenv, this is true even when using The latest versions of pipenv are able to resolve these dependencies and feed the constraints from the VCS dependencies into the initial constraint set of the resolver before resolution even begins. To illustrate the difference, lets take a sample [[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
colorama = "*"
requests = {git = "https://github.com/psf/requests.git", ref="5a1e738ea9c399c3f59977f2f98b083986d6037a"}
urllib3 = ">=1.25"
[requires]
python_version = "3.8" Pipenv 2018.11.26Pipenv 2020.6.2In the second case, /t/test2 pipenv lock --dev
[...snipped]
[pipenv.exceptions.ResolutionFailure]: Warning: Your dependencies could not be resolved. You likely have a mismatch in your sub-dependencies.
First try clearing your dependency cache with $ pipenv lock --clear, then try the original command again.
Alternatively, you can use $ pipenv install --skip-lock to bypass this mechanism, then run $ pipenv graph to inspect the situation.
Hint: try $ pipenv lock --pre if it is a pre-release dependency.
ERROR: Could not find a version that matches urllib3<1.25,>=1.21.1,>=1.25 (from -r /tmp/pipenvlsx1jhhhrequirements/pipenv-81b4tigh-constraints.txt (line 5))
Tried: 0.3, 1.0, 1.0.1, 1.0.2, 1.1, 1.2, 1.2.1, 1.2.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.7.1, 1.8, 1.8.2, 1.8.3, 1.9, 1.9.1, 1.10, 1.10.1, 1.10.2, 1.10.3, 1.10.4, 1.11, 1.11, 1.12, 1.12, 1.13, 1.13, 1.13.1, 1.13.1, 1.14, 1.14, 1.15, 1.15, 1.15.1, 1.15.1, 1.16, 1.16, 1.17, 1.17, 1.18, 1.18, 1.18.1, 1.18.1, 1.19, 1.19, 1.19.1, 1.19.1, 1.20, 1.20, 1.21, 1.21, 1.21.1, 1.21.1, 1.22, 1.22, 1.23, 1.23, 1.24, 1.24, 1.24.1, 1.24.1, 1.24.2, 1.24.2, 1.24.3, 1.24.3, 1.25, 1.25, 1.25.1, 1.25.1, 1.25.2, 1.25.2, 1.25.3, 1.25.3, 1.25.4, 1.25.4, 1.25.5, 1.25.5, 1.25.6, 1.25.6, 1.25.7, 1.25.7, 1.25.8, 1.25.8, 1.25.9, 1.25.9
There are incompatible versions in the resolved dependencies:
urllib3<1.25,>=1.21.1 (from -r /tmp/pipenvlsx1jhhhrequirements/pipenv-81b4tigh-constraints.txt (line 5))
urllib3>=1.25 (from -r /tmp/pipenvlsx1jhhhrequirements/pipenv-81b4tigh-constraints.txt (line 6)) This is expected because it's a fundamental shift in the design of how the resolver works. Does this clear things up? |
Absolutely, thank you for taking the time to go into such detail. It looks like this would effectively surface the concerns of unresolvable constraint sets to the user and fail rather than break any constraint contract/expectation set by the user on any level of the dependency tree. Glad to see that it is now possible to resolve all dependencies in the tree before installing them. Again, great work all! |
Because it is already fixed in 2020.6.2, I am closing it now. |
Issue description
An error is not reported at the end of a
pipenv sync
command if an installed dependency violates a constraint / does not match the version specified in the lockfile.An error is not reported at the end of creating a lockfile via
pipenv install
if an installed dependency violates a constraint specified in the Pipenv file / newly created lockfile.Looks like an editable dependency is key to causing this issue.
May be related to #3296
Note that there appears to be a datarace involved as SOMETIMES when I run
pipenv install
the versions that are installed match the generated/established lockfile and SOMETIMES they do not!The test case I describe here will be able to repeat the issue consistently. It appears to happen whenever there is a dependency of an editable dependency that is loosely locked down ( > or >= or < or <= or * ) this rarely happens if at all when such a dependency is locked down exactly ( == )
Output from test:
Expected result
I expect installed dependency versions to not violate constraints specified in the Pipenv file and I expect dependencies that are installed when running
pipenv sync
orpipenv install
to match exactly the version specified in the lockfile - whether that lockfile be pre-existing or newly created.If this does not happen, I expect an error to be reported.
( In addition, if the lockfile exists and I run
pipenv sync
I still expect the lockfile and Pipenv file to remain unchanged. Though there appears to be no issue around that combination of conditions I feel it should be enumerated. )Actual result
Versions of dependencies that violate the top-most Pipenv file are installed when running
pipenv install
. Also they do not match the version stated in the newly created lockfile.Versions of dependencies that do not match the lockfile are installed when running
pipenv sync
.No error is thrown.
Steps to replicate
Made a couple of minor tests that express the problem:
On a linux friendly system with make:
clone https://github.com/bottom-text-everywhere/test-python-project
cd test-python-project
install docker
make test
View the README.md file in the project root for more details.
There are two tests: calling
pipenv sync
and callingpipenv install
which creates a lockfile.$ pipenv --support
Pipenv version:
'2018.11.26'
Pipenv location:
'/usr/local/lib/python3.7/site-packages/pipenv'
Python location:
'/usr/local/bin/python'
Python installations found:
3.7.5
:/usr/local/bin/python
3.7.5
:/usr/local/bin/python3.7m
3.7.3
:/usr/bin/python3.7m
3.7.3
:/usr/bin/python3.7
2.7.16
:/usr/bin/python2
PEP 508 Information:
System environment variables:
PIPENV_VENV_IN_PROJECT
HOSTNAME
PYTHON_VERSION
DOCKER_SHELL_ACTIVE
PWD
HOME
LANG
GPG_KEY
TERM
SHLVL
PYTHON_PIP_VERSION
PYTHON_GET_PIP_SHA256
PYTHON_GET_PIP_URL
PATH
_
PIP_DISABLE_PIP_VERSION_CHECK
PYTHONDONTWRITEBYTECODE
PIP_SHIMS_BASE_MODULE
PIP_PYTHON_PATH
PYTHONFINDER_IGNORE_UNSUPPORTED
Pipenv–specific environment variables:
PIPENV_VENV_IN_PROJECT
:1
Debug–specific environment variables:
PATH
:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
LANG
:C.UTF-8
PWD
:/workspace
Contents of
Pipfile
('/workspace/Pipfile'):Contents of
Pipfile.lock
('/workspace/Pipfile.lock'):The text was updated successfully, but these errors were encountered: