python 3 compatibility (pycon 2009)

Post on 03-Sep-2014

5.330 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

This talks takes a look at the various options of migrating to Python 3, and takes up examples of some tricks you can do to make you code run unmodified under both 2.6 and 3.0. Video at http://pycon.blip.tv/file/1949281/

TRANSCRIPT

Python 2.6 and 3.0 Compatibility

Lennart Regebrohttp://regebro.wordpress.com/

regebro@gmail.comPyCon 2009, Chicago

Python 3.0 is here!

Python 3 is incompatible

Python 3 is incompatible

O RLY?

Python 3 is incompatible Ya, really!

O RLY?

Strategies to deal with incompatibility

For applications:Just port to Python 3

2to3 helps you port

Tests are really helpful

Libraries need to support both Python 2 and Python 3

For most libraries:Develop in Python 2 and run 2to3

for Python 3 support

2to3 supported development has a significant startup cost

For stable libraries:Just port to Python 3

Platform Extensions/Plugins/etc.

No Plone user will switch to Python 3 until important extensions are available

Nobody will make the extensions support Python 3 until they

themselves move to Python 3

Dead lock

The Zope experience

Zope 3: A complete break

Zope 3.1 etc: No break

Wanted: Gradual upgrade path

First support 2.5 and 2.6, then support 2.6 and 3.0,

finally dropping 2.x completely

Python 3 is incompatible

Oh, right, I forgot already.

Python 2.6 introduces quite a lot of forward compatibility!

Python 2.5:except Exception, e:

Python 3.0:except Exception as e:

Python 2.6:

Both works!

Python 2.5:3/2 == 1

Python 3.0:3/2 == 1.5

Solutions:

3//2 == 1

from __future__ import division

3/2 == 1.5

Python2.5:print >> file, “bla”, “bla”, “bla”,

Python3.0:print(“bla”, “bla”, “bla”,

file=file, ending='')

Python 2.6:from __future__ import

print_function

Python2.5:u”Üniçodê”

Python3.0:“Üniçodê”

Python 2.6:from __future__ import

unicode_literals

from __future__ import \ unicode_literalstry: str = unicodeexcept NameError: pass

isinstance(type(“Üniçodê”), str)

Python2.5:

open('filename', 'r').read()'A string\n'

open('filename', 'rb').read()'A string\n'

Python3.0:

open('filename', 'r').read()'A string\n'

open('filename', 'rb').read()b'A string\n'

Python 2.6:b“A string”[5] == “i”

Python 3.0:b“A string”[5] == 105

Solutions for 2.6 and 3.0:

bytearray(b”A list of bytes”)bytearray(open(file, “rb”).read())

Python 2.6:>>> bytes(a_byte_array)'Binary data'

Python 3.0:>>> bytes(a_byte_array)b'Binary data'

Python2.5:open(“unicodefile”).read()

'\xc3\x9cni\xc3\xa7od\xc3\xaa\n'

Python3.0:'Üniçodê\n'

Solution for 2.6 and 3.0:

infile =open(“unicodefile”, “rb”)uni = infile.read().decode(enc)

try: from cStringIO import StringIOexcept ImportError: from io import StringIO

Python2.5:dict.items()/dict.keys()/dict.values()

return lists

Python3.0:dict.items()/dict.keys()/dict.values()

return views

Python 2.5:foo = bar.keys()foo.sort()

Python 2.4 - 3.0:foo = sorted(bar.keys())

Removed:dict.iteritems()dict.itervalues()dict.iterkeys()

Python 2.6 solution:

try: iter = d.iteritems() except AttributeError: iter = d.items()

Aaaahhhhh........

Now meta classes make sense

infile = open('something', 'rb')bdata = infile.read()

python2.6:pass

python 3.0:sdata = bdata.decode()

Python 2.x and 3.0:sdata = str(bdata.decode('ascii'))

Running on both 2.x and 3.0 will mean some ugly hacks no matter

if you use 2to3 or not

Using 2to3:

Easy to support 2.3, 2.4, 2.5Few contortionsSome setup cost

Single branch of code

Separate branches:

Easy to support 2.3, 2.4, 2.5No contortionsNo setup cost

You have to fix all bugs twice

2.6 and 3.0 support without 2to3:

More contortionsLow setup cost

Single branch of codeBut, no support for < 2.6

Supporting Python 2.5 or lower and 3.0 without 2to3:

Contortion fest!High hack valueLot's of work

So what if you decide to go for 2.6 and 3.0 without 2.6?

1. 2to32. Make it run under 3.03. Backport to Python 2.6

2.6 compatible 2to3?

Preparing yourself for 3.0

Already in 2.6:

String exceptions are gone

“as” and “with” are keywords

Python 2.3:alist.sort(cmp=func)

Python 2.4 and later:alist = sorted(alist, key=func)

Use // when you want integer division.

Usefrom __future__ import division

already now

Mark binary files with “rb” or “wb”

http://code.google.com/p/python-incompatibility

regebro@gmail.com

top related