pipenv: Lock updating is very slow
Updating a lockfile can be very slow. A standard pipenv lock
easily takes well over a minute for me:
$ time pipenv lock
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (abef76)!
real 1m56.988s
user 0m21.805s
sys 0m2.417s
This means every time I need to install, uninstall or upgrade a package I need to take a 2-minute break to wait for pipenv to finish updating its lockfile. I’m not sure why that is; yarn and npm seem to perform a similar task but only take seconds, even for projects that have many many more dependencies.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 136
- Comments: 52 (7 by maintainers)
@iddan Thanks for the reminder, Captain Obvious!
Read this while waiting for pipfile to lock…😃 Would be great if there was a solution.
It’s still super slow
We are aware and have many issues tracking this topic. See #1785 #1886 #1891 and PR #1896
npm and yarn have the advantage of not having to fully download and execute each prospective package to determine their dependency graph because the dependencies are specified in plaintext. Python dependencies require us to fully download and execute the setup files of each package to resolve and compute. That’s just the reality, it’s a bit slow. If you can’t wait 2 minutes or you feel it’s not worth the tradeoff, you can always pass
--skip-lock
.Closing to track in the other issues.
Sorry, as an OSS maintainer I know how sometimes issues can get dismissed because of age. Just wanted to state that even the issue received discussion it’s still relevant
This is pretty consistently happening, essentially
pipenv
going away around town while “locking” something: why is this issue closed?Understand the
--skip-lock
is the way to go, but it’s not clear at all why “installing” takes a few seconds, and “locking” takes forever: it would be great if at least the lock command would emit some progress/update logs: as things stand, it’s not even clear if it just got stuck in some sort ofwhile True
forever…I’d at least like to know if it’s me doing something wrong, or just a “feature” of pipenv.
As far as I gather, the overwhelming benefit of pipenv is the assurance dependencies will play nicely together — not just for you, but for anyone later dealing in your code. The product of that assurance, the lock file, absolutely takes more time than anyone expects or desires, including the devs — see #2200.
However, I think you can also understand the opportunity pipenv has to shepherd well-meaning devs in the Python community at large toward a workflow imposing less head-scratching on future contributors — who might’ve only been visitors had they given up during the “figure out how to setup the dev environment” stage; and less hands thrown up by future maintainers — who might’ve only been drive-by PR authors had they given up during the “seriously screwing around with deep project internals” stage.
If
--skip-lock
were to become a permanent flag in a Pipfile or a setting in a pipenv config, pipenv’s perception would slowly slide toward “better pip”, and just another stepping stone fading into the horizon as the community eventually landed on a less compromising spiritual successor.Better to leave it available only as an env var, or some other method whose application rests squarely in the “your user-specific local config, your fault” territory, allowing pipenv to overcome the passing phase of lockfile generation slowness without giving up the truly beneficial cultural shift toward explicitness over implicitness in package management.
Python’s incredibly vast standard library is an enormous asset, whose history has undergone many eras of imposing consistency. That most standard packages play nicely together is an enormous feat involving consideration over many years by many people. One day, that play-nice-ability will extend to most Python projects encountered on the web — far, far from the stdlib, and with far, far fewer PEPs required (and far, far fewer BDFLs vacating in frustration). The impact of such a unilaterally buttery experience is hard to measure, but some current languages did refuse to compromise conceptual integrity for immediate convenience… and oh, the places they’ll Go.
So yes, generating the lockfile is slow, and yes, it’s frustrating when you only wanted
pip install --save
. But it’s only because we’ve been sweeping an elephant into the closet for years — believing we didn’t have a tangled mess of expectations and intentions from external dependencies, because “it installed fine on my machine”.Lockfile generation is slow only because it’s making explicit what we’ve all taken for granted. But because it hurts, we will adjust things so it doesn’t. We broke our arm because we pushed ourselves doing things we believed in. Sure, we can avoid the pain by never using that arm again— or we can put it in a cast while it heals.
I’d be the last person to tell you not to make pipenv convenient for yourself today (otherwise I’d be a shitty developer — though, the jury’s still out), but I implore you to see the frustration of lockfile generation as a growing pain while the Python community develops into a strong, healthy body with more fully-functioning limbs than one really expected when removing a cast. We made it to Python 3. Let’s make it to dependency management in the stdlib.
You can get dependency information from PyPi without downloading the entire bundle (see PEP 566, which superseded PEP 426).
@techalchemy what if it takes 20 minutes with my brand new mac pro?
This took 38 minutes on my machine to create the lock file. Running Windows 10 and using Python 3.7
Please reopen this issue. Otherwise pipenv will never be the reference packaging tool
Seems like we need some kind of API to parse and cache Python packages deps and distribute it in a machine-friendly format. So we will no longer need to download entire packages and parse them.
FWIW I’ve removed pipenv from all my projects (this being the one main reason, there are others).
virtualenv
+pip
(withrequirements.txt
) now work pretty well, even for Prod deployments; and in any event, one deploys a fully-formed container these days; after getting really into pipenv, I no longer see the point of it.@techalchemy note of
--skip-lock
above is wonderful. This should be a more accessible or publicized option. Can we set it as a default somewhere?@brandonrobertz from what I see, downloading all packages of the dependencies is where most time is spent. This also has been confirmed before.
How to verify this:
Pipfile
and installingscipy
(for example) in it with locking enabledPipfile.lock
pipenv lock
- locking now will take very little time (6 seconds on my machine), because all packages are already downloaded and kept in Pipenv cache which is normally in~/.cache/pipenv
Here’s the Dockerfile I used to test this:
This is the workaround I use for now:
Then
pipenv install foo
won’t be locking and you can lock manually when you have time by runningpipenv lock
.I’m trying to install PyTorch and it took 20 minutes to lock and then it pulls the following error
The error is unreadle, no idea what went wrong. Installing with pip in the environment work fine! This is really a show stopper. Going back to requirements.txt…
Can you point me in the direction of where to find that code? I could take a stab at parallelizing it in a fork.
FYI I found tensorflow is the culprit of the slow/timing out lock, if that helps profile pipenv! (Still consider this a pipenv problem…)
Locking dependencies is important so I don’t think “skip lock” is a lasting solution. At the same time, I simply don’t buy that “locking dependencies” (whatever that could possibly entail under the hood) is maximally optimized as it is now and functionally requires many minutes or hours to complete. Indeed, my pipenv lock ran for several minutes on a Pipfile that has a laughable 5 dependencies before failing—stack attached at bottom—and during that time used only 10–15% of available CPU and a little sip of memory.
Can we at least put forth some group effort to profile and determine the bottlenecks? I have a feeling there are just some silly low hanging fruit in there just waiting to take this process into reasonable runtime.
pipenv version 2018.11.26
For Pipfile:
Java also has POM files (XML) which contain package dependencies and other information about the package. They are uploaded separately from the compiled JARs.
If you can provide a Pipfile that reproduces the slow behavior it would be helpful – thanks
Same here im trying it out right now and installing django is already at 10 minutes and going
For what it’s worth, it still feels too slow. Is there a different issue where this is tracked?
It’s still super slow. I recommend going with Poetry.
In my case the problem seems to be pylint. It always hangs on locking when simply running
pipenv install pylint
see https://github.com/pypa/pipenv/issues/2284#issuecomment-569457752I believe bundler and ruby gems maintains and uses somthing like that.
@lyle-nel I don’t think re-opening this specific issue would help since the content of it is dated, for example,
This is no longer true about
pipenv
as it gets the package hashes from the pypi API. There is a merged PR connected here that relates back to the issue at hand being resolved. If the community still feels that locking is very slow (too slow) and that there might be some optimization that can be done that wouldn’t compromise the integrity of locking (I am unsure) then at this stage, the path forward is to open a new issue with as much detail as possible, including method for reproducing the issue using the latest version of pipenv, and any suggestions on how to improve it would make the ticket even better.@awhillas Pretty sure the last line says all you need:
Every newer package manager has some separate meta files (npm/yarn, composer, gradle/maven, cargo, ruby gems/bundler, …).
No. Pipenv is an application depedency resolution tool. When a dependency is used as a Python package by another application, it is no longer an application. Its dependencies are determined by setup.py (or setup.cfg or whatever you use to upload to PyPI). Loading dependencies from a lock file is a sure route to dependency hell, we will likely never ever do that.