pip really sucks, in fact any packaging system discrete to its programming language sucks, because it bypasses the operating system's software management subsytem (pkgadd, pkgsrc, rpm, et cetera). Then one has to have an imaging system like Docker to work around that, so developer's convenience leads to one bad decision after another in the operational repeatability space.
I used to install Ruby gems with apt circa 10 years ago but quickly gave up because they were outdated and I couldn't have different versions in different projects. Same with Python later on.
Things like virtualenv solve the problem of having multiple versions of the same package or interpreter in different projects. Rpm and apt can't do that, that's why developers are using package managers for virtually every language. Furthermore creating native packages for even the major distros and LTS releases is too difficult. There are also tools like asdf that handle multiple languages (and databases!)
Docker solves the problem of distributing the application. Virtualenv is quite weak about that. Docker can also be used to create separate environments on the development machine and install packages without virtualenv. We still need pip because nobody creates native packages. The same reasoning applies to every language I'm working with (Ruby, Node, Elixir, PHP.)
"Furthermore creating native packages for even the major distros and LTS releases is too difficult."
This is simply not correct: the truth is that people are lazy and don't want to spend the required time reading the documentation, the first thing a real engineer does. Instead, they just want instant gratification. They just want to hack. OS packaging is actually quite easy.
"We still need pip because nobody creates native packages."
I created over 170 CRAN R packages as RPM's. Was it time consuming? You bet! But now it's done correctly. Now it's done cleanly. Now I don't need nonsense like Docker, and I could even plug them all directly into Kickstart and have Kickstart spit out ready to serve systems with a rich R environment on them. With no scripting or any code. Just because I made RPM's, the client now has an architecturaly simple application ecosystem. Simple is robust.
I did not create .deb's because my client uses a RHEL-based operating system. The point is that I had to do it because CRAN simply decided to re-invent the wheel. I did not contact every single one of the 170 authors to create RPM's: if they really wanted to, they would have done that by now, not to mention it would be impractical for me to contact 170 people and attempt to explain to them what it means to design for operational maintainability.
Yes, I maintain the RPM's. It's easy because I always build .src.rpm's (SRPM's) by default, and a binary .rpm (RPM) ends up being a product of one of the steps in that process (`rpmbuild --clean -ba ...`).
But all of that is almost irrelevant. The relevant bit is that if done correctly, if done cleanly, as operating system packages, organizations need neither Docker nor "infrastructure as code" (copious amounts of amateurishly written glue in a scripting language) and the software is easy and fast to install and maintain -- for both system administrators and end users. I even do very large scale configuration management with operating system packaging, rather than with applications like CFengine, Chef, or Puppet.