How to use a different Python version in a virtual environment to solve version compatibility issues with brownie

n4n0b1t3
4 min readFeb 19, 2022

EDIT 26. Feb 2022:

  • After I wrote this article I ran into another problem. A python library has issues with directory names with dots in it like python3.9.venv. This has been taken into account here.
  • Most of the error messages I am recently getting are garbage, I don’t know if this is related to Python in general or rather a brownie issue. This makes it oftentimes very difficult to find out what’s wrong.
  • Another thing I changed: I noticed no differences between having a central directory for all virtual environments versus having one in each project folder. Since creating a virtual environment for each and every project is pretty redundant and creates a lot of clutter on my hard drive, I moved to have just one main directory for my virtual environments and simply activate them from within my project directory. It takes a bit of time getting used to the activation though.

Motivation

The current Brownie version v1.18.1 won’t install (in a virtual environment) on Python 3.10.2 (Win 10). This causes problems when testing for reverted transactions. More on that here:
https://stackoverflow.com/questions/71126128/brownie-testing-for-reverted-transactions-does-not-work-with-pytest-raises-or
eth-brownie/brownie#1441

Approach to fix this
The latest Brownie version can be installed without issues under 3.9.10. I don’t want to downgrade my standard Python so I will create a virtual environment with this specific Python version and install everything in there.

Workflow

The following workflow assumes you have already a running Python version. It is written for Windows but can be easily adapted for Mac. All command line stuff I am doing in Powershell. The setup is my personal preference, there are many ways to organize your code and this is just an example.

Prepare your Python version and install virtualenv

In my home directory, I already have a directory called pythonversions. To create one simply do ...

cd $home
mkdir pythonversions

Download the Python version you need, e.g. Python 3.9.10. I downloaded the MSI Installer 64bit

Install the Python as “custom installation”. Since I don’t want this to become my standard python version I deselected “add to Path” and all other optional features besides pip before proceeding. I will need pip. During the installation process, I create a directory within pythonversions named after the version number, in my case 3.9.10. This step unpacks Python into pythonversions/3.9.10

With my main Python version I install virtualenv like so:
pip install virtualenv

Setup your virtual environment for a specific Python version

Under my home directory, I create a directory that will host all virtual environments.
In PowerShell:

C:\>cd $home
n4n0b1t3>mkdir virtualenvironments
n4n0b1t3>cd .\virtualenvironments\
virtualenvironments>

The syntax for creating a virtual environment is the following:

python -m virtualenv -p="<path to the python executable >" <virtual_environment_directory>

Here is an example.

virtualenvironments>python -m virtualenv -p="C:\Users\n4n0b1t3\pythonversions\3.9.10\python.exe" py39bro

I used py39bro as a directory name because I want it to be short and I want to see the python version and if it contains brownie. Name it to your liking.

Setup your project with node.js

Since my project works with brownie, I will have to install nodeenv for node JS capabilities in order to install ganache.
For one of the next steps (nodeenv -p) I need to open my Powershell as Admin. I keep the other Powershell window in the background because I will come back to it later. Press WindowsKey >enter “PowerShell” > right-click on Powershell in start menu > select “run as administrator” > confirm > navigate to your project directory.

Activate the virtual environment. This can be done from any directory, not necessarily from your project root.
The following are not my actual command in PowerShell, I just want to illustrate that the TAB key is your friend.

myProject>$home\virtualE <-- just type the first few letters and press TAB and it will automatically fill out the rest
don't press Enter
myProject>C:\Users\n4n0b1t3\virtualenvironments\ <-- type the name of your virtual environment
don't press Enter
myProject>C:\Users\n4n0b1t3\virtualenvironments\py39bro\ <-- continue to Scripts\activate.ps1
don't press Enter
myProject>C:\Users\n4n0b1t3\virtualenvironments\py39bro\Scripts\activate.ps1
now press enter!
(py39bro) myProject>

Great your virtual environment is activated. Make sure you are running the correct Python version

(py39bro) myProject>python --version
Python 3.9.10
(py39bro)myProject>pip install nodeenv
Collecting nodeenv
Downloading nodeenv-1.6.0-py2.py3-none-any.whl (21 kB)
Installing collected packages: nodeenv
Successfully installed nodeenv-1.6.0

Connect nodeenv with your virtual Python environment

(py39bro)myProject>nodeenv -p

Installing the payload (stuff I actually want to work with)

At this point, I can close my elevated Powershell window and return to the normal Powershell.

Install ganache
(py39bro)myProject>npm install -g ganache

Install Cython to avoid Cytoolz error
(py39bro)myProject>pip install Cython

Install brownie
(py39bro)myProject>pip install eth-brownie

Now comes the moment of truth. I did all this to get to the newest brownie version, which failed installation on Python 3.10.2. with
ERROR: Could not find a version that satisfies the requirement vyper==0.3.1 (from eth-brownie)

(py39bro)myProject>brownie --version
INFO: Could not find files for the given pattern(s).
Brownie v1.18.1 - Python development framework for Ethereum

Hurray, I finally installed Brownie v1.18.1 … And yes, brownie introduced the error “INFO: Could not find files for the given pattern(s).” which will accompany me from now on without any impact besides creating a slight annoyance.

Just to finish this preparation I will

(py39bro)myProject>brownie init

Disclaimer: I am by no means an expert. In fact, I started a few months ago with learning blockchain development. I hope that this post will be obsolete soon and Python, Virtualenv, nodeenv, Cytoolz, Brownie, Vyper, and … will play nicely with each other. Until then, hope this solved your problem too.

(py39bro)myProject>deactivate

--

--