Six - Python 2 and 3 Compatibility Library

Six: Python 2 and 3 Compatibility Library

Six provides simple utilities for wrapping over differences between Python 2 and Python 3. It is intended to support codebases that work on both Python 2 and 3 without modification. six consists of only one Python file, so it is painless to copy into a project.

Six can be downloaded on PyPi. Its bug tracker and code hosting is on BitBucket.

The name, "six", comes from the fact that 2*3 equals 6. Why not addition? Multiplication is more powerful, and, anyway, "five" has already been snatched away by the (admittedly now moribund) Zope Five project.

Indices and tables

genindex

search

Package contents

Constants

Six provides constants that may differ between Python versions. Ones ending _types are mostly useful as the second argument to isinstance or issubclass.

Object model compatibility

Python 3 renamed the attributes of several intepreter data structures. The following accessors are available. Note that the recommended way to inspect functions and methods is the stdlib py3:inspect module.

A class for making portable iterators. The intention is that it be subclassed and subclasses provide a __next__ method. In Python 2, Iterator has one method: next. It simply delegates to __next__. An alternate way to do this would be to simply alias next to __next__. However, this interacts badly with subclasses that override __next__. Iterator is empty on Python 3. (In fact, it is just aliased to py3:object.)

Syntax compatibility

These functions smooth over operations which have different syntaxes between Python 2 and 3.

Binary and text data

Python 3 enforces the distinction between byte strings and text strings far more rigoriously than Python 2 does; binary data cannot be automatically coerced to or from text data. six provides several functions to assist in classifying string data in all Python versions.

unittest assertions

Six contains compatibility shims for unittest assertions that have been renamed. The parameters are the same as their aliases, but you must pass the test method as the first argument. For example:

Renamed modules and attributes compatibility

Python 3 reorganized the standard library and moved several functions to different modules. Six provides a consistent interface to them through the fake six.moves module. For example, to load the module for parsing HTML on Python 2 or 3, write:

from six.moves import html_parser

Similarly, to get the function to reload modules, which was moved from the builtin module to the imp module, use:

from six.moves import reload_module

For the most part, six.moves aliases are the names of the modules in Python 3. When the new Python 3 name is a package, the components of the name are separated by underscores. For example, html.parser becomes html_parser. In some cases where several modules have been combined, the Python 2 name is retained. This is so the appropiate modules can be found when running on Python 2. For example, BaseHTTPServer which is in http.server in Python 3 is aliased as BaseHTTPServer.

Some modules which had two implementations have been merged in Python 3. For example, cPickle no longer exists in Python 3; it was merged with pickle. In these cases, fetching the fast version will load the fast one on Python 2 and the merged module in Python 3.

The py2:urllib, py2:urllib2, and py2:urlparse modules have been combined in the py3:urllib package in Python 3. The six.moves.urllib package is a version-independent location for this functionality; its structure mimics the structure of the Python 3 py3:urllib package.

In order to make imports of the form:

from six.moves.cPickle import loads

work, six places special proxy objects in in py3:sys.modules. These proxies lazily load the underlying module when an attribute is fetched. This will fail if the underlying module is not available in the Python interpreter. For example, sys.modules["six.moves.winreg"].LoadKey would fail on any non-Windows platform. Unfortunately, some applications try to load attributes on every module in py3:sys.modules. six mitigates this problem for some applications by pretending attributes on unimportable modules don't exist. This hack doesn't work in every case, though. If you are encountering problems with the lazy modules and don't use any from imports directly from six.moves modules, you can workaround the issue by removing the six proxy modules:

d = [name for name in sys.modules if name.startswith("six.moves.")]
for name in d:
del sys.modules[name]

Supported renames:

Name

Python 2 name

Python 3 name

builtins

py2:__builtin__

py3:builtins

configparser

py2:ConfigParser

py3:configparser

copyreg

py2:copy_reg

py3:copyreg

cPickle

py2:cPickle

py3:pickle

cStringIO

py2:cStringIO.StringIO

py3:io.StringIO

dbm_gnu

py2:gdbm

py3:dbm.gnu

_dummy_thread

py2:dummy_thread

py3:_dummy_thread

email_mime_multipart

py2:email.MIMEMultipart

py3:email.mime.multipart

email_mime_nonmultipart

py2:email.MIMENonMultipart

py3:email.mime.nonmultipart

email_mime_text

py2:email.MIMEText

py3:email.mime.text

email_mime_base

py2:email.MIMEBase

py3:email.mime.base

filter

py2:itertools.ifilter

py3:filter

filterfalse

py2:itertools.ifilterfalse

py3:itertools.filterfalse

getcwd

py2:os.getcwdu

py3:os.getcwd

getcwdb

py2:os.getcwd

py3:os.getcwdb

http_cookiejar

py2:cookielib

py3:http.cookiejar

http_cookies

py2:Cookie

py3:http.cookies

html_entities

py2:htmlentitydefs

py3:html.entities

html_parser

py2:HTMLParser

py3:html.parser

http_client

py2:httplib

py3:http.client

BaseHTTPServer

py2:BaseHTTPServer

py3:http.server

CGIHTTPServer

py2:CGIHTTPServer

py3:http.server

SimpleHTTPServer

py2:SimpleHTTPServer

py3:http.server

input

py2:raw_input

py3:input

intern

py2:intern

py3:sys.intern

map

py2:itertools.imap

py3:map

queue

py2:Queue

py3:queue

range

py2:xrange

py3:range

reduce

py2:reduce

py3:functools.reduce

reload_module

py2:reload

py3:imp.reload, py3:importlib.reload on Python 3.4+

reprlib

py2:repr

py3:reprlib

shlex_quote

py2:pipes.quote

py3:shlex.quote

