pyenv install with zlib

I've lost count of the amount of times I've had to research this on a fresh install or different machine. Since python is not a language I use day to day, I constantly forget the environment configuration so I'm putting it here for quick reference when I will inevitably need it in a month or two.

Full credit goes to @tarrex for the original comment on this issue thread. I'm simply surfacing the important parts from that thread for quick reference, mainly for my own needs.

For reference, my current system enviroment at time of writing (2019-04-10) is:

You're likely to end up here if you searched for an error message along the lines of:

zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1

Your first instinct (as mine was) would be to brew install zlib, but you'll soon find that won't resolve your issue. The problem lies in fact with the compiler not knowing where zlib is located on your machine, rather than it not being installed. Fixing this is, thankfully, quite trivial.

First, you'll want to make sure pyenv and zlib are actually installed and up to date:

brew install pyenv zlib

Next, you'll need to grab the compiler exports which can be found via the info command:

brew info

This is likely to yield something like the following:

zlib: stable 1.2.11 (bottled) [keg-only]
General-purpose lossless data-compression library
https://zlib.net/
/usr/local/Cellar/zlib/1.2.11 (12 files, 373KB)
  Poured from bottle on 2019-04-10 at 09:34:14
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/zlib.rb
==> Caveats
zlib is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

For compilers to find zlib you may need to set:
  export LDFLAGS="-L/usr/local/opt/zlib/lib"
  export CPPFLAGS="-I/usr/local/opt/zlib/include"

For pkg-config to find zlib you may need to set:
  export PKG_CONFIG_PATH="/usr/local/opt/zlib/lib/pkgconfig"

As the output suggests, you want to make sure that LDFLAGS and CPPFLAGS are set for the compiler (python-build):

export LDFLAGS="-L/usr/local/opt/zlib/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include"

You can even take this a step further and setup these environment variables as part of your bash or zsh profile, so you never have to worry about this again.

Finally, you are now ready to install your desired version of python!

pyenv install 3.7.2
pyenv local 3.7.2

You can now verify your new version of python is activated:

which python # $HOME/.pyenv/shims/python
python --version # Python 3.7.2

If everything went smoothly, you should now have a working version of python 3.7.2.

If you have any questions about this post, or anything else, you can get in touch on Twitter or browse my code on Github.