2to3 for 2.7

R

rurpy

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?

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.
 
S

Steven D'Aprano

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.
 
R

rurpy

Yes. :)

That, and the 2.6 and 2.7 What's New's and the docs for
the 3.x backported features mentioned therein... I've
started to do just that but if someone else has already
distilled all this information...

I can't really migrate my project until wxPython does.
But I've read a number of conversion experiences
ranging from "ran 2to3 and everything was golden" to
needing to make some serious design decisions (usually
in the bytes/str area) to months of effort to get all
the little glitches wrung out. So I have no idea what
is in store for me. By doing some of the conversion
now I can hopefully get a better sense of what is in
store and get some of the work done earlier rather
than later. There is also the generally useful
heuristic of dividing a larger task into two smaller
independent tasks...

And finally, there is the question about maintaining
2/3 compatibility in a single codebase. I don't have
a hard requirement for this but if it is doable without
too much effort, I would prefer to do so. ISTM that
looking at what remains left to do after the 2.7 code
has been 3-ifided as much as possible will allow me to
make a better judgment about that.

I did not spend much time optimizing for performance
when writing the code, so it probably doesn't make
sense to worry about it now, unless a really large
performance difference is likely (which seems to me
unlikely given that I don't have any really large
in-memory data). Thanks for the tip though; it is
something I'll remain alert for.
[...]
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.

Thanks for that list. Sans anything more definitive
it is a good starting point.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top