2to3 for 2.7

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun May 27 09:53:30 EDT 2012


On Sat, 26 May 2012 19:37:33 -0700, rurpy at yahoo.com wrote:

> Is there a list of fixers I can tell 2to3 to use that will limit changes
> to things that will continue to run under python-2.7?

So you want a 2to2?

I suggest you read the Fine Manual and choose the fixers you want to 
apply yourself:

http://docs.python.org/library/2to3.html

That, plus a bit of trial-and-error at the interactive prompt, will soon 
tell you what works and what doesn't. But read on for my suggestions.


> I want to start the 2->3 trip by making my code as py3 compatible (under
> py2) as possible before going the rest of the way to py3, and having
> 2to3 help with this seems like a good idea.


Your project, your decision, but it doesn't sound like a good idea to me, 
unless your project is quite small or efficiency is not high on your list 
of priorities. You risk making your 2.7 version significantly slower and 
less efficient than your 2.6 version, but without actually gaining 3.x 
compatibility.

(For what it's worth, I try to aim at 3.x compatibility as the priority, 
and if that means my code is a bit slower under 2.5-2.7, that's a price 
I'm willing to pay.)

The problem is that many of the idioms that work well in Python 3 will be 
less efficient, and therefore slower, in Python 2.7. For example, 
consider this Python 2.x loop, iterating lazily over a dict efficiently:

    for key,value in dict.iteritems(): ...

After applying the dict fixer, that is converted to the Python3-ism:

    for key,value in dict.items(): ...

where it remains lazy and efficient. But you aren't running it under 
Python 3, you are running it under Python 2.7 where it is *eager* rather 
than lazy, and inefficient if the dict is big and you bail out of the 
loop early.

Now, this may not matter if:

- efficiency is not a high priority;

- you're happy to make 2.7 a bit less efficient for the sake of 
  Python 3 compatibility (except you aren't getting Python 3
  compatibility, only *partial* compatibility);

- none of the changes are bottlenecks, so a little inefficiency 
  doesn't matter ("premature optimization is the root of all evil");

- you are prepared to carefully scrutinise the 2to3 diffs and apply 
  only the changes that won't slow your code down;

- you carefully limit yourself to only the few 2to3 changes which 
  are purely syntactic, with no performance or semantic implications.

In which case, it hardly seems worthwhile to me. But your mileage may 
vary.

For what it's worth, I'd try these fixers:

apply
except
exec
execfile
exitfunc
has_key
idioms
ne
next
paren
print
raise
repr
tuple_params
ws_comma
xreadlines

plus "from __future__ import print", and see what breaks :)

Also, don't forget future_builtins:

http://docs.python.org/library/future_builtins.html


Good luck, and if you do go ahead with this, please consider posting an 
update here, or writing a blog post with details of how successful it was.



-- 
Steven



More information about the Python-list mailing list