socketserver

py2:SocketServer

py3:socketserver

_thread

py2:thread

py3:_thread

tkinter

py2:Tkinter

py3:tkinter

tkinter_dialog

py2:Dialog

py3:tkinter.dialog

tkinter_filedialog

py2:FileDialog

py3:tkinter.FileDialog

tkinter_scrolledtext

py2:ScrolledText

py3:tkinter.scrolledtext

tkinter_simpledialog

py2:SimpleDialog

py3:tkinter.simpledialog

tkinter_ttk

py2:ttk

py3:tkinter.ttk

tkinter_tix

py2:Tix

py3:tkinter.tix

tkinter_constants

py2:Tkconstants

py3:tkinter.constants

tkinter_dnd

py2:Tkdnd

py3:tkinter.dnd

tkinter_colorchooser

py2:tkColorChooser

py3:tkinter.colorchooser

tkinter_commondialog

py2:tkCommonDialog

py3:tkinter.commondialog

tkinter_tkfiledialog

py2:tkFileDialog

py3:tkinter.filedialog

tkinter_font

py2:tkFont

py3:tkinter.font

tkinter_messagebox

py2:tkMessageBox

py3:tkinter.messagebox

tkinter_tksimpledialog

py2:tkSimpleDialog

py3:tkinter.simpledialog

urllib.parse

See six.moves.urllib.parse

py3:urllib.parse

urllib.error

See six.moves.urllib.error

py3:urllib.error

urllib.request

See six.moves.urllib.request

py3:urllib.request

urllib.response

See six.moves.urllib.response

py3:urllib.response

urllib.robotparser

py2:robotparser

py3:urllib.robotparser

urllib_robotparser

py2:robotparser

py3:urllib.robotparser

UserDict

py2:UserDict.UserDict

py3:collections.UserDict

UserList

py2:UserList.UserList

py3:collections.UserList

UserString

py2:UserString.UserString

py3:collections.UserString

winreg

py2:_winreg

py3:winreg

xmlrpc_client

py2:xmlrpclib

py3:xmlrpc.client

xmlrpc_server

py2:SimpleXMLRPCServer

py3:xmlrpc.server

xrange

py2:xrange

py3:range

zip

py2:itertools.izip

py3:zip

zip_longest

py2:itertools.izip_longest

py3:itertools.zip_longest

urllib parse

Contains functions from Python 3's py3:urllib.parse and Python 2's:

py2:urlparse:

py2:urlparse.ParseResult

py2:urlparse.SplitResult

py2:urlparse.urlparse

py2:urlparse.urlunparse

py2:urlparse.parse_qs

py2:urlparse.parse_qsl

py2:urlparse.urljoin

py2:urlparse.urldefrag

py2:urlparse.urlsplit

py2:urlparse.urlunsplit

py2:urlparse.splitquery

py2:urlparse.uses_fragment

py2:urlparse.uses_netloc

py2:urlparse.uses_params

py2:urlparse.uses_query

py2:urlparse.uses_relative

and py2:urllib:

py2:urllib.quote

py2:urllib.quote_plus

py2:urllib.splittag

py2:urllib.splituser

py2:urllib.unquote

py2:urllib.unquote_plus

py2:urllib.urlencode

urllib error

Contains exceptions from Python 3's py3:urllib.error and Python 2's:

py2:urllib:

py2:urllib.ContentTooShortError

and py2:urllib2:

py2:urllib2.URLError

py2:urllib2.HTTPError

urllib request

Contains items from Python 3's py3:urllib.request and Python 2's:

py2:urllib:

py2:urllib.pathname2url

py2:urllib.url2pathname

py2:urllib.getproxies

py2:urllib.urlretrieve

py2:urllib.urlcleanup

py2:urllib.URLopener

py2:urllib.FancyURLopener

py2:urllib.proxy_bypass

and py2:urllib2:

py2:urllib2.urlopen

py2:urllib2.install_opener

py2:urllib2.build_opener

py2:urllib2.Request

py2:urllib2.OpenerDirector

py2:urllib2.HTTPDefaultErrorHandler

py2:urllib2.HTTPRedirectHandler

py2:urllib2.HTTPCookieProcessor

py2:urllib2.ProxyHandler

py2:urllib2.BaseHandler

py2:urllib2.HTTPPasswordMgr

py2:urllib2.HTTPPasswordMgrWithDefaultRealm

py2:urllib2.AbstractBasicAuthHandler

py2:urllib2.HTTPBasicAuthHandler

py2:urllib2.ProxyBasicAuthHandler

py2:urllib2.AbstractDigestAuthHandler

py2:urllib2.HTTPDigestAuthHandler

py2:urllib2.ProxyDigestAuthHandler

py2:urllib2.HTTPHandler

py2:urllib2.HTTPSHandler

py2:urllib2.FileHandler

py2:urllib2.FTPHandler

py2:urllib2.CacheFTPHandler

py2:urllib2.UnknownHandler

py2:urllib2.HTTPErrorProcessor

urllib response

Contains classes from Python 3's py3:urllib.response and Python 2's:

py2:urllib:

py2:urllib.addbase

py2:urllib.addclosehook

py2:urllib.addinfo

py2:urllib.addinfourl

Advanced - Customizing renames

It is possible to add additional names to the six.moves namespace.

Instances of the following classes can be passed to add_move. Neither have any public members.

Create a mapping for six.moves called name that references different modules in Python 2 and 3. old_mod is the name of the Python 2 module. new_mod is the name of the Python 3 module.

Create a mapping for six.moves called name that references different attributes in Python 2 and 3. old_mod is the name of the Python 2 module. new_mod is the name of the Python 3 module. If new_attr is not given, it defaults to old_attr. If neither is given, they both default to name.