For a long time, I have been happily using pyenv as my support infrastructure when setting up a Python environment. But now apparently the powers that be in the Python world have given their blessing to make pipenv the official tool for such things.
The problem I have found with
pipenv is that it wants to run in a non-virtualenv environment,
so that it can manage the virtualenvs itself. But usually I really try to avoid using the
system Python for my own projects, as the system usually has assumptions and settings that
may conflict with my intentions or needs. (This is why
pyenv is so handy.)
I’ve found a technique that does the minimal steps needed to get
pipenv working, using the
system Python installation only for the initial bootstrap.
This installs the system packages required for
pyenv to build Python from source code,
and include all the extra modules such as SSL, SQLite, curses, etc.
$ sudo apt-get install \ git build-essential libssl-dev zlib1g-dev \ libbz2-dev libreadline-dev libsqlite3-dev \ wget curl llvm libncurses5-dev
pyenvitself, and associated plugins
This uses the very handy
pyenv-installer script to set everything up nicely from the
$ curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
The exact form of this step may be different for you, as you may have other ways of
initializing your environment, but the commands have to be run someplace in order
pyenv to run properly.
This method tacks the
pyenv initialization commands onto the end of your
$ cat >>~/.bash_profile <<EOD export PATH="\$HOME/.pyenv/bin:\$PATH" eval "\$(pyenv init -)" eval "\$(pyenv virtualenv-init -)" EOD
Be sure to either re-run your
.bash_profile (or whatever init script you added the
commands to) or just log out and back in, to get the environment set up for the next
steps. Something like
source $HOME/.bash_profile works well for me.
$ sudo apt install python3-pip python3-setuptools
This step is the crucial one. We need to install
pipenv as a local (“user”) install,
not in the system area. So we need to tell
pip this specifically:
$ python3 -m pip install --user pipenv
Use the version of your choice here; you can see the (very long) list with
pyenv install --list. You have to be very specific here.
$ pyenv install 3.6.5 # latest version as of this writing
.local/bindirectory to your shell path
We need to add a specific directory to the shell’s path in order to allow us to
pipenv without using the full path every time, which would be very annoying.
The command here looks very similar to the one for
pyenv in step 3, and as in
that step, you may need to adapt it for your specific environment or tastes.
Also, as in step 3, be sure to re-run your shell init scripts with
or similar commands.
$ cat >>~/.bash_profile <<EOD export PATH="\$HOME/.local/bin:\$PATH" EOD
You can be a little less specific in the version of python you ask for in this step.
pipenv will grab the latest patch version of e.g. Python 3.6 if you ask for just
$ mkdir myproject; cd myproject $ pipenv --python 3.6 # match the version installed in step 6
Now you should be able to follow the rest of the
pipenv instructions on creating a
Pipfile, etc. (Actually
pipenv will have created one for you at this point, so you
can just fill out the rest of what you need inside it.)
At this point my personal technique is to install
pipenv directly into the virtual
environment I’m working with, having set it up with
pyenv virtualenv 3.6.5 foo pyenv local foo pip install pipenv
I prefer the way that
pyenv creates its virtualenvs (more specifically, it lets you control the names of the
virtualenvs instead of appending some random string and throwing it in your
pipenv does complain for some reason about the
--system flag being used although I didn’t actually use it.
I found a bug report which mentions that this will be fixed soon, so perhaps there’s no
reason to worry much about it. In any case,
pipenv detects that it’s already running
in a virtualenv and works fine with it.
Now if I could only get PyCharm to recognize and use the
.python-version file that
pyenv creates, I’d be
in for much smoother sailing…
It seems that the bug which thinks the
--system flag has been used,
when it hasn’t, has mutated into a more serious version that causes
pipenv to abort in a couple different circumstances. Fortunately,
until this is properly fixed (as I believe it will be shortly), there is a
monkeypatch which will work for now.
To patch this, you need to find where
pipenv is actually installed.
In my case (with
pyenv) I can use
$PYENV_VIRTUAL_ENV/lib/python*/site-packages/pipenv. This bug seems to be specific to
pyenv (from my
limited experience) so that may be all you need.
site-packages/pipenv directory, you need to edit
There are two lines that need to be edited, in a similar fashion. In
my version of
pipenv these are lines 1322 and 1349. They are both
if statements; the first one is an
elif and the other one is a
The condition they are testing needs to be changed from
system or allow_global to
(system or allow_global) and not PIPENV_VIRTUALENV.
This should fix the problem, as far as I can see. May your luck be as good or better than mine. :)
The problem seems to be fixed in pyenv’s github repo, but hasn’t been released yet. Currently I am using the following command to install pipenv (this checks out a specific git commit from the pyenv repo, so it will quickly be out of date):
pip install git+https://github.com/pypa/pipenv.git@1afee9a118982a46d570e8ce7ce00dfd37f8da85
There is a new release of
pipenv to the pypi package index, which
seems to have solved the aforementioned errors. Installing the specific
git commit is therefore no longer necessary.