without modification. six consists of only one Python file, so it is painless
to copy into a project.
-Six can be downloaded on `PyPi <http://pypi.python.org/pypi/six/>`_. Its bug
-tracker and code hosting is on `BitBucket <http://bitbucket.org/gutworth/six>`_.
+Six can be downloaded on `PyPi <https://pypi.python.org/pypi/six/>`_. Its bug
+tracker and code hosting is on `GitHub <https://github.com/benjaminp/six>`_.
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
Object model compatibility
>>>>>>>>>>>>>>>>>>>>>>>>>>
-Python 3 renamed the attributes of several intepreter data structures. The
+Python 3 renamed the attributes of several interpreter data structures. The
following accessors are available. Note that the recommended way to inspect
functions and methods is the stdlib :mod:`py3:inspect` module.
Get the next item of iterator *it*. :exc:`py3:StopIteration` is raised if
the iterator is exhausted. This is a replacement for calling ``it.next()``
- in Python 2 and ``next(it)`` in Python 3.
+ in Python 2 and ``next(it)`` in Python 3. Python 2.6 and above have a
+ builtin ``next`` function, so six's version is only necessary for Python 2.5
+ compatibility.
.. function:: callable(obj)
on Python 3 or ::
class MyClass(object):
- __metaclass__ = MyMeta
+ __metaclass__ = Meta
on Python 2.
>>>>>>>>>>>>>>>>>>>>
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
+rigorously 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.
.. note::
Since all Python versions 2.6 and after support the ``b`` prefix,
- :func:`b`, code without 2.5 support doesn't need :func:`b`.
+ code without 2.5 support doesn't need :func:`b`.
.. function:: u(text)
.. data:: StringIO
- This is an fake file object for textual data. It's an alias for
+ This is a fake file object for textual data. It's an alias for
:class:`py2:StringIO.StringIO` in Python 2 and :class:`py3:io.StringIO` in
Python 3.
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
+Python 2 name is retained. This is so the appropriate modules can be found when
running on Python 2. For example, ``BaseHTTPServer`` which is in
``http.server`` in Python 3 is aliased as ``BaseHTTPServer``.
from six.moves.cPickle import loads
- work, six places special proxy objects in in :data:`py3:sys.modules`. These
+ work, six places special proxy objects in :data:`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 :data:`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
+ modules do not exist. This hack does not 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::
Supported renames:
-+------------------------------+-------------------------------------+-------------------------------------+
-| Name | Python 2 name | Python 3 name |
-+==============================+=====================================+=====================================+
-| ``builtins`` | :mod:`py2:__builtin__` | :mod:`py3:builtins` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``configparser`` | :mod:`py2:ConfigParser` | :mod:`py3:configparser` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``copyreg`` | :mod:`py2:copy_reg` | :mod:`py3:copyreg` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``cPickle`` | :mod:`py2:cPickle` | :mod:`py3:pickle` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``dbm_gnu`` | :func:`py2:gdbm` | :class:`py3:dbm.gnu` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``_dummy_thread`` | :mod:`py2:dummy_thread` | :mod:`py3:_dummy_thread` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``email_mime_multipart`` | :mod:`py2:email.MIMEMultipart` | :mod:`py3:email.mime.multipart` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``email_mime_nonmultipart`` | :mod:`py2:email.MIMENonMultipart` | :mod:`py3:email.mime.nonmultipart` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``email_mime_text`` | :mod:`py2:email.MIMEText` | :mod:`py3:email.mime.text` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``email_mime_base`` | :mod:`py2:email.MIMEBase` | :mod:`py3:email.mime.base` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``filter`` | :func:`py2:itertools.ifilter` | :func:`py3:filter` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``filterfalse`` | :func:`py2:itertools.ifilterfalse` | :func:`py3:itertools.filterfalse` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``getcwd`` | :func:`py2:os.getcwdu` | :func:`py3:os.getcwd` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``getcwdb`` | :func:`py2:os.getcwd` | :func:`py3:os.getcwdb` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``http_cookiejar`` | :mod:`py2:cookielib` | :mod:`py3:http.cookiejar` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``http_cookies`` | :mod:`py2:Cookie` | :mod:`py3:http.cookies` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``html_entities`` | :mod:`py2:htmlentitydefs` | :mod:`py3:html.entities` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``html_parser`` | :mod:`py2:HTMLParser` | :mod:`py3:html.parser` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``http_client`` | :mod:`py2:httplib` | :mod:`py3:http.client` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``BaseHTTPServer`` | :mod:`py2:BaseHTTPServer` | :mod:`py3:http.server` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``CGIHTTPServer`` | :mod:`py2:CGIHTTPServer` | :mod:`py3:http.server` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``SimpleHTTPServer`` | :mod:`py2:SimpleHTTPServer` | :mod:`py3:http.server` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``input`` | :func:`py2:raw_input` | :func:`py3:input` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``intern`` | :func:`py2:intern` | :func:`py3:sys.intern` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``map`` | :func:`py2:itertools.imap` | :func:`py3:map` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``queue`` | :mod:`py2:Queue` | :mod:`py3:queue` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``range`` | :func:`py2:xrange` | :func:`py3:range` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``reduce`` | :func:`py2:reduce` | :func:`py3:functools.reduce` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``reload_module`` | :func:`py2:reload` | :func:`py3:imp.reload`, |
-| | | :func:`py3:importlib.reload` |
-| | | on Python 3.4+ |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``reprlib`` | :mod:`py2:repr` | :mod:`py3:reprlib` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``shlex_quote`` | :mod:`py2:pipes.quote` | :mod:`py3:shlex.quote` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``socketserver`` | :mod:`py2:SocketServer` | :mod:`py3:socketserver` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``_thread`` | :mod:`py2:thread` | :mod:`py3:_thread` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter`` | :mod:`py2:Tkinter` | :mod:`py3:tkinter` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_dialog`` | :mod:`py2:Dialog` | :mod:`py3:tkinter.dialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_filedialog`` | :mod:`py2:FileDialog` | :mod:`py3:tkinter.FileDialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_scrolledtext`` | :mod:`py2:ScrolledText` | :mod:`py3:tkinter.scrolledtext` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_simpledialog`` | :mod:`py2:SimpleDialog` | :mod:`py3:tkinter.simpledialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_ttk`` | :mod:`py2:ttk` | :mod:`py3:tkinter.ttk` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_tix`` | :mod:`py2:Tix` | :mod:`py3:tkinter.tix` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_constants`` | :mod:`py2:Tkconstants` | :mod:`py3:tkinter.constants` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_dnd`` | :mod:`py2:Tkdnd` | :mod:`py3:tkinter.dnd` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_colorchooser`` | :mod:`py2:tkColorChooser` | :mod:`py3:tkinter.colorchooser` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_commondialog`` | :mod:`py2:tkCommonDialog` | :mod:`py3:tkinter.commondialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_tkfiledialog`` | :mod:`py2:tkFileDialog` | :mod:`py3:tkinter.filedialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_font`` | :mod:`py2:tkFont` | :mod:`py3:tkinter.font` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_messagebox`` | :mod:`py2:tkMessageBox` | :mod:`py3:tkinter.messagebox` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``tkinter_tksimpledialog`` | :mod:`py2:tkSimpleDialog` | :mod:`py3:tkinter.simpledialog` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib.parse`` | See :mod:`six.moves.urllib.parse` | :mod:`py3:urllib.parse` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib.error`` | See :mod:`six.moves.urllib.error` | :mod:`py3:urllib.error` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib.request`` | See :mod:`six.moves.urllib.request` | :mod:`py3:urllib.request` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib.response`` | See :mod:`six.moves.urllib.response`| :mod:`py3:urllib.response` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib.robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``urllib_robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``UserDict`` | :class:`py2:UserDict.UserDict` | :class:`py3:collections.UserDict` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``UserList`` | :class:`py2:UserList.UserList` | :class:`py3:collections.UserList` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``UserString`` | :class:`py2:UserString.UserString` | :class:`py3:collections.UserString` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``winreg`` | :mod:`py2:_winreg` | :mod:`py3:winreg` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``xmlrpc_client`` | :mod:`py2:xmlrpclib` | :mod:`py3:xmlrpc.client` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``xmlrpc_server`` | :mod:`py2:SimpleXMLRPCServer` | :mod:`py3:xmlrpc.server` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``xrange`` | :func:`py2:xrange` | :func:`py3:range` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``zip`` | :func:`py2:itertools.izip` | :func:`py3:zip` |
-+------------------------------+-------------------------------------+-------------------------------------+
-| ``zip_longest`` | :func:`py2:itertools.izip_longest` | :func:`py3:itertools.zip_longest` |
-+------------------------------+-------------------------------------+-------------------------------------+
++------------------------------+-------------------------------------+---------------------------------------+
+| Name | Python 2 name | Python 3 name |
++==============================+=====================================+=======================================+
+| ``builtins`` | :mod:`py2:__builtin__` | :mod:`py3:builtins` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``configparser`` | :mod:`py2:ConfigParser` | :mod:`py3:configparser` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``copyreg`` | :mod:`py2:copy_reg` | :mod:`py3:copyreg` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``cPickle`` | :mod:`py2:cPickle` | :mod:`py3:pickle` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``dbm_gnu`` | :func:`py2:gdbm` | :class:`py3:dbm.gnu` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``_dummy_thread`` | :mod:`py2:dummy_thread` | :mod:`py3:_dummy_thread` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``email_mime_base`` | :mod:`py2:email.MIMEBase` | :mod:`py3:email.mime.base` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``email_mime_image`` | :mod:`py2:email.MIMEImage` | :mod:`py3:email.mime.image` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``email_mime_multipart`` | :mod:`py2:email.MIMEMultipart` | :mod:`py3:email.mime.multipart` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``email_mime_nonmultipart`` | :mod:`py2:email.MIMENonMultipart` | :mod:`py3:email.mime.nonmultipart` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``email_mime_text`` | :mod:`py2:email.MIMEText` | :mod:`py3:email.mime.text` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``filter`` | :func:`py2:itertools.ifilter` | :func:`py3:filter` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``filterfalse`` | :func:`py2:itertools.ifilterfalse` | :func:`py3:itertools.filterfalse` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``getcwd`` | :func:`py2:os.getcwdu` | :func:`py3:os.getcwd` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``getcwdb`` | :func:`py2:os.getcwd` | :func:`py3:os.getcwdb` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``getoutput`` | :func:`py2:commands.getoutput` | :func:`py3:subprocess.getoutput` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``http_cookiejar`` | :mod:`py2:cookielib` | :mod:`py3:http.cookiejar` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``http_cookies`` | :mod:`py2:Cookie` | :mod:`py3:http.cookies` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``html_entities`` | :mod:`py2:htmlentitydefs` | :mod:`py3:html.entities` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``html_parser`` | :mod:`py2:HTMLParser` | :mod:`py3:html.parser` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``http_client`` | :mod:`py2:httplib` | :mod:`py3:http.client` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``BaseHTTPServer`` | :mod:`py2:BaseHTTPServer` | :mod:`py3:http.server` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``CGIHTTPServer`` | :mod:`py2:CGIHTTPServer` | :mod:`py3:http.server` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``SimpleHTTPServer`` | :mod:`py2:SimpleHTTPServer` | :mod:`py3:http.server` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``input`` | :func:`py2:raw_input` | :func:`py3:input` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``intern`` | :func:`py2:intern` | :func:`py3:sys.intern` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``map`` | :func:`py2:itertools.imap` | :func:`py3:map` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``queue`` | :mod:`py2:Queue` | :mod:`py3:queue` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``range`` | :func:`py2:xrange` | :func:`py3:range` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``reduce`` | :func:`py2:reduce` | :func:`py3:functools.reduce` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``reload_module`` | :func:`py2:reload` | :func:`py3:imp.reload`, |
+| | | :func:`py3:importlib.reload` |
+| | | on Python 3.4+ |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``reprlib`` | :mod:`py2:repr` | :mod:`py3:reprlib` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``shlex_quote`` | :mod:`py2:pipes.quote` | :mod:`py3:shlex.quote` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``socketserver`` | :mod:`py2:SocketServer` | :mod:`py3:socketserver` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``_thread`` | :mod:`py2:thread` | :mod:`py3:_thread` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter`` | :mod:`py2:Tkinter` | :mod:`py3:tkinter` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_dialog`` | :mod:`py2:Dialog` | :mod:`py3:tkinter.dialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_filedialog`` | :mod:`py2:FileDialog` | :mod:`py3:tkinter.FileDialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_scrolledtext`` | :mod:`py2:ScrolledText` | :mod:`py3:tkinter.scrolledtext` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_simpledialog`` | :mod:`py2:SimpleDialog` | :mod:`py3:tkinter.simpledialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_ttk`` | :mod:`py2:ttk` | :mod:`py3:tkinter.ttk` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_tix`` | :mod:`py2:Tix` | :mod:`py3:tkinter.tix` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_constants`` | :mod:`py2:Tkconstants` | :mod:`py3:tkinter.constants` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_dnd`` | :mod:`py2:Tkdnd` | :mod:`py3:tkinter.dnd` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_colorchooser`` | :mod:`py2:tkColorChooser` | :mod:`py3:tkinter.colorchooser` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_commondialog`` | :mod:`py2:tkCommonDialog` | :mod:`py3:tkinter.commondialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_tkfiledialog`` | :mod:`py2:tkFileDialog` | :mod:`py3:tkinter.filedialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_font`` | :mod:`py2:tkFont` | :mod:`py3:tkinter.font` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_messagebox`` | :mod:`py2:tkMessageBox` | :mod:`py3:tkinter.messagebox` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``tkinter_tksimpledialog`` | :mod:`py2:tkSimpleDialog` | :mod:`py3:tkinter.simpledialog` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib.parse`` | See :mod:`six.moves.urllib.parse` | :mod:`py3:urllib.parse` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib.error`` | See :mod:`six.moves.urllib.error` | :mod:`py3:urllib.error` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib.request`` | See :mod:`six.moves.urllib.request` | :mod:`py3:urllib.request` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib.response`` | See :mod:`six.moves.urllib.response`| :mod:`py3:urllib.response` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib.robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``urllib_robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``UserDict`` | :class:`py2:UserDict.UserDict` | :class:`py3:collections.UserDict` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``UserList`` | :class:`py2:UserList.UserList` | :class:`py3:collections.UserList` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``UserString`` | :class:`py2:UserString.UserString` | :class:`py3:collections.UserString` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``winreg`` | :mod:`py2:_winreg` | :mod:`py3:winreg` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``xmlrpc_client`` | :mod:`py2:xmlrpclib` | :mod:`py3:xmlrpc.client` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``xmlrpc_server`` | :mod:`py2:SimpleXMLRPCServer` | :mod:`py3:xmlrpc.server` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``xrange`` | :func:`py2:xrange` | :func:`py3:range` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``zip`` | :func:`py2:itertools.izip` | :func:`py3:zip` |
++------------------------------+-------------------------------------+---------------------------------------+
+| ``zip_longest`` | :func:`py2:itertools.izip_longest` | :func:`py3:itertools.zip_longest` |
++------------------------------+-------------------------------------+---------------------------------------+
urllib parse
<<<<<<<<<<<<
* :func:`py2:urllib.quote_plus`
* :func:`py2:urllib.splittag`
* :func:`py2:urllib.splituser`
-* :func:`py2:urllib.unquote`
+* :func:`py2:urllib.splitvalue`
+* :func:`py2:urllib.unquote` (also exposed as :func:`py3:urllib.parse.unquote_to_bytes`)
* :func:`py2:urllib.unquote_plus`
* :func:`py2:urllib.urlencode`
* :func:`py2:urllib2.urlopen`
* :func:`py2:urllib2.install_opener`
* :func:`py2:urllib2.build_opener`
+* :func:`py2:urllib2.parse_http_list`
+* :func:`py2:urllib2.parse_keqv_list`
* :class:`py2:urllib2.Request`
* :class:`py2:urllib2.OpenerDirector`
* :class:`py2:urllib2.HTTPDefaultErrorHandler`
-"""Utilities for writing code that runs on Python 2 and 3"""
-
-# Copyright (c) 2010-2015 Benjamin Peterson
+# Copyright (c) 2010-2017 Benjamin Peterson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
+"""Utilities for writing code that runs on Python 2 and 3"""
+
from __future__ import absolute_import
import functools
import types
__author__ = "Benjamin Peterson <benjamin@python.org>"
-__version__ = "1.10.0"
+__version__ = "1.11.0"
# Useful for very coarse version differentiation.
MovedAttribute("map", "itertools", "builtins", "imap", "map"),
MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
+ MovedAttribute("getoutput", "commands", "subprocess"),
MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"),
MovedAttribute("reduce", "__builtin__", "functools"),
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
MovedModule("html_parser", "HTMLParser", "html.parser"),
MovedModule("http_client", "httplib", "http.client"),
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
+ MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"),
MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
- MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
MovedAttribute("quote_plus", "urllib", "urllib.parse"),
MovedAttribute("unquote", "urllib", "urllib.parse"),
MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
+ MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"),
MovedAttribute("urlencode", "urllib", "urllib.parse"),
MovedAttribute("splitquery", "urllib", "urllib.parse"),
MovedAttribute("splittag", "urllib", "urllib.parse"),
MovedAttribute("splituser", "urllib", "urllib.parse"),
+ MovedAttribute("splitvalue", "urllib", "urllib.parse"),
MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
MovedAttribute("uses_params", "urlparse", "urllib.parse"),
MovedAttribute("URLopener", "urllib", "urllib.request"),
MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
+ MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
+ MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
]
for attr in _urllib_request_moved_attributes:
setattr(Module_six_moves_urllib_request, attr.name, attr)
exec_ = getattr(moves.builtins, "exec")
def reraise(tp, value, tb=None):
- if value is None:
- value = tp()
- if value.__traceback__ is not tb:
- raise value.with_traceback(tb)
- raise value
+ try:
+ if value is None:
+ value = tp()
+ if value.__traceback__ is not tb:
+ raise value.with_traceback(tb)
+ raise value
+ finally:
+ value = None
+ tb = None
else:
def exec_(_code_, _globs_=None, _locs_=None):
exec("""exec _code_ in _globs_, _locs_""")
exec_("""def reraise(tp, value, tb=None):
- raise tp, value, tb
+ try:
+ raise tp, value, tb
+ finally:
+ tb = None
""")
if sys.version_info[:2] == (3, 2):
exec_("""def raise_from(value, from_value):
- if from_value is None:
- raise value
- raise value from from_value
+ try:
+ if from_value is None:
+ raise value
+ raise value from from_value
+ finally:
+ value = None
""")
elif sys.version_info[:2] > (3, 2):
exec_("""def raise_from(value, from_value):
- raise value from from_value
+ try:
+ raise value from from_value
+ finally:
+ value = None
""")
else:
def raise_from(value, from_value):
# This requires a bit of explanation: the basic idea is to make a dummy
# metaclass for one level of class instantiation that replaces itself with
# the actual metaclass.
- class metaclass(meta):
+ class metaclass(type):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
+
+ @classmethod
+ def __prepare__(cls, name, this_bases):
+ return meta.__prepare__(name, bases)
return type.__new__(metaclass, 'temporary_class', (), {})