2016-06-22
I need to cultivate some new coding habits for Python 3 ready code
We have a Django application, and because of various aspects of Django (such as Django handling much of the heavy lifting), I expect that it's our most Python 3 ready chunk of code. Since I was working on it today anyways, I took a brief run at seeing if it would at least print help messages if I ran it under Python 3. As it turns out, making the attempt shows me that I need to cultivate some new coding habits in order to routinely write code that will be ready for Python 3.
What I stumbled over today is that I still like to write except
clauses in the old way:
try: .... except SomeErr, err: ....
The new way to write except
clauses is the less ambiguous 'except
SomeErr as err:
'. Python 3 only supports the new style.
Despite writing at least some of the code in our Django application
relatively recently, I still wrote it using the old style for
except
. Of course this means I need to change it all. I'm pretty
certain that writing except
clauses this way is not something
that I think about; it's just a habit of how I write Python, developed
from years of writing Python before 'except CLS as ERR
' existed
or at least was usable by me.
What I take away from this is that I'm going to need to make new
Python coding habits, or more exactly go through the more difficult
exercise of overwriting old habits with new ones. I'm sure to be
irrationally annoyed at some of the necessary changes, especially
turning 'print
' statements into function calls.
(If I was serious about this, what I should do is force myself to write only in Python 3 for a while. Unfortunately that's not very likely.)
The good news is that I checked some code I wrote recently, and I
seem to have deliberately used the new style except
clauses in
it. Now if I can remember to keep doing that, I might be in okay
shape.
(Having thought about it, what would be handy is a Python linter that complains about such unnecessary Python 3 incompatibilities. Then I'd at least have a chance of catching my issues here right away.)
PS: Modernizing an old code base is a related issue, of course. I need to modernize both code and habits to be ready for Python 3 in both current and future code.
Sidebar: The timing and rationality of using old-style except
New style except
was introduced in Python 2.6, which dates back
to 2008. However, the new version of Python didn't propagate into
things like Linux distributions immediately; it took two years to
get it into an Ubuntu LTS release, for example (in 10.04). Looking
back at various records, it seems that the initial version of our
Django application was deployed on an
Ubuntu 8.04 machine that would have had only Python 2.5. In fact I may have written the first version
of all of the substantial code in the application while we were
still using 8.04 as the host machine and so new-style except
would
have been unavailable to us.
This is of course no longer the case. Although not everything we
run today has Python 2.7 available (cf),
it all has at least Python 2.6. So I should be writing all my code
with new style except
clauses and probably some other modernizations.
Moving from Python 2 to Python 3 calls for a code inventory
I was all set to write a blog entry breaking down what sort of Python code we had, how much it was exposed to security issues and other threats, and how much work it would probably be to migrate it to or towards Python 3. I even thought it was going to be a relatively short and simple entry. Then, as I was writing things down, I kept remembering more and more bits of Python code we're using in different contexts, and I'm pretty sure I'm still forgetting some.
So, here's my broad moral for today: if you have Python code, and you're either thinking of migrating at least some of it to Python 3 or considering whether you can ignore the alleged risks of continuing to use Python 2, your first step is (or should be) to get a code inventory. Expect this to probably take a while; you don't want just the big obvious applications, you also care about the little things in the corners.
Perhaps we're unusual, but we don't have our Python code in one or more big applications, where it's easy and obvious to look at things. Instead, we have all sorts of things written in Python, everything from a modest Django application through system management subsystems to little command line things (and not so little ones). These have accumulated over what is almost a decade by now, and if they work quietly we basically forget about them (and most of them do). It's clearly going to take me some work to find them all, categorize them, and probably in some cases discover that they're now unnecessary.
Having written this, I don't know if I'm actually going to do such an inventory any time soon. The problem is that the work is a boring slog and the issue is not particularly urgent, even if we accept a '2020 or earlier' deadline on Python 2 support. Worse, if I do an inventory now and then do nothing with it, it's probably going to get out of date (wasting the work). I'd still like to know, though, if only for my own peace of mind.