39
2 × 3 = 6

2 × 3 = 6

Embed Size (px)

DESCRIPTION

A brief overview of six, a module of “utilities for wrapping between Python 2 and 3,” and cross-version compatibility as a whole.

Citation preview

Page 1: 2 × 3 = 6

2 × 3 = 6

Page 2: 2 × 3 = 6

six

• Utilities for wrapping between Python 2 and 3

• Multiplication is more powerful

• “Five” has already been snatched away by the Zope Five project

http://pythonhosted.org/six/

Page 3: 2 × 3 = 6

Use Case: Reflection

Page 4: 2 × 3 = 6

>>> text = 'Lorem ipsum'!>>> isinstance(text, str)!True

Python 2

Page 5: 2 × 3 = 6

>>> text = u'Lorem ipsum'!>>> isinstance(text, str)!False

Python 2

Page 6: 2 × 3 = 6

>>> text = u'Lorem ipsum'!>>> isinstance(text, str)!False!>>> isinstance(text, unicode)!True

Python 2

Page 7: 2 × 3 = 6

>>> text1 = 'Lorem ipsum'!>>> text2 = u'Lorem ipsum'!>>> isinstance(text1, (str, unicode))!True!>>> isinstance(text2, (str, unicode))!True

Python 2

Page 8: 2 × 3 = 6

>>> text1 = 'Lorem ipsum'!>>> text2 = u'Lorem ipsum'!>>> isinstance(text1, basestring)!True!>>> isinstance(text2, basestring)!True

Python 2

Page 9: 2 × 3 = 6

>>> text = 'Lorem ipsum' # "Unicode"!>>> isinstance(text, str)!True

Python 3

Page 10: 2 × 3 = 6

>>> text = u'Lorem ipsum' !! # Python 3.3+!>>> isinstance(text, unicode)!Traceback (most recent call last):! File "<stdin>", line 2, in <module>!NameError: name 'unicode' is not defined

Python 3

Page 11: 2 × 3 = 6

>>> text = 'Lorem ipsum'!>>> isinstance(text, basestring)!Traceback (most recent call last):! File "<stdin>", line 2, in <module>!NameError: name 'basestring' is not defined

Python 3

Page 12: 2 × 3 = 6

>>> import six!>>> text = 'Lorem ipsum'!>>> isinstance(text, six.string_types)!True!>>> text = u'Lorem ipsum' # Python 3.3+!>>> isinstance(text, six.string_types)!True

six

Page 13: 2 × 3 = 6

six Python 2 Python 3

class_types type, types.ClassType type

integer_types long, int int

string_types basestring str

text_type unicode str

binary_type str, bytes (2.7) bytes

MAXSIZE sys.maxsize (2.6+) sys.maxsize

Page 14: 2 × 3 = 6

Use Case: Syntax Compatibility

Page 15: 2 × 3 = 6

>>> lv = {}!>>> exec 'x = 3, y = 4' in {}, lv!>>> with open('foo.txt', 'w') as f:!... print >>f lv['x'], lv['y']!...!>>>

Python 2

Page 16: 2 × 3 = 6

Python 3

>>> lv = {}!>>> exec('x = 3, y = 4', {}, lv)!>>> with open('foo.txt', 'w') as f:!... print(lv['x'], lv['y'], file=f)!...!>>>

Page 17: 2 × 3 = 6

six

>>> from six import exec_, print_!>>> lv = {}!>>> exec_('x = 3, y = 4', {}, lv)!>>> with open('foo.txt', 'w') as f:!... print_(lv['x'], lv['y'], file=f)!...!>>>

Page 18: 2 × 3 = 6

class MetaFoo(type):! pass!!

class Foo(object):! __metaclass__ = MetaFoo

Python 2

Page 19: 2 × 3 = 6

class MetaFoo(type):! pass!!

class Foo(object, metaclass=MetaFoo):! pass

Python 3

Page 20: 2 × 3 = 6

from six import add_metaclass!!

class MetaFoo(type):! pass!!

@add_metaclass(MetaFoo)!class Foo(object):! pass

six

Page 21: 2 × 3 = 6

from six import with_metaclass!!

class MetaFoo(type):! pass!!

class Foo(with_metaclass(object, MetaFoo)):! pass

six

Page 22: 2 × 3 = 6

six Python 2 Python 3

exec_ exec (statement) exec (function)

print_ print (statement) print (function)

reraise exception re-raising (can contain previous tracebacks)

with_metaclass metaclassing (creates an intermediate class)

add_metaclass metaclassing (no intermediate class)

Page 23: 2 × 3 = 6

Use Case: Texts

Page 24: 2 × 3 = 6

a_byte_string = 'Lorem ipsum'!

still_bytestr = b'Lorem ipsum' # 2.7!

a_unicode_obj = u'Lorem ipsum'

Python 2

Page 25: 2 × 3 = 6

a_unicode_obj = 'Lorem ipsum'!

still_unicode = u'Lorem ipsum' # 3.3+ !

a_byte_string = b'Lorem ipsum'

Python 3

Page 26: 2 × 3 = 6

from six import b, u!

a_byte_string = b('Lorem ipsum')!

a_unicode_obj = u('Lorem ipsum')

six

Page 27: 2 × 3 = 6

a_unicode_obj = u('Lorem ipsum')

six

Be careful with this on Python 2!

Page 28: 2 × 3 = 6

six Python 2 Python 3

b str, bytes (2.7) bytes

uunicode

(allows escaping)str

unichr unichr chr

int2byte chr bytes([integer])

byte2int ord(bytestr[0]) bytestr[0]

Page 29: 2 × 3 = 6

six Python 2 Python 3

indexbytes(buf, i) ord(buf[i]) buf[i]

iterbytes(buf) an iterator for a bytes instance buf

StringIO StringIO.StringIO io.StringIO

BytesIO StringIO.StringIO io.BytesIO

Page 30: 2 × 3 = 6

Use Case: Name Changes

Page 31: 2 × 3 = 6

from itertools import izip!

!

u = raw_input()!

!

for i, v in izip(xrange(len(u)), u):!

print i, v

Python 2

Page 32: 2 × 3 = 6

u = input()!

!

for i, v in zip(range(len(u)), u):!

print i, v

Python 3

Page 33: 2 × 3 = 6

from six.moves import input, zip, range!

!

u = input()!

!

for i, v in zip(range(len(u)), u):!

print i, v

six

Page 34: 2 × 3 = 6

from six.moves import ConfigParser!

!

# This will fail on Python 3!!

parser = ConfigParser.SafeConfigParser()

Caveats

Page 35: 2 × 3 = 6

Read the Doc(Too many to list)

http://pythonhosted.org/six/#module-six.moves

Page 36: 2 × 3 = 6

Advanced Usage

• Customised renames

• Object model compatibility

• six.PY2 and six.PY3 (when all others fail)

Page 37: 2 × 3 = 6

In the Meantime

• pies

• Supports 2.6+ only (six supports 2.4+)

• Lightweight

• python-future

• Based on six

• Let you write in pure Python 3

Page 38: 2 × 3 = 6

Related Readinghttp://pythonhosted.org/six/

http://python3porting.com/differences.html

http://docs.python.org/3/library/

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

http://python-future.org

https://github.com/timothycrosley/pies

Page 39: 2 × 3 = 6