Imported Upstream version 1.11.0 upstream/1.11.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 4 Jan 2021 06:35:02 +0000 (15:35 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 4 Jan 2021 06:35:02 +0000 (15:35 +0900)
18 files changed:
.gitignore [new file with mode: 0644]
.travis.yml [new file with mode: 0644]
CHANGES
CONTRIBUTORS [new file with mode: 0644]
LICENSE
PKG-INFO [deleted file]
README.rst [moved from README with 57% similarity]
documentation/conf.py
documentation/index.rst
setup.cfg
setup.py
six.egg-info/PKG-INFO [deleted file]
six.egg-info/SOURCES.txt [deleted file]
six.egg-info/dependency_links.txt [deleted file]
six.egg-info/top_level.txt [deleted file]
six.py
test_six.py
tox.ini [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..7b027c2
--- /dev/null
@@ -0,0 +1,6 @@
+*.pyc
+dist
+MANIFEST
+documentation/_build
+.tox
+six.egg-info
diff --git a/.travis.yml b/.travis.yml
new file mode 100644 (file)
index 0000000..f86390e
--- /dev/null
@@ -0,0 +1,50 @@
+os: linux
+dist: trusty
+sudo: false
+language: python
+python:
+- 2.6
+- 2.7
+- 3.2
+- 3.3
+- 3.4
+- 3.5
+- &mainstream_python 3.6
+- 3.6-dev
+- 3.7-dev
+- pypy2.7-5.8.0
+- pypy3.5-5.8.0
+install:
+- pip install --upgrade --force-reinstall "setuptools; python_version != '3.2'" "setuptools < 30; python_version == '3.2'"
+- pip uninstall --yes six || true
+- pip install --upgrade --force-reinstall --ignore-installed -e .
+- pip install pytest
+- &py_pkg_list pip list --format=columns || pip list
+script:
+- py.test
+- echo Checking whether installation flow is not broken...
+- pip uninstall --yes six || true
+- pip install --ignore-installed .
+- *py_pkg_list
+jobs:
+  fast_finish: true
+  include:
+  - stage: upload new version of python package to PYPI (only for tagged commits)
+    python: *mainstream_python
+    install: skip
+    script: skip
+    deploy:
+      provider: pypi
+      on:
+        tags: true
+        all_branches: true
+        python: *mainstream_python
+      user: gutworth
+      distributions: "sdist bdist_wheel"
+      password:
+        secure: NPhfQT7XnZb0r0hKGWBwpHPXYpe3diD8aQXaUUq7+Y/iLAk5PhoFCRz+lPqnu7HiQcC2mcdzz3fvvRmj9IR/4EJj/+hkAfUeK4utwhXojSovEyk7VM/sUoT8hK4x++42sqbTvu2UcoSabTMEdFXC/Rhg/HHmOYzRMONJF2l8NGLsOu+t+BM6ruMZbmteGcquedi6JcOOAx7KR8dZ5vY387HwMyZg8yis4Qp7fSSivLzjV5i60ZDE4GzbD0XXywc+dxvl6KnLvJN4ApwnDRgTDsPU7OuEG09od0kVELhxsvwvKh47iBor0vVWCLb+sOgQj+EgMVZNqbghvTdQZMR/D4CADKBHHYZcCS7PuesbXfP4/USzDHPQB1i9bPMo7heRJpOfAt09SC49MJ6F1oEXkDWizN64Q9S3C0ZZvl4oDRcBxOYv17QyCM88ezhokadF2anVz+qEG7QINDrpq0qDGYnvb+1m7iZkGELnbmYPN3vu4Kow2LQkIE2tomv6Hvd/NTCEXHoPBybNE2LhmfrN6tdpkT0DDAg2PCnexcl+usZArHYuA/chX1IuhmxrQCeVVhSiVdxldR3XRjmavYcNhLsYP9upxEGEtQw7zR8vIw+WDlZmR+UN44sjTQCescAznZyxlqBtB6heW5CkrtiMjcmwKplCccsPHwWrkKOSb6w=
+cache:
+  pip: true
+after_failure:
+- echo "Here's a list of installed Python packages:"
+- *py_pkg_list
diff --git a/CHANGES b/CHANGES
index 6e9df6d..b399882 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,29 @@ Changelog for six
 
 This file lists the changes in each six version.
 
+1.11.0
+------
+
+- Pull request #178: `with_metaclass` now properly proxies `__prepare__` to the
+  underlying metaclass.
+
+- Pull request #191: Allow `with_metaclass` to work with metaclasses implemented
+  in C.
+
+- Pull request #203: Add parse_http_list and parse_keqv_list to moved
+  urllib.request.
+
+- Pull request #172 and issue #171: Add unquote_to_bytes to moved urllib.parse.
+
+- Pull request #167: Add `six.moves.getoutput`.
+
+- Pull request #80: Add `six.moves.urllib_parse.splitvalue`.
+
+- Pull request #75: Add `six.moves.email_mime_image`.
+
+- Pull request #72: Avoid creating reference cycles through tracebacks in
+  `reraise`.
+
 1.10.0
 ------
 
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..5979045
--- /dev/null
@@ -0,0 +1,32 @@
+The primary author and maintainer of six is Benjamin Peterson. He would like to
+acknowledge the following people who submitted bug reports, pull requests, and
+otherwise worked to improve six:
+
+Marc Abramowitz
+Alexander Artemenko
+Aymeric Augustin
+Ned Batchelder
+Wouter Bolsterlee
+Brett Cannon
+Jason R. Coombs
+Julien Danjou
+Ben Darnell
+Ben Davis
+Tim Graham
+Thomas Grainger
+Max Grender-Jones
+Joshua Harlow
+Anselm Kruis
+Alexander Lukanin
+James Mills
+Berker Peksag
+Sridhar Ratnakumar
+Erik Rose
+Mirko Rossini
+Peter Ruibal
+Miroslav Shubernetskiy
+Anthony Sottile
+Lucas Wiman
+Jordan Moldow
+
+If you think you belong on this list, please let me know! --Benjamin
diff --git a/LICENSE b/LICENSE
index e558f9d..f3068bf 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-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 in
diff --git a/PKG-INFO b/PKG-INFO
deleted file mode 100644 (file)
index 8c403fe..0000000
--- a/PKG-INFO
+++ /dev/null
@@ -1,32 +0,0 @@
-Metadata-Version: 1.1
-Name: six
-Version: 1.10.0
-Summary: Python 2 and 3 compatibility utilities
-Home-page: http://pypi.python.org/pypi/six/
-Author: Benjamin Peterson
-Author-email: benjamin@python.org
-License: MIT
-Description: Six is a Python 2 and 3 compatibility library.  It provides utility functions
-        for smoothing over the differences between the Python versions with the goal of
-        writing Python code that is compatible on both Python versions.  See the
-        documentation for more information on what is provided.
-        
-        Six supports every Python version since 2.6.  It is contained in only one Python
-        file, so it can be easily copied into your project. (The copyright and license
-        notice must be retained.)
-        
-        Online documentation is at https://pythonhosted.org/six/.
-        
-        Bugs can be reported to https://bitbucket.org/gutworth/six.  The code can also
-        be found there.
-        
-        For questions about six or porting in general, email the python-porting mailing
-        list: https://mail.python.org/mailman/listinfo/python-porting
-        
-Platform: UNKNOWN
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Utilities
similarity index 57%
rename from README
rename to README.rst
index ee628a9..c17d8d7 100644 (file)
--- a/README
@@ -1,3 +1,12 @@
+.. image:: http://img.shields.io/pypi/v/six.svg
+   :target: https://pypi.python.org/pypi/six
+
+.. image:: https://travis-ci.org/benjaminp/six.svg?branch=master
+    :target: https://travis-ci.org/benjaminp/six
+
+.. image:: http://img.shields.io/badge/license-MIT-green.svg
+   :target: https://github.com/benjaminp/six/blob/master/LICENSE
+
 Six is a Python 2 and 3 compatibility library.  It provides utility functions
 for smoothing over the differences between the Python versions with the goal of
 writing Python code that is compatible on both Python versions.  See the
@@ -7,9 +16,9 @@ Six supports every Python version since 2.6.  It is contained in only one Python
 file, so it can be easily copied into your project. (The copyright and license
 notice must be retained.)
 
-Online documentation is at https://pythonhosted.org/six/.
+Online documentation is at http://six.rtfd.org.
 
-Bugs can be reported to https://bitbucket.org/gutworth/six.  The code can also
+Bugs can be reported to https://github.com/benjaminp/six.  The code can also
 be found there.
 
 For questions about six or porting in general, email the python-porting mailing
index 0215bdd..ad925c1 100644 (file)
@@ -33,7 +33,7 @@ master_doc = "index"
 
 # General information about the project.
 project = u"six"
-copyright = u"2010-2015, Benjamin Peterson"
+copyright = u"2010-2017, Benjamin Peterson"
 
 sys.path.append(os.path.abspath(os.path.join(".", "..")))
 from six import __version__ as six_version
index 1391bac..dd0dc6e 100644 (file)
@@ -13,8 +13,8 @@ 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 <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
@@ -104,7 +104,7 @@ Here's example usage of the module::
 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.
 
@@ -164,7 +164,9 @@ 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)
@@ -345,7 +347,7 @@ Python 2 and 3.
    on Python 3 or ::
 
        class MyClass(object):
-           __metaclass__ = MyMeta
+           __metaclass__ = Meta
 
    on Python 2.
 
@@ -361,7 +363,7 @@ 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
+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.
 
@@ -376,7 +378,7 @@ 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)
@@ -433,7 +435,7 @@ string data in all Python versions.
 
 .. 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.
 
