Setting up Python and virtualenv with pyenv
Tags: python, pyenv, bash, setup
Published: 2023-01-04 23:08:22

---
title: Setting up Python and virtualenv with pyenv
published: true
date: 2021-01-04 08:00:00 UTC
tags: python,pyenv,bash,setup
canonical_url: https://www.hackerculture.com/python-setup/
---

 ![Setting up Python and virtualenv with pyenv](https://www.hackerculture.com/content/images/2021/05/9d2e8896750899.5eb54f3381452.png)

In this one, I’ll show you how to set up your local machine for python development so you can get started with python today. Let’s go!

Python comes preinstalled in most operating systems by default. But sometimes you may want to upgrade to a newer version of Python or a new version of a library that you depend on which is not compatible with your current version of Python?

If you upgrade your system version, you may introduce changes that are not backward compatible, and you may find yourself hours deep into the rabbit hole of upgrading your entire system.

What we should do instead is use a library like Pyenv for installing multiple versions of Python and switching between them as needed.

We'll also see how virtual environments can help us isolate changes between projects and how to keep project dependencies pinned to a specific version of Python.

## Requirements

- Ubuntu 20.x / WSL
- Internet connection

Open up your terminal (if you’re using WSL, open up your Ubuntu terminal). First, we will update our package index and upgrade any installed packages.

```
sudo apt update && sudo apt upgrade -y
```

Enter your password if prompted and wait for the terminal to finish.

…

Now, we will install all the python toolchain dependencies and build tools. Even though Ubuntu ships with python installed, we still need some other libraries to build and run python packages. This is the recommended list of dependencies for sane build environments, [according to pyenv instructions](https://github.com/pyenv/pyenv/wiki#suggested-build-environment).

```
sudo apt install -y make build-essential build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev python-dev python3-dev python3-pip python3-virtualenv python3-venv git
```

Once that finishes, you should have all the necessary libraries installed. Now for the python specific part.

## Pyenv

The recommended way to manage your python dependencies and packages is to encapsulate your builds inside a python virtual environment. You might be wondering if you really need this, the answer (unless you want to spend most of your time in package versioning hell) is definitely yes.

We’ll use **pyenv** to manage python installations.

```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

We also need to add these lines to your _.bashrc_ (or _.zshrc_ if you use **zshell** )

```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

Finally, you will need to reload your terminal session to apply the changes, or run `source ~/.bashrc`.

Now, let’s go ahead and make sure we have Python installed.

```
python3 --version
# Python 3.8.6
```

So my current version is 3.8.5 but there are newer versions out there. We can install them using **pyenv** without messing with the default system version.

```
pyenv install 3.11
```

Once that’s done, we can list all the installed versions with:

```
pyenv versions
* system (...)
  2.7.18
  3.8.13
```

You should see some output like that, which tells me I have a system version, and others installed and available.

The reason why this matters is that some legacy python code needs to run with _python2_ while newer code should be using _python3_ versions. Also, when a new version of python comes out, you can try it in a new project by installing it with **pyenv** without having to worry about other legacy code not being able to run on the newer version.

## Python virtual environments

Let’s introduce virtual environments by looking at a problem you might encounter. You start working on some project which uses some pip package, like pandas. Without knowing about virtualenvs, you just do what one does to install pandas like _pip install pandas_ and just continue your work.

All is good and well… except for the fact that now you installed a version of pandas in your system dependencies, which means some code you wrote months ago that depended on pandas too is now broken **because pandas changed versions** and now it’s incompatible with your old code. That can be very messy.

What we really want is to make sure whatever version of pandas we build our project with **never changes behind the scenes** , so our code stays working even though pandas itself might change in the future. This is known as **locking your dependencies** , and that’s exactly what virtualenvs are for.

Let’s install virtual environments on top of **pyenv**.

```
git clone https://github.com/pyenv/pyenv-virtualenv.git $(pyenv root)/plugins/pyenv-virtualenv

echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.profile
```

Now I’ll show you how you can use virtual environments to isolate dependencies for a new project. I recommend creating a `src` directory in your root dir and putting all your projects in there. Like this

```
exec "$SHELL"

mkdir ~/src/new-project
cd ~/src/new-project

pyenv virtualenv 3.11 venv
```

This just creates a new virtualenv which will use `python3.10-dev` called `venv`. You can use any version of python installed by **pyenv** and any name you like, I just happen to use `venv` for consistency.

The last step is to actually activate the environment, so every command we run in this directory is isolated from the rest of our python installations.

```
pyenv activate venv
```

Now, you should see something like this

```
(venv) user@epyc02:~/src/new-project$
```

That first part on your path is telling us we are inside a virtual environment called `venv`.

BTW you can exit the virtual environment with `pyenv deactivate`, in case you want to switch between projects or install some packages outside your project.

### Wrapping up

OK so now you are all set with python and you can install any dependencies in your project by running `pip install <package>`. This will save your packages inside of your `venv` directory and they will be local to your project. If you’re using **git** it’s recommended to ignore everything under your `venv` directory, so go ahead and add venv to your gitignore. _Note: if you called it something other than venv, substitute your environment’s name below instead of venv._

```
echo 'venv' >> .gitignore
```

That way if you deploy your code later or someone is pulling your code but has a different type of CPU when they install the packages they will actually get the right build for their particular environment.

And that is all for our python environment setup. Go write some code!