top | item 22127235

How to Port from Python 2 to Python 3 (2019)

54 points| noego | 6 years ago |stxnext.com

48 comments

order

ryandvm|6 years ago

Python 3 and IPv6 are the poster-children of how _not_ to do a major upgrade. I'm not sure what the right way is, but if the short-term advantages of the upgrade do not outweigh the immediate pain, prepare for the matter to drag out for _decades_.

badsectoracula|6 years ago

> I'm not sure what the right way is

The right way is to make sure that stuff that used to work in the previous version still works in the current version. Breaking people's work, especially work that spans multiple years, projects, knowledge, etc and expecting them to be happy about it is naive. Being condescending when they turn out to not be happy and try to avoid the unnecessary busywork forced on them does not help either.

This isn't just about Python, many libraries and languages (and some OSes - see iOS, macOS and to a slightly less extent Android) are terrible about this. The proliferation of semver with its normalization of breaking stuff (the fact that a dependency - be it a library or language or whatever - uses semver communicates that they have already decided that they will break backwards compatibility at some point) shows that most people are fine with breaking others' code.

cletus|6 years ago

IPv6 is a perfect example of the second-system effect [1] as in it added a bunch of things no one needed (but might need someday) and didn't solve roaming. All IPv4 really needed was a bigger address space.

But as soon as you cross the mental threshold of making a breaking change (which expanding the IPv4 address space obviously was) then it's easier to convince yourself to make a bunch more breaking changes. And this is where Python3 really lost its way (IMHO).

One of the silliest design decisions in Python3 was (initially) removing the string prefixes like s and u. Now obviously Python2 defaulted to ASCII and Python3 defaulted to Unicode but this decision just made making libraries compatible with both, so much so that they added it back (around 3.2-3.3 IIRC).

There are also always decisions you make that in hindsight you wish you'd done differently (eg the mutable Date class in Java) but just because you're making breaking changes doesn't mean you should "fix" all of those. You still have to look at each one and ask yourself "does this really matter enough to justify changing it now?". The default answer is "no" and the bar for "yes" should be really high.

I feel like Python3 failed here too.

And look where we are. Python3 out in 2008 and we're still writing migration guides in 2019.

[1]: https://en.wikipedia.org/wiki/Second-system_effect

segmondy|6 years ago

Upgrades are just hard.

See perl5 to perl6 GWbasic to Qbasic to VB to VB.net

you either make a clean break or keep all the warts, Either way folks are going to be unhappy.

Keep the warts, COBOL, Fortran, C, C++, PHP, Excel

rb808|6 years ago

At least Python3 brings an improvement. I still can't think of a good reason I should spend any time trying to figure out IPv6. Maybe my external router has to think about it, but that is about it.

Edit: If you down vote me please say why I should care about IPv6

LoreleiPenn|6 years ago

Hopefully no more people will keep saying "learn Python 2 because 3 has almost no packages".

It is so easy for people to just repeat what they heard even if that idea originated a decade ago and was valid a decade ago.

And that way we got into a mess of not migrating until pass the time it is no longer supported...

zdw|6 years ago

I've been doing a lot of Python 2 -> 3 lately, and found this to be one of the best actionable guides: https://portingguide.readthedocs.io/en/latest

Also, using tox on the project to run tests against both python 2.7 and multiple versions of 3 and the work goes pretty quickly.

mixmastamyk|6 years ago

Looks like a lot of the guide assumes you want to run on Py2 and 3 concurrently. The time for that has passed to be honest. A clean port is easier to do.

pjc50|6 years ago

We built a product with an embedded Jython interpreter. Jython is stuck on Python2 and somewhat abandoned. So that's nice.

Re: packages, one of the huge advantages of the C ecosystem has been that compiled packages are usually fine across language transitions, not only between major compiler version numbers but even from C to C++ which are much more different languages than Python2 to 3. How different would the Python transition have been if it were possible to load Python2 packages in a Python3 program?

o_x|6 years ago

Isn't it ironic that Sentry is one of the tools mentioned in py2->py3 migration? (Sentry is on py2 and as far as I remember they were not very optimistic about migrating)

zojirushibottle|6 years ago

that's correct. sentry itself is on python 2.7, not the python client.

not to pick on sentry here, but you know, my experience is that people are having a hard time migrating due to them using obscure tricks and features of python 2.7. so their code is breaking because the language evolved.

the saying goes write dumb code or something because debugging is twice as hard. if there is anything to learn from all this, it's to write dumb code because maintenance is twice as hard too.

that's all that is happening really!

zitterbewegung|6 years ago

The big issue of ports like these is not the tutorial but to justify that to your boss.

From enterprise to a self run startup you have to see if it’s worth it .

BeetleB|6 years ago

> The big issue of ports like these is not the tutorial but to justify that to your boss.

I think that's a red herring. Convincing your boss is an issue even for minor upgrades. In a previous job, we couldn't convince him to move from Python 2.5 to 2.7.

swalsh|6 years ago

I literally just got on a phone call to discuss our migration away from 2.7, very timely post.

classified|6 years ago

IIRC, the Python used in the macOS vim(1) is still 2.x. So at least on a Mac it won't be possible to just move on to Py3 and forget / uninstall Py2 for the foreseeable future.

cinnamonheart|6 years ago

I think you can just do

    brew install vim -- --with-override-system-vi --with-python3
To get a vim with python 3 on mac os. You are correct that it defaults to python 2, though.

mixmastamyk|6 years ago

Porting is a non-event for most non-large projects. In short:

- First cut a new major version

- Write a few tests if needed, they go a long way here.

- Update to 2.7 best practices and logging

- Run tests, commit

- Add a few future statements, commit

- Run pyflakes3 on it, fix, commit

- Run under 3.x/fix until clean, commit

However, if your project is huge and/or does a lot of string and bit twiddling it's excruciating. Hence the controversy between factions.

grifball|6 years ago

sed -i 's/print \("[^"]*"\)/print(\1)'