@@ -509,7 +511,7 @@ For the most part, :mod:`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
+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``.
 
@@ -530,14 +532,14 @@ functionality; its structure mimics the structure of the Python 3
 
      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::
@@ -548,139 +550,143 @@ functionality; its structure mimics the structure of the Python 3
 
 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
 <<<<<<<<<<<<
@@ -715,7 +721,8 @@ and :mod:`py2:urllib`:
 * :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`
 
@@ -762,6 +769,8 @@ and :mod:`py2:urllib2`:
 * :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`
index c8a09e2..70ce163 100644 (file)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,22 +1,17 @@
-[wheel]
+[bdist_wheel]
 universal = 1
 
 [flake8]
 max-line-length = 100
 ignore = F821
 
-[pytest]
-minversion = 2.2.0
-pep8ignore = 
-       documentation/*.py ALL
-       test_six.py ALL
-flakes-ignore = 
-       documentation/*.py ALL
-       test_six.py ALL
-       six.py UndefinedName
-
-[egg_info]
-tag_date = 0
-tag_svn_revision = 0
-tag_build = 
+[tool:pytest]
+minversion=2.2.0
+pep8ignore =
+    documentation/*.py ALL
+    test_six.py ALL
 
+flakes-ignore =
+    documentation/*.py ALL
+    test_six.py ALL
+    six.py UndefinedName
index b0cca52..ca44e10 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,28 @@
+# 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
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
 from __future__ import with_statement
 
+# Six is a dependency of setuptools, so using setuptools creates a
+# circular dependency when building a Python stack from source. We
+# therefore allow falling back to distutils to install six.
 try:
     from setuptools import setup
 except ImportError:
@@ -16,7 +39,7 @@ six_classifiers = [
     "Topic :: Utilities",
 ]
 
-with open("README", "r") as fp:
+with open("README.rst", "r") as fp:
     six_long_description = fp.read()
 
 setup(name="six",
@@ -24,6 +47,7 @@ setup(name="six",
       author="Benjamin Peterson",
       author_email="benjamin@python.org",
       url="http://pypi.python.org/pypi/six/",
+      tests_require=["pytest"],
       py_modules=["six"],
       description="Python 2 and 3 compatibility utilities",
       long_description=six_long_description,
diff --git a/six.egg-info/PKG-INFO b/six.egg-info/PKG-INFO
deleted file mode 100644 (file)
index 8c403fe..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-Metadata-Version: 1.1
-Name: six
-Version: 1.10.0
-Summary: Python 2 and 3 compatibility utilities
-Home-page: http://pypi.python.org/pypi/six/
-Author: Benjamin Peterson
-Author-email: benjamin@python.org
-License: MIT
-Description: Six is a Python 2 and 3 compatibility library.  It provides utility functions
-        for smoothing over the differences between the Python versions with the goal of
-        writing Python code that is compatible on both Python versions.  See the
-        documentation for more information on what is provided.
-        
-        Six supports every Python version since 2.6.  It is contained in only one Python
-        file, so it can be easily copied into your project. (The copyright and license
-        notice must be retained.)
-        
-        Online documentation is at https://pythonhosted.org/six/.
-        
-        Bugs can be reported to https://bitbucket.org/gutworth/six.  The code can also
-        be found there.
-        
-        For questions about six or porting in general, email the python-porting mailing
-        list: https://mail.python.org/mailman/listinfo/python-porting
-        
-Platform: UNKNOWN
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Topic :: Software Development :: Libraries
-Classifier: Topic :: Utilities
diff --git a/six.egg-info/SOURCES.txt b/six.egg-info/SOURCES.txt
deleted file mode 100644 (file)
index 9aa7c20..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-CHANGES
-LICENSE
-MANIFEST.in
-README
-setup.cfg
-setup.py
-six.py
-test_six.py
-documentation/Makefile
-documentation/conf.py
-documentation/index.rst
-six.egg-info/PKG-INFO
-six.egg-info/SOURCES.txt
-six.egg-info/dependency_links.txt
-six.egg-info/top_level.txt
\ No newline at end of file
diff --git a/six.egg-info/dependency_links.txt b/six.egg-info/dependency_links.txt
deleted file mode 100644 (file)
index 8b13789..0000000
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/six.egg-info/top_level.txt b/six.egg-info/top_level.txt
deleted file mode 100644 (file)
index ffe2fce..0000000
+++ /dev/null
@@ -1 +0,0 @@
-six
diff --git a/six.py b/six.py
index 190c023..6bf4fd3 100644 (file)
--- a/six.py
+++ b/six.py
@@ -1,6 +1,4 @@
-"""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
@@ -20,6 +18,8 @@
 # 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
@@ -29,7 +29,7 @@ import sys
 import types
 
 __author__ = "Benjamin Peterson <benjamin@python.org>"
-__version__ = "1.10.0"
+__version__ = "1.11.0"
 
 
 # Useful for very coarse version differentiation.
@@ -241,6 +241,7 @@ _moved_attributes = [
     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"),
@@ -262,10 +263,11 @@ _moved_attributes = [
     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"),
@@ -337,10 +339,12 @@ _urllib_parse_moved_attributes = [
     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"),
@@ -416,6 +420,8 @@ _urllib_request_moved_attributes = [
     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)
@@ -679,11 +685,15 @@ if PY3:
     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):
@@ -699,19 +709,28 @@ else:
         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):
@@ -802,10 +821,14 @@ def with_metaclass(meta, *bases):
     # 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', (), {})
 
 
index 3e57f49..43e7426 100644 (file)
@@ -1,3 +1,23 @@
+# 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
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
 import operator
 import sys
 import types
@@ -212,6 +232,12 @@ def test_map():
     assert six.advance_iterator(map(lambda x: x + 1, range(2))) == 1
 
 
+def test_getoutput():
+    from six.moves import getoutput
+    output = getoutput('echo "foo"')
+    assert output == 'foo'
+
+
 def test_zip():
     from six.moves import zip
     assert six.advance_iterator(zip(range(2), range(2))) == (0, 0)
@@ -708,6 +734,42 @@ def test_with_metaclass():
     assert issubclass(X, Base)
     assert issubclass(X, Base2)
     assert X.__mro__ == (X, Base, Base2, object)
+    class X(six.with_metaclass(Meta)):
+        pass
+    class MetaSub(Meta):
+        pass
+    class Y(six.with_metaclass(MetaSub, X)):
+        pass
+    assert type(Y) is MetaSub
+    assert Y.__mro__ == (Y, X, object)
+
+
+@py.test.mark.skipif("sys.version_info[:2] < (3, 0)")
+def test_with_metaclass_prepare():
+    """Test that with_metaclass causes Meta.__prepare__ to be called with the correct arguments."""
+
+    class MyDict(dict):
+        pass
+
+    class Meta(type):
+
+        @classmethod
+        def __prepare__(cls, name, bases):
+            namespace = MyDict(super().__prepare__(name, bases), cls=cls, bases=bases)
+            namespace['namespace'] = namespace
+            return namespace
+
+    class Base(object):
+        pass
+
+    bases = (Base,)
+
+    class X(six.with_metaclass(Meta, *bases)):
+        pass
+
+    assert getattr(X, 'cls', type) is Meta
+    assert getattr(X, 'bases', ()) == bases
+    assert isinstance(getattr(X, 'namespace', {}), MyDict)
 
 
 def test_wraps():
diff --git a/tox.ini b/tox.ini
new file mode 100644 (file)
index 0000000..d581326
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,15 @@
+[tox]
+envlist=py26,py27,py31,py32,py33,py34,pypy,flake8
+indexserver=
+    default = https://pypi.python.org/simple
+    testrun = http://pypi.testrun.org
+
+[testenv]
+deps= pytest
+commands= py.test -rfsxX {posargs}
+
+[testenv:flake8]
+basepython=python
+deps=flake8
+commands= flake8 six.py
+