Virtualenv is an anti-pattern (for beginners)

Every time I do a user test with a beginning programmer, I remember how hard computers are, how unforgiving the tools are, and end up wanting to apologize for how annoying and strict programming is. We are making progress with teaching people how to code, but it's still really hard.

For example, if you are just getting started with Python, here's a short list of problems you might face when trying to set up Flask, which is by far the easiest Python web server to set up.

  • Learning how to cd in the terminal
  • How URL's requested by a user map to actual code
  • HTML, CSS and Javascript, because you actually want it to be pretty.
  • How to read and write things from a database
  • Installing Flask, so learning how to use pip or easy_install
  • Python telling you your file is no good because it mixes tabs and spaces.
  • How to run Flask locally

How to draw an owl: 1. Draw some circles 2. Draw the rest of the fucking owl

And that's not even counting the stuff that's so obvious to us we forget to mention it. Most quickstart guides also fail to help people make incremental progress.

Game designers are great at teaching new, hard things. They have to be, or no one will play their games. You will notice that games don't start with you battling Ganon in an epic death match; they start with you learning how to use the character and perform actions like make a kick, or open a door. Through a series of incremental successes you become an expert in the game and can tackle more and more complex tasks.

It bugs me to see so many Python tutorials mention virtualenv as a requirement to get started. (virtualenv is a tool for sandboxing your Python apps, so each Python project on your computer is using its own set of packages). The biggest advantage of virtualenv is that you can have different versions of the same Python package (like Flask or requests) that are required by different projects, whereas if you install them system-wide you can't.

However, recommending virtualenv just adds another thing you have to do before you can see pretty lights on the screen, and represents another possible opportunity for people to lose interest, and start doing something else instead of learning how to get a web server set up.

It also introduces a significant opportunity for confusion; the "It was working yesterday, why isn't it working now?" problem. You need to remember to source your virtualenv file in every Terminal shell where you're running Python, or your terminal will tell you it can't find the library you literally just installed. Needless to say this is confusing, the Terminal won't tell you how to solve the problem, and Googling for the answer isn't likely to give you the solution you need, because it's such a generic error message.

I've never seen beginners run into the problem of needing conflicting versions of a Python package for two different projects. I was comfortable dumping everything into site-packages for over two years of Python development; only when I started working at Twilio did I need to start installing virtualenvs for every project.

As a community, I believe we should stop recommending that beginners install virtualenv. The faster we can get beginners to a Holy Shit, I Wrote Code That Made Something Happen moment, the better, and virtualenv is a big block for getting to that point. Instead I'd recommend installing pip using the one line curl program in the second paragraph here. virtualenv is something that's more appropriate to learn about and use once you have a few Python projects under your belt.

9 thoughts on “Virtualenv is an anti-pattern (for beginners)

  1. Ian Bicking

    Virtualenv bootstrap scripts are in part intended to address this use case – you can create a single script that creates a virtualenv and runs commands (like installing libraries, creating some scratch directories, etc), all in one batch. I haven’t seen many people use it recently, though it was popular when people didn’t know what virtualenv was.

    It’s also pretty feasible (so long as you only are using pure-Python libraries) to ship an entire directory that you just unzip and use. The tool support for this isn’t great, so there’s a lot of hand-crafting involved, but there is a pull request that adds some useful (but indirect) support for this sort of thing to pip: https://github.com/pypa/pip/pull/519

    Actually installing junk in your system libraries causes a bunch of problems really quickly, so I am really not a big fan of that.

    Reply
    1. Ian Bicking

      I’ll also add that I don’t think it’s terrible to install a couple select binary packages system-wide. For example, if you use lxml in a tutorial, letting the user install lxml any darn way that works is just fine.

      Reply
  2. mani

    When I started to learn python I faced all the issues which you have mentioned. virtualenv was another additional step.
    But if a user has a system which has a different version of python installed in it by default and if the tutorial which he wants to learn from insists that the user use a specific version virtualenv is god sent :)

    But I totally agree with you. It can / should be simpler.

    Reply
  3. dAnjou

    I agree that there is this problem you pointed out at the beginning. But I absolutely do not agree with not recommending virtualenv. It makes it so much easier to program with Python and not messing up your system. It also eases the sometimes painful task of deploying a web application.

    You are right, it is a bit of a hurdle but it is totally worth it!

    Reply
  4. Jamie Curle

    Hi Kevin,

    Asking beginners to jump through hoops by getting them to installing virtualenv can, for some, be a little overwhelming. So if virtualenv is recommended without any proposition or demonstration of why it’s necessary then I’d attribute that to a lack of understanding of the learners context, not an anti-pattern.

    I agree that the sooner someone gets to the “Wow, I made that” moment the better. However, some of the moments you’ve mentioned about confusion and “where’s my package” are all opportunities to learn and and experiment. Just as virtualenv or being able use the terminal are all skills required to become a seasoned developer, so is getting yourself out of a pickle.

    I think the real issue here is a pedagogical one, not a technical one. So whilst I don’t agree that virtualenv is an anti-pattern for beginners, you raise good valid points.

    Reply
  5. petraszd

    For beginners there is one killer virtualenv feature. If You are using virtualenv there is no harm in modifying installed libraries source code. So, You can add pdb or print statements into other’s source code. It is hacky and stupid way, but sometimes it really helps while debugging…

    Of course, I am talking about “new to python” beginners, not “new to programming” ones.

    Reply
  6. Stephen Paulger

    I can see your point that virtualenvs are another thing to learn that makes little sense to a beginner programmer but calling them an anti-pattern is frankly stupid.

    Reply
  7. Jeff Weakley

    As a newbie Python Programmer (about a year and a half), I’ve started to learn Django a couple of times and the Virtualenv difficulty has been a pain in the ass. In fact, I am in the process of trying to learn it again (and determined) which is what led me to this post. I was actually searching for Virtualevn tutorials as it has been a bear to deal with. Though I have accomplished in past attempts. but it took so long, I had to move onto other projects before diving deeper into Django.
    I believe you make an excellent point. At the same time, I can see the need for Virtualenv. Since I’ve started looking at Django it has gone from 1.3 to 1.5.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>