Hello community, here is the log from the commit of package python-six for openSUSE:Leap:15.2 checked in at 2020-03-19 08:35:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python-six (Old) and /work/SRC/openSUSE:Leap:15.2/.python-six.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-six" Thu Mar 19 08:35:37 2020 rev:22 rq:785980 version:1.14.0 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python-six/python-six.changes 2020-01-15 15:53:01.971583786 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python-six.new.3160/python-six.changes 2020-03-19 08:35:44.937827464 +0100 @@ -1,0 +2,88 @@ +Tue Mar 10 07:53:50 UTC 2020 - Tomáš Chvátal <[email protected]> + +- Do not cause buildcycle with previous change but rather + install the egg-info prepared metadata from the tarball + +------------------------------------------------------------------- +Mon Mar 9 20:54:38 UTC 2020 - Dirk Mueller <[email protected]> + +- use setuptools for building to support pip 10.x (bsc#1166139) + +------------------------------------------------------------------- +Tue Jan 21 11:17:01 UTC 2020 - Ondřej Súkup <[email protected]> + +- update to 1.14.0 + * Add `six.assertNotRegex` + * `six.moves._dummy_thread` now points to the `_thread` module on + Python 3.9+. Python 3.7 and later requires threading and deprecated the + `_dummy_thread` module + * Remove support for Python 2.6 and Python 3.2 + * `six.wraps` now ignores missing attributes + +------------------------------------------------------------------- +Thu Jan 2 10:36:00 UTC 2020 - Tomáš Chvátal <[email protected]> + +- Pull in dbm/gdbm module from python for testing + +------------------------------------------------------------------- +Fri Dec 20 19:06:13 UTC 2019 - Dirk Mueller <[email protected]> + +- update to 0.13.0: + - Issue #298, pull request #299: Add `six.moves.dbm_ndbm`. + - Issue #155: Add `six.moves.collections_abc`, which aliases the `collections` + module on Python 2-3.2 and the `collections.abc` on Python 3.3 and greater. + - Pull request #304: Re-add distutils fallback in `setup.py`. + - Pull request #305: On Python 3.7, `with_metaclass` supports classes using PEP + +------------------------------------------------------------------- +Thu Jul 18 09:15:25 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Simplify the pytest call + +------------------------------------------------------------------- +Tue Jun 11 06:58:13 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Fix pytest call +- Fixdocumentation package generating + +------------------------------------------------------------------- +Fri Jan 25 19:43:33 UTC 2019 - Neal Gompa <[email protected]> + +- Change %pretrans back to %pre to fix bootstrap issue + boo#1123064 bsc#1143893 + +------------------------------------------------------------------- +Thu Jan 17 11:31:09 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Require just base python module, even full python is too much + and it is not required here + +------------------------------------------------------------------- +Mon Dec 10 09:20:52 CET 2018 - [email protected] + +- Update to 0.12.0: + * `six.add_metaclass` now preserves `__qualname__` from the + original class. + * Add `six.ensure_binary`, `six.ensure_text`, and + `six.ensure_str`. +- Because of cyclical dependencies between six and Sphinx, we + need to to do multibuild. + +------------------------------------------------------------------- +Mon Sep 3 15:37:13 UTC 2018 - Hans-Peter Jansen <[email protected]> + +- remove egg-info directory in %pretrans +- fix egg-info directory pattern +- match any version of egg-info for a certain python version + +------------------------------------------------------------------- +Sat Aug 18 09:08:38 UTC 2018 - Matěj Cepl <[email protected]> + +- Break the cycilical dependency on python-setuptools. + +------------------------------------------------------------------- +Fri Aug 10 13:07:30 UTC 2018 - [email protected] + +- Remove argparse dependency + +------------------------------------------------------------------- Old: ---- python-six-doc.changes python-six-doc.spec six-1.11.0.tar.gz New: ---- _multibuild six-1.14.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-six.spec ++++++ --- /var/tmp/diff_new_pack.WV8brz/_old 2020-03-19 08:35:45.261827662 +0100 +++ /var/tmp/diff_new_pack.WV8brz/_new 2020-03-19 08:35:45.265827665 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-six # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,29 +12,39 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %{?!python_module:%define python_module() python-%{**} python3-%{**}} -Name: python-six -Version: 1.11.0 +# This is not only because of dependency of testsuite, but mostly +# because of cyclical dependencies between six and Sphinx. +%global flavor @BUILD_FLAVOR@%{nil} +%if "%{flavor}" == "test" +%bcond_without test +%define psuffix -test +%else +%bcond_with test +%define psuffix %{nil} +%endif +Name: python-six%{psuffix} +Version: 1.14.0 Release: 0 -Url: http://pypi.python.org/pypi/six/ Summary: Python 2 and 3 compatibility utilities License: MIT Group: Development/Libraries/Python +URL: http://pypi.python.org/pypi/six/ Source: https://files.pythonhosted.org/packages/source/s/six/six-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: %{python_module base} +BuildRequires: fdupes BuildRequires: python-rpm-macros -%if 0%{?suse_version} > 1110 BuildArch: noarch -%else -BuildRequires: python-argparse -Requires: python-argparse +%if %{with test} +BuildRequires: %{python_module dbm} +BuildRequires: %{python_module pytest} +BuildRequires: %{python_module py} +BuildRequires: python3-Sphinx %endif - %python_subpackages %description @@ -44,32 +54,61 @@ both Python versions. See the documentation for more information on what is provided. +%package -n python-six-doc +Summary: Documentation files for %{name} +Group: Documentation/HTML +Provides: %{python_module six-doc = %{version}} + +%description -n python-six-doc +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. + +This package provides documentation for %{name}. + %prep %setup -q -n six-%{version} %build %python_build -# due to cyclic requirements between Sphinx and six, -# documentation is build in its own package <[email protected]> +%if %{with test} +cd documentation && make html && rm _build/html/.buildinfo +%endif %install +%if ! %{with test} %python_install +%python_expand %fdupes %{buildroot}%{$python_sitelib} +# add the setuptools egg-info directory +%{python_expand rm %{buildroot}%{$python_sitelib}/six-%{version}-py%{$python_version}.egg-info +mkdir -p %{buildroot}%{$python_sitelib}/six-%{version}-py%{$python_version}.egg-info/ +cp six.egg-info/* %{buildroot}%{$python_sitelib}/six-%{version}-py%{$python_version}.egg-info/ +} +%endif -# Run tests in -doc package to avoid dependency loop -# %check -# python test_six.py +%check +%if %{with test} +%pytest test_six.py +%endif %pre -# bsc#1057496 - egg-info changed from directory to file -if [ -d %{python_sitelib}/six-%{version}-py%{python_version}.egg-info ]; then - rm -r %{python_sitelib}/six-%{version}-%{python_version}.egg-info +# handle distutils (file) to setuptools transition (directory) +if [ -f %{python_sitelib}/six-*-py%{python_version}.egg-info ]; then + rm -vf %{python_sitelib}/six-*-py%{python_version}.egg-info fi -%files %python_files -%defattr(-,root,root) -%doc LICENSE README.rst CHANGES +%if !%{with test} +%files %{python_files} +%license LICENSE +%doc README.rst CHANGES %{python_sitelib}/six.py* %pycache_only %{python3_sitelib}/__pycache__/* %{python_sitelib}/six-%{version}-py*.egg-info +%else +%files -n python-six-doc +%license LICENSE +%doc documentation/_build/html +%endif %changelog ++++++ _multibuild ++++++ <multibuild> <package>test</package> </multibuild> ++++++ six-1.11.0.tar.gz -> six-1.14.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/CHANGES new/six-1.14.0/CHANGES --- old/six-1.11.0/CHANGES 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/CHANGES 2020-01-15 19:10:01.000000000 +0100 @@ -3,6 +3,42 @@ This file lists the changes in each six version. +1.14.0 +------ + +- Issue #288, pull request #289: Add `six.assertNotRegex`. + +- Issue #317: `six.moves._dummy_thread` now points to the `_thread` module on + Python 3.9+. Python 3.7 and later requires threading and deprecated the + `_dummy_thread` module. + +- Issue #308, pull request #314: Remove support for Python 2.6 and Python 3.2. + +- Issue #250, issue #165, pull request #251: `six.wraps` now ignores missing + attributes. This follows the Python 3.2+ standard library behavior. + +1.13.0 +------ + +- Issue #298, pull request #299: Add `six.moves.dbm_ndbm`. + +- Issue #155: Add `six.moves.collections_abc`, which aliases the `collections` + module on Python 2-3.2 and the `collections.abc` on Python 3.3 and greater. + +- Pull request #304: Re-add distutils fallback in `setup.py`. + +- Pull request #305: On Python 3.7, `with_metaclass` supports classes using PEP + 560 features. + +1.12.0 +------ + +- Issue #259, pull request #260: `six.add_metaclass` now preserves + `__qualname__` from the original class. + +- Pull request #204: Add `six.ensure_binary`, `six.ensure_text`, and + `six.ensure_str`. + 1.11.0 ------ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/LICENSE new/six-1.14.0/LICENSE --- old/six-1.11.0/LICENSE 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/LICENSE 2020-01-15 19:10:01.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2010-2017 Benjamin Peterson +Copyright (c) 2010-2020 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/PKG-INFO new/six-1.14.0/PKG-INFO --- old/six-1.11.0/PKG-INFO 2017-09-17 20:46:53.000000000 +0200 +++ new/six-1.14.0/PKG-INFO 2020-01-15 19:10:19.026476400 +0100 @@ -1,41 +1,47 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: six -Version: 1.11.0 +Version: 1.14.0 Summary: Python 2 and 3 compatibility utilities -Home-page: http://pypi.python.org/pypi/six/ +Home-page: https://github.com/benjaminp/six Author: Benjamin Peterson Author-email: [email protected] License: MIT -Description: .. image:: http://img.shields.io/pypi/v/six.svg - :target: https://pypi.python.org/pypi/six +Description: .. image:: https://img.shields.io/pypi/v/six.svg + :target: https://pypi.org/project/six/ + :alt: six on PyPI .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master - :target: https://travis-ci.org/benjaminp/six + :target: https://travis-ci.org/benjaminp/six + :alt: six on TravisCI - .. image:: http://img.shields.io/badge/license-MIT-green.svg + .. image:: https://readthedocs.org/projects/six/badge/?version=latest + :target: https://six.readthedocs.io/ + :alt: six's documentation on Read the Docs + + .. image:: https://img.shields.io/badge/license-MIT-green.svg :target: https://github.com/benjaminp/six/blob/master/LICENSE + :alt: MIT License badge 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 + Six supports Python 2.7 and 3.3+. 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. + Online documentation is at https://six.readthedocs.io/. 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 - Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable 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 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/README.rst new/six-1.14.0/README.rst --- old/six-1.11.0/README.rst 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/README.rst 2020-01-15 19:10:01.000000000 +0100 @@ -1,25 +1,29 @@ -.. image:: http://img.shields.io/pypi/v/six.svg - :target: https://pypi.python.org/pypi/six +.. image:: https://img.shields.io/pypi/v/six.svg + :target: https://pypi.org/project/six/ + :alt: six on PyPI .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master - :target: https://travis-ci.org/benjaminp/six + :target: https://travis-ci.org/benjaminp/six + :alt: six on TravisCI -.. image:: http://img.shields.io/badge/license-MIT-green.svg +.. image:: https://readthedocs.org/projects/six/badge/?version=latest + :target: https://six.readthedocs.io/ + :alt: six's documentation on Read the Docs + +.. image:: https://img.shields.io/badge/license-MIT-green.svg :target: https://github.com/benjaminp/six/blob/master/LICENSE + :alt: MIT License badge 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 +Six supports Python 2.7 and 3.3+. 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. +Online documentation is at https://six.readthedocs.io/. 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/documentation/conf.py new/six-1.14.0/documentation/conf.py --- old/six-1.11.0/documentation/conf.py 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/documentation/conf.py 2020-01-15 19:10:01.000000000 +0100 @@ -33,7 +33,7 @@ # General information about the project. project = u"six" -copyright = u"2010-2017, Benjamin Peterson" +copyright = u"2010-2020, Benjamin Peterson" sys.path.append(os.path.abspath(os.path.join(".", ".."))) from six import __version__ as six_version diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/documentation/index.rst new/six-1.14.0/documentation/index.rst --- old/six-1.11.0/documentation/index.rst 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/documentation/index.rst 2020-01-15 19:10:01.000000000 +0100 @@ -13,7 +13,7 @@ without modification. six consists of only one Python file, so it is painless to copy into a project. -Six can be downloaded on `PyPi <https://pypi.python.org/pypi/six/>`_. Its bug +Six can be downloaded on `PyPI <https://pypi.org/project/six/>`_. Its bug tracker and code hosting is on `GitHub <https://github.com/benjaminp/six>`_. The name, "six", comes from the fact that 2*3 equals 6. Why not addition? @@ -50,8 +50,9 @@ .. data:: class_types - Possible class types. In Python 2, this encompasses old-style and new-style - classes. In Python 3, this is just new-styles. + Possible class types. In Python 2, this encompasses old-style + :data:`py2:types.ClassType` and new-style ``type`` classes. In Python 3, + this is just ``type``. .. data:: integer_types @@ -75,7 +76,9 @@ .. data:: binary_type Type for representing binary data. This is :func:`py2:str` in Python 2 and - :func:`py3:bytes` in Python 3. + :func:`py3:bytes` in Python 3. Python 2.6 and 2.7 include ``bytes`` as a + builtin alias of ``str``, so six’s version is only necessary for Python 2.5 + compatibility. .. data:: MAXSIZE @@ -254,9 +257,10 @@ .. decorator:: wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES) - This is exactly the :func:`py3:functools.wraps` decorator, but it sets the - ``__wrapped__`` attribute on what it decorates as :func:`py3:functools.wraps` - does on Python versions after 3.2. + This is Python 3.2's :func:`py3:functools.wraps` decorator. It sets the + ``__wrapped__`` attribute on what it decorates. It doesn't raise an error if + any of the attributes mentioned in ``assigned`` and ``updated`` are missing + on ``wrapped`` object. Syntax compatibility @@ -371,7 +375,7 @@ .. function:: b(data) A "fake" bytes literal. *data* should always be a normal string literal. In - Python 2, :func:`b` returns a 8-bit string. In Python 3, *data* is encoded + Python 2, :func:`b` returns an 8-bit string. In Python 3, *data* is encoded with the latin-1 encoding to bytes. @@ -433,6 +437,24 @@ a bytes object iterator in Python 3. +.. function:: ensure_binary(s, encoding='utf-8', errors='strict') + + Coerce *s* to :data:`binary_type`. *encoding*, *errors* are the same as + :meth:`py3:str.encode` + + +.. function:: ensure_str(s, encoding='utf-8', errors='strict') + + Coerce *s* to ``str``. *encoding*, *errors* are the same as + :meth:`py3:str.encode` + + +.. function:: ensure_text(s, encoding='utf-8', errors='strict') + + Coerce *s* to :data:`text_type`. *encoding*, *errors* are the same as + :meth:`py3:str.encode` + + .. data:: StringIO This is a fake file object for textual data. It's an alias for @@ -488,6 +510,11 @@ Alias for :meth:`~py3:unittest.TestCase.assertRegex` on Python 3 and :meth:`~py2:unittest.TestCase.assertRegexpMatches` on Python 2. +.. function:: assertNotRegex() + + Alias for :meth:`~py3:unittest.TestCase.assertNotRegex` on Python 3 and + :meth:`~py2:unittest.TestCase.assertNotRegexpMatches` on Python 2. + Renamed modules and attributes compatibility >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -503,7 +530,7 @@ from six.moves import html_parser Similarly, to get the function to reload modules, which was moved from the -builtin module to the ``imp`` module, use:: +builtin module to the ``importlib`` module, use:: from six.moves import reload_module @@ -563,9 +590,14 @@ +------------------------------+-------------------------------------+---------------------------------------+ | ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` | +------------------------------+-------------------------------------+---------------------------------------+ -| ``dbm_gnu`` | :func:`py2:gdbm` | :class:`py3:dbm.gnu` | +| ``collections_abc`` | :mod:`py2:collections` | :mod:`py3:collections.abc` (3.3+) | ++------------------------------+-------------------------------------+---------------------------------------+ +| ``dbm_gnu`` | :mod:`py2:gdbm` | :mod:`py3:dbm.gnu` | ++------------------------------+-------------------------------------+---------------------------------------+ +| ``dbm_ndbm`` | :mod:`py2:dbm` | :mod:`py3:dbm.ndbm` | +------------------------------+-------------------------------------+---------------------------------------+ -| ``_dummy_thread`` | :mod:`py2:dummy_thread` | :mod:`py3:_dummy_thread` | +| ``_dummy_thread`` | :mod:`py2:dummy_thread` | :mod:`py3:_dummy_thread` (< 3.9) | +| | | :mod:`py3:_thread` (3.9+) | +------------------------------+-------------------------------------+---------------------------------------+ | ``email_mime_base`` | :mod:`py2:email.MIMEBase` | :mod:`py3:email.mime.base` | +------------------------------+-------------------------------------+---------------------------------------+ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/setup.cfg new/six-1.14.0/setup.cfg --- old/six-1.11.0/setup.cfg 2017-09-17 20:46:53.000000000 +0200 +++ new/six-1.14.0/setup.cfg 2020-01-15 19:10:19.026476400 +0100 @@ -5,6 +5,9 @@ max-line-length = 100 ignore = F821 +[metadata] +license_file = LICENSE + [tool:pytest] minversion = 2.2.0 pep8ignore = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/setup.py new/six-1.14.0/setup.py --- old/six-1.11.0/setup.py 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/setup.py 2020-01-15 19:10:01.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2017 Benjamin Peterson +# Copyright (c) 2010-2020 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 @@ -31,6 +31,7 @@ import six six_classifiers = [ + "Development Status :: 5 - Production/Stable", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Intended Audience :: Developers", @@ -46,11 +47,12 @@ version=six.__version__, author="Benjamin Peterson", author_email="[email protected]", - url="http://pypi.python.org/pypi/six/", + url="https://github.com/benjaminp/six", tests_require=["pytest"], py_modules=["six"], description="Python 2 and 3 compatibility utilities", long_description=six_long_description, license="MIT", - classifiers=six_classifiers + classifiers=six_classifiers, + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*", ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/six.egg-info/PKG-INFO new/six-1.14.0/six.egg-info/PKG-INFO --- old/six-1.11.0/six.egg-info/PKG-INFO 2017-09-17 20:46:53.000000000 +0200 +++ new/six-1.14.0/six.egg-info/PKG-INFO 2020-01-15 19:10:18.000000000 +0100 @@ -1,41 +1,47 @@ -Metadata-Version: 1.1 +Metadata-Version: 1.2 Name: six -Version: 1.11.0 +Version: 1.14.0 Summary: Python 2 and 3 compatibility utilities -Home-page: http://pypi.python.org/pypi/six/ +Home-page: https://github.com/benjaminp/six Author: Benjamin Peterson Author-email: [email protected] License: MIT -Description: .. image:: http://img.shields.io/pypi/v/six.svg - :target: https://pypi.python.org/pypi/six +Description: .. image:: https://img.shields.io/pypi/v/six.svg + :target: https://pypi.org/project/six/ + :alt: six on PyPI .. image:: https://travis-ci.org/benjaminp/six.svg?branch=master - :target: https://travis-ci.org/benjaminp/six + :target: https://travis-ci.org/benjaminp/six + :alt: six on TravisCI - .. image:: http://img.shields.io/badge/license-MIT-green.svg + .. image:: https://readthedocs.org/projects/six/badge/?version=latest + :target: https://six.readthedocs.io/ + :alt: six's documentation on Read the Docs + + .. image:: https://img.shields.io/badge/license-MIT-green.svg :target: https://github.com/benjaminp/six/blob/master/LICENSE + :alt: MIT License badge 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 + Six supports Python 2.7 and 3.3+. 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. + Online documentation is at https://six.readthedocs.io/. 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 - Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable 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 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/six.py new/six-1.14.0/six.py --- old/six-1.11.0/six.py 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/six.py 2020-01-15 19:10:01.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2017 Benjamin Peterson +# Copyright (c) 2010-2020 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 @@ -29,7 +29,7 @@ import types __author__ = "Benjamin Peterson <[email protected]>" -__version__ = "1.11.0" +__version__ = "1.14.0" # Useful for very coarse version differentiation. @@ -255,9 +255,11 @@ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), @@ -637,13 +639,16 @@ import io StringIO = io.StringIO BytesIO = io.BytesIO + del io _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" else: _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" + _assertNotRegex = "assertNotRegex" else: def b(s): return s @@ -665,6 +670,7 @@ _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") @@ -681,6 +687,10 @@ return getattr(self, _assertRegex)(*args, **kwargs) +def assertNotRegex(self, *args, **kwargs): + return getattr(self, _assertNotRegex)(*args, **kwargs) + + if PY3: exec_ = getattr(moves.builtins, "exec") @@ -716,16 +726,7 @@ """) -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, 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): +if sys.version_info[:2] > (3,): exec_("""def raise_from(value, from_value): try: raise value from from_value @@ -805,13 +806,33 @@ _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): + # This does exactly the same what the :func:`py3:functools.update_wrapper` + # function does on Python versions after 3.2. It sets the ``__wrapped__`` + # attribute on ``wrapper`` object and it doesn't raise an error if any of + # the attributes mentioned in ``assigned`` and ``updated`` are missing on + # ``wrapped`` object. + def _update_wrapper(wrapper, wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + continue + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + wrapper.__wrapped__ = wrapped + return wrapper + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper + return functools.partial(_update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + wraps.__doc__ = functools.wraps.__doc__ + else: wraps = functools.wraps @@ -824,7 +845,15 @@ class metaclass(type): def __new__(cls, name, this_bases, d): - return meta(name, bases, d) + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d['__orig_bases__'] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) @classmethod def __prepare__(cls, name, this_bases): @@ -844,13 +873,73 @@ orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) + if hasattr(cls, '__qualname__'): + orig_vars['__qualname__'] = cls.__qualname__ return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, text_type): + return s.encode(encoding, errors) + elif isinstance(s, binary_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding='utf-8', errors='strict'): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if PY2 and isinstance(s, text_type): + s = s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + s = s.decode(encoding, errors) + return s + + +def ensure_text(s, encoding='utf-8', errors='strict'): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + def python_2_unicode_compatible(klass): """ - A decorator that defines __unicode__ and __str__ methods under Python 2. + A class decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.11.0/test_six.py new/six-1.14.0/test_six.py --- old/six-1.11.0/test_six.py 2017-09-17 20:46:32.000000000 +0200 +++ new/six-1.14.0/test_six.py 2020-01-15 19:10:01.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2017 Benjamin Peterson +# Copyright (c) 2010-2020 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 @@ -22,8 +22,9 @@ import sys import types import unittest +import abc -import py +import pytest import six @@ -80,7 +81,7 @@ except AttributeError: # Before Python 2.6. pass - py.test.raises( + pytest.raises( (ValueError, OverflowError), operator.mul, [None], six.MAXSIZE + 1) @@ -112,7 +113,7 @@ except ImportError: have_gdbm = False [email protected]("item_name", [email protected]("item_name", [item.name for item in six._moved_attributes]) def test_move_items(item_name): """Ensure that everything loads correctly.""" @@ -120,70 +121,55 @@ item = getattr(six.moves, item_name) if isinstance(item, types.ModuleType): __import__("six.moves." + item_name) - except AttributeError: - if item_name == "zip_longest" and sys.version_info < (2, 6): - py.test.skip("zip_longest only available on 2.6+") except ImportError: if item_name == "winreg" and not sys.platform.startswith("win"): - py.test.skip("Windows only module") + pytest.skip("Windows only module") if item_name.startswith("tkinter"): if not have_tkinter: - py.test.skip("requires tkinter") - if item_name == "tkinter_ttk" and sys.version_info[:2] <= (2, 6): - py.test.skip("ttk only available on 2.7+") + pytest.skip("requires tkinter") if item_name.startswith("dbm_gnu") and not have_gdbm: - py.test.skip("requires gdbm") + pytest.skip("requires gdbm") raise - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves) + assert item_name in dir(six.moves) [email protected]("item_name", [email protected]("item_name", [item.name for item in six._urllib_parse_moved_attributes]) def test_move_items_urllib_parse(item_name): """Ensure that everything loads correctly.""" - if item_name == "ParseResult" and sys.version_info < (2, 5): - py.test.skip("ParseResult is only found on 2.5+") - if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6): - py.test.skip("parse_qs[l] is new in 2.6") - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves.urllib.parse) + assert item_name in dir(six.moves.urllib.parse) getattr(six.moves.urllib.parse, item_name) [email protected]("item_name", [email protected]("item_name", [item.name for item in six._urllib_error_moved_attributes]) def test_move_items_urllib_error(item_name): """Ensure that everything loads correctly.""" - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves.urllib.error) + assert item_name in dir(six.moves.urllib.error) getattr(six.moves.urllib.error, item_name) [email protected]("item_name", [email protected]("item_name", [item.name for item in six._urllib_request_moved_attributes]) def test_move_items_urllib_request(item_name): """Ensure that everything loads correctly.""" - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves.urllib.request) + assert item_name in dir(six.moves.urllib.request) getattr(six.moves.urllib.request, item_name) [email protected]("item_name", [email protected]("item_name", [item.name for item in six._urllib_response_moved_attributes]) def test_move_items_urllib_response(item_name): """Ensure that everything loads correctly.""" - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves.urllib.response) + assert item_name in dir(six.moves.urllib.response) getattr(six.moves.urllib.response, item_name) [email protected]("item_name", [email protected]("item_name", [item.name for item in six._urllib_robotparser_moved_attributes]) def test_move_items_urllib_robotparser(item_name): """Ensure that everything loads correctly.""" - if sys.version_info[:2] >= (2, 6): - assert item_name in dir(six.moves.urllib.robotparser) + assert item_name in dir(six.moves.urllib.robotparser) getattr(six.moves.urllib.robotparser, item_name) @@ -243,7 +229,6 @@ assert six.advance_iterator(zip(range(2), range(2))) == (0, 0) [email protected]("sys.version_info < (2, 6)") def test_zip_longest(): from six.moves import zip_longest it = zip_longest(range(2), range(1)) @@ -321,7 +306,7 @@ def test_empty_remove(self): - py.test.raises(AttributeError, six.remove_move, "eggs") + pytest.raises(AttributeError, six.remove_move, "eggs") def test_get_unbound_function(): @@ -337,7 +322,7 @@ pass x = X() assert six.get_method_self(x.m) is x - py.test.raises(AttributeError, six.get_method_self, 42) + pytest.raises(AttributeError, six.get_method_self, 42) def test_get_method_function(): @@ -346,7 +331,7 @@ pass x = X() assert six.get_method_function(x.m) is X.__dict__["m"] - py.test.raises(AttributeError, six.get_method_function, hasattr) + pytest.raises(AttributeError, six.get_method_function, hasattr) def test_get_function_closure(): @@ -364,7 +349,7 @@ pass assert isinstance(six.get_function_code(f), types.CodeType) if not hasattr(sys, "pypy_version_info"): - py.test.raises(AttributeError, six.get_function_code, hasattr) + pytest.raises(AttributeError, six.get_function_code, hasattr) def test_get_function_defaults(): @@ -404,7 +389,7 @@ it = meth(d) assert not isinstance(it, list) assert list(it) == list(getattr(d, name)()) - py.test.raises(StopIteration, six.advance_iterator, it) + pytest.raises(StopIteration, six.advance_iterator, it) record = [] def with_kw(*args, **kw): record.append(kw["kw"]) @@ -416,17 +401,7 @@ monkeypatch.undo() [email protected]("sys.version_info[:2] < (2, 7)", - reason="view methods on dictionaries only available on 2.7+") def test_dictionary_views(): - def stock_method_name(viewwhat): - """Given a method suffix like "keys" or "values", return the name - of the dict method that delivers those on the version of Python - we're running in.""" - if six.PY3: - return viewwhat - return 'view' + viewwhat - d = dict(zip(range(10), (range(11, 20)))) for name in "keys", "values", "items": meth = getattr(six, "view" + name) @@ -440,8 +415,8 @@ it = iter(l) assert six.next(it) == 1 assert six.next(it) == 2 - py.test.raises(StopIteration, six.next, it) - py.test.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) def test_iterator(): @@ -489,7 +464,7 @@ def f(self): return self u = six.create_unbound_method(f, X) - py.test.raises(TypeError, u) + pytest.raises(TypeError, u) if six.PY2: assert isinstance(u, types.MethodType) x = X() @@ -537,13 +512,13 @@ def test_int2byte(): assert six.int2byte(3) == six.b("\x03") - py.test.raises(Exception, six.int2byte, 256) + pytest.raises(Exception, six.int2byte, 256) def test_byte2int(): assert six.byte2int(six.b("\x03")) == 3 assert six.byte2int(six.b("\x03\x04")) == 3 - py.test.raises(IndexError, six.byte2int, six.b("")) + pytest.raises(IndexError, six.byte2int, six.b("")) def test_bytesindex(): @@ -554,7 +529,7 @@ it = six.iterbytes(six.b("hi")) assert six.next(it) == ord("h") assert six.next(it) == ord("i") - py.test.raises(StopIteration, six.next, it) + pytest.raises(StopIteration, six.next, it) def test_StringIO(): @@ -643,7 +618,6 @@ # We should have done a raise f from None equivalent. assert val.__cause__ is None assert val.__context__ is ctx - if sys.version_info[:2] >= (3, 3): # And that should suppress the context on the exception. assert val.__suppress_context__ # For all versions the outer exception should have raised successfully. @@ -689,28 +663,10 @@ assert out.flushed [email protected]("sys.version_info[:2] >= (2, 6)") -def test_print_encoding(monkeypatch): - # Fool the type checking in print_. - monkeypatch.setattr(six, "file", six.BytesIO, raising=False) - out = six.BytesIO() - out.encoding = "utf-8" - out.errors = None - six.print_(six.u("\u053c"), end="", file=out) - assert out.getvalue() == six.b("\xd4\xbc") - out = six.BytesIO() - out.encoding = "ascii" - out.errors = "strict" - py.test.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out) - out.errors = "backslashreplace" - six.print_(six.u("\u053c"), end="", file=out) - assert out.getvalue() == six.b("\\u053c") - - def test_print_exceptions(): - py.test.raises(TypeError, six.print_, x=3) - py.test.raises(TypeError, six.print_, end=3) - py.test.raises(TypeError, six.print_, sep=42) + pytest.raises(TypeError, six.print_, x=3) + pytest.raises(TypeError, six.print_, end=3) + pytest.raises(TypeError, six.print_, sep=42) def test_with_metaclass(): @@ -744,7 +700,53 @@ assert Y.__mro__ == (Y, X, object) [email protected]("sys.version_info[:2] < (3, 0)") +def test_with_metaclass_typing(): + try: + import typing + except ImportError: + pytest.skip("typing module required") + class Meta(type): + pass + if sys.version_info[:2] < (3, 7): + # Generics with custom metaclasses were broken on older versions. + class Meta(Meta, typing.GenericMeta): + pass + T = typing.TypeVar('T') + class G(six.with_metaclass(Meta, typing.Generic[T])): + pass + class GA(six.with_metaclass(abc.ABCMeta, typing.Generic[T])): + pass + assert isinstance(G, Meta) + assert isinstance(GA, abc.ABCMeta) + assert G[int] is not G[G[int]] + assert GA[int] is not GA[GA[int]] + assert G.__bases__ == (typing.Generic,) + assert G.__orig_bases__ == (typing.Generic[T],) + + [email protected]("sys.version_info[:2] < (3, 7)") +def test_with_metaclass_pep_560(): + class Meta(type): + pass + class A: + pass + class B: + pass + class Fake: + def __mro_entries__(self, bases): + return (A, B) + fake = Fake() + class G(six.with_metaclass(Meta, fake)): + pass + class GA(six.with_metaclass(abc.ABCMeta, fake)): + pass + assert isinstance(G, Meta) + assert isinstance(GA, abc.ABCMeta) + assert G.__bases__ == (A, B) + assert G.__orig_bases__ == (fake,) + + [email protected]("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.""" @@ -792,14 +794,33 @@ def f(g, assign, update): def w(): return 42 - w.glue = {"foo" : "bar"} + w.glue = {"foo": "bar"} + w.xyzzy = {"qux": "quux"} return six.wraps(g, assign, update)(w) - k.glue = {"melon" : "egg"} + k.glue = {"melon": "egg"} k.turnip = 43 - k = f(k, ["turnip"], ["glue"]) + k = f(k, ["turnip", "baz"], ["glue", "xyzzy"]) assert k.__name__ == "w" assert k.turnip == 43 - assert k.glue == {"melon" : "egg", "foo" : "bar"} + assert not hasattr(k, "baz") + assert k.glue == {"melon": "egg", "foo": "bar"} + assert k.xyzzy == {"qux": "quux"} + + +def test_wraps_raises_on_missing_updated_field_on_wrapper(): + """Ensure six.wraps doesn't ignore missing attrs wrapper. + + Because that's what happens in Py3's functools.update_wrapper. + """ + def wrapped(): + pass + + def wrapper(): + pass + + with pytest.raises(AttributeError, match='has no attribute.*xyzzy'): + six.wraps(wrapped, [], ['xyzzy'])(wrapper) + def test_add_metaclass(): @@ -857,7 +878,7 @@ assert MySlots.__slots__ == ["a", "b"] instance = MySlots() instance.a = "foo" - py.test.raises(AttributeError, setattr, instance, "c", "baz") + pytest.raises(AttributeError, setattr, instance, "c", "baz") # Test a class with string for slots. class MyStringSlots(object): @@ -866,8 +887,8 @@ assert MyStringSlots.__slots__ == "ab" instance = MyStringSlots() instance.ab = "foo" - py.test.raises(AttributeError, setattr, instance, "a", "baz") - py.test.raises(AttributeError, setattr, instance, "b", "baz") + pytest.raises(AttributeError, setattr, instance, "a", "baz") + pytest.raises(AttributeError, setattr, instance, "b", "baz") class MySlotsWeakref(object): __slots__ = "__weakref__", @@ -875,7 +896,26 @@ assert type(MySlotsWeakref) is Meta [email protected]("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))") [email protected]("sys.version_info[:2] < (3, 3)") +def test_add_metaclass_nested(): + # Regression test for https://github.com/benjaminp/six/issues/259 + class Meta(type): + pass + + class A: + class B: pass + + expected = 'test_add_metaclass_nested.<locals>.A.B' + + assert A.B.__qualname__ == expected + + class A: + @six.add_metaclass(Meta) + class B: pass + + assert A.B.__qualname__ == expected + + def test_assertCountEqual(): class TestAssertCountEqual(unittest.TestCase): def test(self): @@ -887,7 +927,6 @@ TestAssertCountEqual('test').test() [email protected]("sys.version_info[:2] < (2, 7)") def test_assertRegex(): class TestAssertRegex(unittest.TestCase): def test(self): @@ -899,7 +938,17 @@ TestAssertRegex('test').test() [email protected]("sys.version_info[:2] < (2, 7)") +def test_assertNotRegex(): + class TestAssertNotRegex(unittest.TestCase): + def test(self): + with self.assertRaises(AssertionError): + six.assertNotRegex(self, 'test', r'^t') + + six.assertNotRegex(self, 'test', r'^a') + + TestAssertNotRegex('test').test() + + def test_assertRaisesRegex(): class TestAssertRaisesRegex(unittest.TestCase): def test(self): @@ -932,3 +981,61 @@ assert str(my_test) == six.u("hello") assert getattr(six.moves.builtins, 'bytes', str)(my_test) == six.b("hello") + + +class EnsureTests: + + # grinning face emoji + UNICODE_EMOJI = six.u("\U0001F600") + BINARY_EMOJI = b"\xf0\x9f\x98\x80" + + def test_ensure_binary_raise_type_error(self): + with pytest.raises(TypeError): + six.ensure_str(8) + + def test_errors_and_encoding(self): + six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='ignore') + with pytest.raises(UnicodeEncodeError): + six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='strict') + + def test_ensure_binary_raise(self): + converted_unicode = six.ensure_binary(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') + converted_binary = six.ensure_binary(self.BINARY_EMOJI, encoding="utf-8", errors='strict') + if six.PY2: + # PY2: unicode -> str + assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str) + # PY2: str -> str + assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str) + else: + # PY3: str -> bytes + assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, bytes) + # PY3: bytes -> bytes + assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, bytes) + + def test_ensure_str(self): + converted_unicode = six.ensure_str(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') + converted_binary = six.ensure_str(self.BINARY_EMOJI, encoding="utf-8", errors='strict') + if six.PY2: + # PY2: unicode -> str + assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str) + # PY2: str -> str + assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str) + else: + # PY3: str -> str + assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str) + # PY3: bytes -> str + assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str) + + def test_ensure_text(self): + converted_unicode = six.ensure_text(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') + converted_binary = six.ensure_text(self.BINARY_EMOJI, encoding="utf-8", errors='strict') + if six.PY2: + # PY2: unicode -> unicode + assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode) + # PY2: str -> unicode + assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode) + else: + # PY3: str -> str + assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str) + # PY3: bytes -> str + assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
