From: DongHun Kwak Date: Mon, 4 Jan 2021 06:35:49 +0000 (+0900) Subject: Imported Upstream version 1.11.0 X-Git-Tag: upstream/1.11.0^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a43a7ed88e166ebadeb2ca78704cc1d8d7e3f5f6;p=platform%2Fupstream%2Fpython3-six.git Imported Upstream version 1.11.0 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b027c2 --- /dev/null +++ b/.gitignore @@ -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 index 0000000..f86390e --- /dev/null +++ b/.travis.yml @@ -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 --- 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 index 0000000..5979045 --- /dev/null +++ b/CONTRIBUTORS @@ -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 --- 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 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 diff --git a/README b/README deleted file mode 100644 index ee628a9..0000000 --- a/README +++ /dev/null @@ -1,16 +0,0 @@ -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 diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c17d8d7 --- /dev/null +++ b/README.rst @@ -0,0 +1,25 @@ +.. 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 +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 http://six.rtfd.org. + +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 +list: https://mail.python.org/mailman/listinfo/python-porting diff --git a/documentation/conf.py b/documentation/conf.py index 0215bdd..ad925c1 100644 --- a/documentation/conf.py +++ b/documentation/conf.py @@ -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 diff --git a/documentation/index.rst b/documentation/index.rst index 1391bac..dd0dc6e 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -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 `_. Its bug -tracker and code hosting is on `BitBucket `_. +Six can be downloaded on `PyPi `_. Its bug +tracker and code hosting is on `GitHub `_. 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` diff --git a/setup.cfg b/setup.cfg index c8a09e2..70ce163 100644 --- 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 diff --git a/setup.py b/setup.py index b0cca52..ca44e10 100644 --- 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 index 8c403fe..0000000 --- a/six.egg-info/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 diff --git a/six.egg-info/SOURCES.txt b/six.egg-info/SOURCES.txt deleted file mode 100644 index 9aa7c20..0000000 --- a/six.egg-info/SOURCES.txt +++ /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 index 8b13789..0000000 --- a/six.egg-info/dependency_links.txt +++ /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 index ffe2fce..0000000 --- a/six.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -six diff --git a/six.py b/six.py index 190c023..6bf4fd3 100644 --- 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 " -__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', (), {}) diff --git a/test_six.py b/test_six.py index 3e57f49..43e7426 100644 --- a/test_six.py +++ b/test_six.py @@ -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 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 +