From: DongHun Kwak Date: Mon, 4 Jan 2021 06:35:02 +0000 (+0900) Subject: Imported Upstream version 1.11.0 X-Git-Tag: upstream/1.11.0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Ftags%2Fupstream%2F1.11.0;p=platform%2Fupstream%2Fpython-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.rst similarity index 57% rename from README rename to README.rst index ee628a9..c17d8d7 100644 --- a/README +++ b/README.rst @@ -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 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 +