Migration Strategies From Python 2 to Python 3
Now that you know how tests can help you migrating your Python code to another version, it’s time to migrate your code to Python 3.
Therefore, different migration strategies are discussed during this lesson and the 2to3
tool is introduced.
00:00 So, by the power of movie magic we are back. Our tests have run and we have now Python 2.7 as all green, which is great! But the problem is that Python 3.2 is still broken.
00:15 So we’re going to go over a few migration strategies for going from Python 2 to Python 3. One strategy you can take is only support Python 3.
00:27 Hopefully, this will happen relatively soon, but a lot of applications are written in Python 2 and there’s not a lot of force to make everybody switch to Python 3, but I believe that’s starting to change now with a lot of the new functionality in Python 3. But for the most part, that isn’t an option that most people can have.
00:46
Another option you can do is support Python 2 and Python 3 distributions via the 2to3
package, which is a package that helps you convert Python 2 code to Python 3 at install time.
00:59 So you can use this distribution with Setuptools and Distribute to convert or take your Python 2 code and, on install, on to a version of Python that is above Python 2.7, it will convert all the code to Python 3 on the fly.
01:17 So you just commit all your changes to a Python 2 version, convert it locally, make sure you run tests so that you make sure that it actually works in Python 3 and above, and it’ll do the conversion on the fly on the host computer.
01:32 Or, and this is the option that I prefer if possible, to rewrite your Python 2 code so that it can both run in Python 2 and Python 3. Now, if you go back past Python 2.6 where it doesn’t have a lot of the intermediary steps, for example, in Python 2.5,
01:53
you can’t do print()
like this. It just won’t work, it isn’t aware, all the backports were only done up until 2.6. Now, if you’re working from 2.6 and up, then this is much easier.
02:05 You’ll have an easier time switching from 2.6 to Python 3 and it’ll be easy to
02:13
do the switch over and have one codebase which is compatible with two. Now, there’s a lot of libraries that also help with that. There’s one called six
, which will come in very handy when doing this.
02:24 So, what I first suggest everybody does is take their Python 2 library… Hopefully, you’ll have some tests so that you know when you change stuff it won’t actually break.
02:33
So your first step, actually, is to write tests for whatever library you’re converting, just to make sure nothing breaks. Then what you do is you run them in 2to3
.
02:45
2to3
is available in, I believe, up until in the standard library from 2.5 and up. And what it does, it lets you run a conversion on your Python 3 code.
02:58
So, what we’d do here is… So, we have delorean
, it’s right here, it’s in this package. This is where all our source code is. What you do, simply, is go 2to3 -l
, and that’ll list out all the changes that it’s supposed to do.
03:11
And then we’ll run that against the delorean
library. So as you can see, it spit out all the fixers that I was running against it and then spit out all the changes that it would need to do. Luckily, this library isn’t too bad and we can make a lot of these changes really quick.
03:26
A fixer is what converts something like this. Let’s just quickly take a look. So, remember, like we said before, you have… print 5
can do this.
03:36
What a fixer would do is simply take the Python 2 version of your print
statement and convert it inline with a Python 3 compatible version.
03:51
Python’s 2to3
does. You can even have it so that it will write to the actual file and create backups so you can convert back to this. Or you could even have it just completely run against your whole entire codebase and spit out a new one and you can run the tests that way to make sure everything works.
04:07
So, we ran it and we saw that there were two changes that we need to make. We need to make that print
statement here—which albeit is superfluous, but I’d like to keep it in the codebase—is to simply wrap it in brackets, which takes the statement and makes it a function, as well as the unicode()
method that we have here, which… This function no longer exists in Python 3.
04:29
The equivalent is to wrap it in a str()
(string) call. So, let’s quickly just do that. So one’s in exceptions.py
and one is in interface.py
.
04:38
Let’s first do the exceptions one. The call no longer exists, so let’s just make it a string. Save that. And then we go to the interface.py
. We want to go to
04:52
print
. There’s only one print
here. And simply wrap that in a function call.
04:59 And that, for the most part, should be all we need to do to convert this particular library to Python 3.
05:06
Let’s make sure it still functions under Python 2.7, make test
. Awesome, everything still works. So, we’re going to push this code up and have it run against Python 2 and 3, and then we’ll come back and we’ll discuss what was the result.
Become a Member to join the conversation.