Article summary
Python has always been an intriguing language to me, but I’ve never been a huge fan of its syntax. I have always liked Lisps, though. Thus, when I discovered Hy a few months ago, I was completely smitten. Then I tried to set up a development environment, and was caught in a morass of old tooling and poorly explained transitions. Python 2? Python 3? Pip? Setuptools? Easy_install? Ugh.
Thankfully, I’ve now discovered a few tools that make managing multiple versions of Python and your projects libraries a breeze (on Mac/Linux systems, at least). In this post, I’ll walk you through a basic Python setup to get you rolling on a new project.
Python Package Management
When confronting the problem of managing library dependencies, I was massively confused. Over the course of Python’s evolution, there have been many tools for managing and distributing packages. Googling around, you’ll find (at minimum) references to distutils, setuptools, easy_install, and pip.
Luckily, until you want to start distributing your own libraries, you can pretty much forget about everything but pip. As Anton Kovalyov quipped on Twitter, “easy_install is the internet explorer of Python package managers.” (It is only used to install pip when setting up your development environment)
Pip has an extremely easy to use interface, similar to other well-known package managers like bundler or npm.
Python Version Management
In Ruby, tools like rbenv make it a snap to install and manage which version of Ruby is being used for a project. By simply dropping a file called .ruby-version
containing your desired Ruby version in your project directory, rbenv will automatically update shims to point at the correct Ruby install. Combined with bundler to manage package versions, you have a full language versioning system.
For quite some time, Python has had the ability to isolate the module dependencies for a project using a utility called virtualenv. Virtualenv allows you to source a shell script to activate a particular Python environment, with isolated packages and a specific Python version, which I found pretty awesome. Virtualenv does not, however, provide any facilities for managing installed Pythons.
Thankfully, an enterprising developer forked rbenv to create pyenv, which works very similarly to rbenv. When combined with pyenv-virtualenv, it allows you to automatically activate a Python virtualenv on a per-project basis.
To install pyenv and pyenv-virtualenv with Homebrew on a Mac:
brew install pyenv
brew install pyenv-virtualenv
-
Add the following lines to your .bash_profile to put the pyenv shims in your
$PATH
:if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi if which pyenv-virtualenv-init > /dev/null; then eval "$(pyenv virtualenv-init -)"; fi
- Close and reopen your terminal so the
$PATH
changes propagate
And to set up a fresh Python environment for a new project:
pyenv install 3.4.2
cd /my/project/dir
pyenv virtualenv 3.4.2 my_project_env
- Drop a .python-version containing my_project_env into your current directory
pyenv local my_project_env
Congratulations. Now whenever you cd
into this project directory, pyenv-virtualenv will activate the “my_project_env” virtualenv, and all your package installs will be scoped to the “my_project_env” virtualenv.
This is great. Have you found any useful analogs for
bundler
,rspec
,cane
, orrake
? :-)Thanks, Carl.
In python, the role of bundler is taken by a combination of
pip
andvirtualenv
. For dependency management,pip
conventions are to have a file calledrequirements.txt
, which you can read about here. There’s no messing about withbundle exec
to activate a dependency set, instead you just hop into a dedicatedvirtualenv
for the project.For testing, python has quite a few different libraries available. I’m unsure that there’s a direct equivalent of
rspec
, but the standard library hasunittest
(docs here), which has worked quite well for my small projects. From my limited reading, if I were to start a new project today, I’d probably usenose
(docs here). The python wiki has a larger list of available frameworks here.Several options exist for code coverage, but I usually see
coverage.py
used. Docs here.I haven’t had to use any rake-alikes, though
Invoke
looks absolutely intriguing. Docs here.Good luck on your python adventures. :-)
Thanks, Mitchell!