Dear all, as of today, Firedrake now only supports Python 3. In particular, we require Python >= 3.5 Rationale ========= The Python development team have formally end-of-lifed Python 2. Python 2.7 will be the last ever Python in the 2 series (see https://www.python.org/dev/peps/pep-0373/#update). Similarly, many large Python packages have stopped new feature releases compatible with Python 2. For example, the most recent IPython releases are Python 3 only. The Scientific Python community is also commited to dropping support for Python 2 by 2020. See http://www.python3statement.org/ for details. What does this mean for you? ============================ Upgrading existing installations -------------------------------- For technical reasons to do with how we package a firedrake installation, upgrading an existing (Python 2) install is *not possible*. You will instead have to reinstall from scratch. Should you attempt to update your old install, you will get an error message informing you to reinstall. Fresh installations ------------------- The installation procedure is as before (but remember to download a new copy of the firedrake-install script). See http://firedrakeproject.org/download.html for details. Porting your code to Python 3 ----------------------------- Most Python code that you have been writing will be compatible with Python 3 already, especially if you have been writing: from __future__ import division, print_function, absolute_import at the top of your Python files. To find out what to do in detail, we recommend the advice on http://python-future.org/, in particular, their cheat sheet: http://python-future.org/compatible_idioms.html You of course do not need to write compatible code, but you can use this to see how to convert your Python 2isms to Python 3. The most common gotchas are: . print is no longer a statement, but a function. You cannot write: print "foo" But instead should write: print("foo") This is enforced in Python 2 with "from __future__ import print_function" . division of integers returns a floating point number. In Python 2: 1 / 2 => 0 In Python 3: 1 / 2 => 0.5 If you actually want integer division, write: 1 // 2 => 0 This is enforced in Python 2 with "from __future__ import division" . Iteration constructs now return generators, not lists In Python 2, calls like dict.keys(), or range, return a list (i.e. they are eager). In Python 3, they return a generator that may be iterated over (i.e. they are lazy). You must explicitly convert them to a list if you want that. As ever, if you have any problems installing or updating, please do get in touch with bug reports. Cheers, Lawrence (& the rest of the Firedrake team)